blob: f1efa9286d31a3e62b2ce5587d2f74786f5c6c5e [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 {
Ady Abraham57f8e182022-03-08 15:54:33 -080069 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070070 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000071 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080072 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070073 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070074 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000075 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070076 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000077 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070078 }
79
Adithya Srinivasan01189672020-10-20 14:23:05 -070080 // Each tracing session can be used for a single block of Start -> Stop.
81 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
82 perfetto::TraceConfig cfg;
83 cfg.set_duration_ms(500);
84 cfg.add_buffers()->set_size_kb(1024);
85 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
86 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
87
88 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
89 tracingSession->Setup(cfg);
90 return tracingSession;
91 }
92
93 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
94 perfetto::TracingSession* tracingSession) {
95 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
96 perfetto::protos::Trace trace;
97 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
98
99 std::vector<perfetto::protos::TracePacket> packets;
100 for (const auto& packet : trace.packet()) {
101 if (!packet.has_frame_timeline_event()) {
102 continue;
103 }
104 packets.emplace_back(packet);
105 }
106 return packets;
107 }
108
109 void addEmptyDisplayFrame() {
110 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000111 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700112 mFrameTimeline->setSfPresent(2500, presentFence1);
113 }
114
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000115 void flushTokens() {
116 for (size_t i = 0; i < maxTokens; i++) {
117 mTokenManager->generateTokenForPredictions({});
118 }
119 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700120 }
121
122 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
123 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800124 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
125 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700126 }
127
128 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
129 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
130 return mFrameTimeline->mDisplayFrames[idx];
131 }
132
133 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
134 return a.startTime == b.startTime && a.endTime == b.endTime &&
135 a.presentTime == b.presentTime;
136 }
137
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000138 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700139 return mTokenManager->mPredictions;
140 }
141
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000142 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700143 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
144 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
145 }
146
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000147 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
148
149 void flushTrace() {
150 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
151 FrameTimelineDataSource::Trace(
152 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
153 }
154
Alec Mouri9a29e672020-09-14 12:39:14 -0700155 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700156 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
157 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000158 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700159 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700160 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000161 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000162 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000163 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000164 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000165 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800166 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
167 kDeadlineThreshold,
168 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700169};
170
Alec Mouri9a29e672020-09-14 12:39:14 -0700171static const std::string sLayerNameOne = "layer1";
172static const std::string sLayerNameTwo = "layer2";
Dominik Laskowskif5d0ea52021-09-26 17:27:01 -0700173
174constexpr const uid_t sUidOne = 0;
175constexpr pid_t sPidOne = 10;
176constexpr pid_t sPidTwo = 20;
177constexpr int32_t sInputEventId = 5;
178constexpr int32_t sLayerIdOne = 1;
179constexpr int32_t sLayerIdTwo = 2;
180constexpr GameMode sGameMode = GameMode::Unsupported;
Alec Mouri9a29e672020-09-14 12:39:14 -0700181
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700182TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
183 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000184 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000185 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700186 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
187 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
188
189 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700190 EXPECT_EQ(predictions.has_value(), false);
191
192 predictions = mTokenManager->getPredictionsForToken(token2);
193 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
194}
195
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700196TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800197 auto surfaceFrame1 =
198 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000199 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000200 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800201 auto surfaceFrame2 =
202 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000203 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000204 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700205 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
206 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
207}
208
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700209TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800210 auto surfaceFrame =
211 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000212 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000213 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700214 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
215}
216
217TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
218 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000219 flushTokens();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000220 auto surfaceFrame =
221 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000222 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000223 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700224
225 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
226}
227
228TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
229 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000230 auto surfaceFrame =
231 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000232 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000233 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700234
235 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
236 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
237}
238
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000239TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
240 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
241 constexpr int32_t inputEventId = 1;
242 auto surfaceFrame =
243 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000244 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000245 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000246
247 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
248}
249
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700250TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
251 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700252 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000253 auto surfaceFrame1 =
254 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000255 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000256 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700257
258 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800259 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000260 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800261 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
262 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700263 mFrameTimeline->setSfPresent(25, presentFence1);
264 presentFence1->signalForTest(30);
265
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000266 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700267
268 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
269 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000270 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
271 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700272 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
273}
274
275TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800276 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800277 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700278 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
279 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700280 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700281 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000282 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800283 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000284 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700285 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000286 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800287 sUidOne, sLayerIdTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000288 sLayerNameTwo, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800289 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800290 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
291 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
292 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
293 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700294 mFrameTimeline->setSfPresent(26, presentFence1);
295 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800296 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
297 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700298 presentFence1->signalForTest(42);
299
300 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800301 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700302 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
303 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
304
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000305 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700306
307 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800308 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700309 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
310 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100311 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
312 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700313}
314
315TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
316 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
317 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800318 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800319 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800320 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700321 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700322 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
323 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
324 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
325 int64_t sfToken = mTokenManager->generateTokenForPredictions(
326 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700327 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000328 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
Alec Mouriadebf5c2021-01-05 12:57:36 -0800329 sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000330 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000331 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800332 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800333 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
334 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700335 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
336 presentFence->signalForTest(32 + frameTimeFactor);
337 frameTimeFactor += 30;
338 }
339 auto displayFrame0 = getDisplayFrame(0);
340
341 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800342 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700343
344 // Add one more display frame
345 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
346 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
347 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
348 int64_t sfToken = mTokenManager->generateTokenForPredictions(
349 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700350 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000351 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800352 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000353 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800354 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800355 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
356 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700357 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
358 presentFence->signalForTest(32 + frameTimeFactor);
359 displayFrame0 = getDisplayFrame(0);
360
361 // The window should have slided by 1 now and the previous 0th display frame
362 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800363 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700364}
365
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700366TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000367 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
368 "acquireFenceAfterQueue",
369 "acquireFenceAfterQueue",
370 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700371 surfaceFrame->setActualQueueTime(123);
372 surfaceFrame->setAcquireFenceTime(456);
373 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
374}
375
376TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000377 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
378 "acquireFenceAfterQueue",
379 "acquireFenceAfterQueue",
380 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700381 surfaceFrame->setActualQueueTime(456);
382 surfaceFrame->setAcquireFenceTime(123);
383 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
384}
385
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700386TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
387 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
388 presentFence->signalForTest(2);
389
390 // Size shouldn't exceed maxDisplayFrames - 64
391 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700392 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800393 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000394 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000395 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700396 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800397 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800398 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
399 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700400 mFrameTimeline->setSfPresent(27, presentFence);
401 }
402 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
403
404 // Increase the size to 256
405 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000406 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700407
408 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700409 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800410 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000411 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000412 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700413 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800414 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800415 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
416 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700417 mFrameTimeline->setSfPresent(27, presentFence);
418 }
419 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
420
421 // Shrink the size to 128
422 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000423 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700424
425 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700426 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800427 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000428 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000429 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700430 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800431 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800432 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
433 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700434 mFrameTimeline->setSfPresent(27, presentFence);
435 }
436 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
437}
Alec Mouri9a29e672020-09-14 12:39:14 -0700438
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000439TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
440 Fps refreshRate = Fps::fromPeriodNsecs(11);
441
442 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
443 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
444 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
445
446 auto surfaceFrame1 =
447 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
448 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000449 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000450 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
451 surfaceFrame1->setAcquireFenceTime(20);
452 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
453 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
454
455 mFrameTimeline->setSfPresent(59, presentFence1);
456 presentFence1->signalForTest(-1);
457 addEmptyDisplayFrame();
458
459 auto displayFrame0 = getDisplayFrame(0);
460 EXPECT_EQ(displayFrame0->getActuals().presentTime, -1);
461 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
462 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
463 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
464}
465
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800466// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000467TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
468 Fps refreshRate = Fps::fromPeriodNsecs(11);
469 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
470 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
471 int64_t surfaceFrameToken1 = -1;
472 int64_t sfToken1 = -1;
473
474 auto surfaceFrame1 =
475 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
476 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000477 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000478 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
479 surfaceFrame1->setAcquireFenceTime(20);
480 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
481 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
482 presentFence1->signalForTest(70);
483
484 mFrameTimeline->setSfPresent(59, presentFence1);
485}
486
Alec Mouri9a29e672020-09-14 12:39:14 -0700487TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000488 Fps refreshRate = Fps::fromPeriodNsecs(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700489 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800490 incrementJankyFrames(
491 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000492 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000493 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800494 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700495 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000496 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
497 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
498
Alec Mouri9a29e672020-09-14 12:39:14 -0700499 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000500 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800501 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000502 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000503 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
504 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800505 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
506 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000507 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700508
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000509 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700510}
511
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000512TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
513 Fps refreshRate = Fps::fromPeriodNsecs(11);
514 EXPECT_CALL(*mTimeStats,
515 incrementJankyFrames(
516 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000517 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000518 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
519 0}));
520 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
521 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
522 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
523 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
524
525 auto surfaceFrame1 =
526 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
527 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000528 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000529 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
530 surfaceFrame1->setAcquireFenceTime(20);
531 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
532 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
533 gpuFence1->signalForTest(64);
534 presentFence1->signalForTest(70);
535
536 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
537}
538
Alec Mouri9a29e672020-09-14 12:39:14 -0700539TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800540 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700541 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800542 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000543 sLayerNameOne, sGameMode,
544 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800545
Alec Mouri9a29e672020-09-14 12:39:14 -0700546 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000547 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
548 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
549
Alec Mouri9a29e672020-09-14 12:39:14 -0700550 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000551 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800552 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000553 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000554 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800555 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000556 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800557 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000558 presentFence1->signalForTest(90);
559 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800560 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700561}
562
563TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700564 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700565 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000566 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000567 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000568 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000569 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700570 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000571 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
572 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
573
Alec Mouri9a29e672020-09-14 12:39:14 -0700574 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000575 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800576 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000577 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000578 surfaceFrame1->setAcquireFenceTime(45);
579 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700580
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800581 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
582 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000583 presentFence1->signalForTest(90);
584 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100585
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800586 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700587}
588
Adithya Srinivasanead17162021-02-18 02:17:37 +0000589TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000590 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000591 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000592 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000593 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000594 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000595 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000596 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000597 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
598 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
599
Adithya Srinivasanead17162021-02-18 02:17:37 +0000600 auto surfaceFrame1 =
601 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800602 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000603 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000604 surfaceFrame1->setAcquireFenceTime(50);
605 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000606
607 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
608 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000609 presentFence1->signalForTest(60);
610 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000611
612 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
613}
614
615TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000616 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000617 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000618 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000619 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000620 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000621 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000622 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000623 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
624 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
625
Adithya Srinivasanead17162021-02-18 02:17:37 +0000626 auto surfaceFrame1 =
627 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800628 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000629 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000630 surfaceFrame1->setAcquireFenceTime(40);
631 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000632
633 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
634 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000635 presentFence1->signalForTest(65);
636 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000637
638 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
639}
640
641TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000642 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000643 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000644 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000645 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000646 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000647 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000648 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000649 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
650 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
651
Adithya Srinivasanead17162021-02-18 02:17:37 +0000652 auto surfaceFrame1 =
653 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800654 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000655 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000656 surfaceFrame1->setAcquireFenceTime(40);
657 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000658
659 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000660 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000661 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000662 presentFence1->signalForTest(90);
663 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000664
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000665 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000666}
667
Alec Mouri363faf02021-01-29 16:34:55 -0800668TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000669 Fps refreshRate = Fps::fromPeriodNsecs(11);
670 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800671 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000672 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
673 sLayerNameOne, sGameMode,
674 JankType::AppDeadlineMissed, -4, 0,
675 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800676 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000677 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
678 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
679
Alec Mouri363faf02021-01-29 16:34:55 -0800680 auto surfaceFrame1 =
681 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800682 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000683 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000684 surfaceFrame1->setAcquireFenceTime(45);
685 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800686
687 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
688 surfaceFrame1->setRenderRate(renderRate);
689 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000690 presentFence1->signalForTest(90);
691 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800692
693 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
694}
695
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000696TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
697 Fps refreshRate = Fps::fromPeriodNsecs(11);
698 Fps renderRate = Fps::fromPeriodNsecs(30);
699
700 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000701 incrementJankyFrames(
702 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000703 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000704 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000705 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000706 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
707 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
708 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
709
710 auto surfaceFrame1 =
711 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
712 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000713 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000714 surfaceFrame1->setAcquireFenceTime(45);
715 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000716 flushTokens();
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000717 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
718
719 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
720 surfaceFrame1->setRenderRate(renderRate);
721 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
722 presentFence1->signalForTest(90);
723 mFrameTimeline->setSfPresent(86, presentFence1);
724
725 auto displayFrame = getDisplayFrame(0);
726 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
727 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
728 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
729 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
730
731 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000732 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000733}
734
Adithya Srinivasan01189672020-10-20 14:23:05 -0700735/*
736 * Tracing Tests
737 *
738 * Trace packets are flushed all the way only when the next packet is traced.
739 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
740 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
741 * will have additional empty frames created for this reason.
742 */
743TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
744 auto tracingSession = getTracingSessionForTest();
745 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700746 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000747 auto surfaceFrame1 =
748 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000749 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000750 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700751
752 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800753 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800754 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
755 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700756 mFrameTimeline->setSfPresent(25, presentFence1);
757 presentFence1->signalForTest(30);
758
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000759 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700760
761 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000762 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700763}
764
765TEST_F(FrameTimelineTest, tracing_sanityTest) {
766 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800767 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800768 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700769 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700770
771 tracingSession->StartBlocking();
772 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
773 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000774 auto surfaceFrame1 =
775 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000776 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000777 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700778
779 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800780 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800781 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
782 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700783 mFrameTimeline->setSfPresent(25, presentFence1);
784 presentFence1->signalForTest(30);
785
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000786 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000787 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700788 tracingSession->StopBlocking();
789
790 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000791 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000792 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700793}
794
795TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
796 auto tracingSession = getTracingSessionForTest();
797 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700798
799 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700800
801 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800802 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700803 mFrameTimeline->setSfPresent(25, presentFence1);
804 presentFence1->signalForTest(30);
805
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000806 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000807 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700808 tracingSession->StopBlocking();
809
810 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000811 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700812}
813
814TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
815 auto tracingSession = getTracingSessionForTest();
816 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700817
818 tracingSession->StartBlocking();
819 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800820 auto surfaceFrame1 =
821 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000822 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000823 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700824
825 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800826 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800827 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
828 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700829 mFrameTimeline->setSfPresent(25, presentFence1);
830 presentFence1->signalForTest(30);
831
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000832 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000833 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700834 tracingSession->StopBlocking();
835
836 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000837 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
838 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000839 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700840}
841
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000842ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
843 pid_t pid) {
844 ProtoExpectedDisplayFrameStart proto;
845 proto.set_cookie(cookie);
846 proto.set_token(token);
847 proto.set_pid(pid);
848 return proto;
849}
850
851ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
852 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000853 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000854 ProtoActualDisplayFrameStart proto;
855 proto.set_cookie(cookie);
856 proto.set_token(token);
857 proto.set_pid(pid);
858 proto.set_present_type(presentType);
859 proto.set_on_time_finish(onTimeFinish);
860 proto.set_gpu_composition(gpuComposition);
861 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000862 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000863 return proto;
864}
865
866ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
867 int64_t displayFrameToken,
868 pid_t pid,
869 std::string layerName) {
870 ProtoExpectedSurfaceFrameStart proto;
871 proto.set_cookie(cookie);
872 proto.set_token(token);
873 proto.set_display_frame_token(displayFrameToken);
874 proto.set_pid(pid);
875 proto.set_layer_name(layerName);
876 return proto;
877}
878
879ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
880 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
881 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000882 ProtoJankType jankType, ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000883 ProtoActualSurfaceFrameStart proto;
884 proto.set_cookie(cookie);
885 proto.set_token(token);
886 proto.set_display_frame_token(displayFrameToken);
887 proto.set_pid(pid);
888 proto.set_layer_name(layerName);
889 proto.set_present_type(presentType);
890 proto.set_on_time_finish(onTimeFinish);
891 proto.set_gpu_composition(gpuComposition);
892 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000893 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000894 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000895 return proto;
896}
897
898ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
899 ProtoFrameEnd proto;
900 proto.set_cookie(cookie);
901 return proto;
902}
903
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000904void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
905 const ProtoExpectedDisplayFrameStart& source) {
906 ASSERT_TRUE(received.has_cookie());
907 EXPECT_EQ(received.cookie(), source.cookie());
908
Adithya Srinivasan01189672020-10-20 14:23:05 -0700909 ASSERT_TRUE(received.has_token());
910 EXPECT_EQ(received.token(), source.token());
911
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000912 ASSERT_TRUE(received.has_pid());
913 EXPECT_EQ(received.pid(), source.pid());
914}
915
916void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
917 const ProtoActualDisplayFrameStart& source) {
918 ASSERT_TRUE(received.has_cookie());
919 EXPECT_EQ(received.cookie(), source.cookie());
920
921 ASSERT_TRUE(received.has_token());
922 EXPECT_EQ(received.token(), source.token());
923
924 ASSERT_TRUE(received.has_pid());
925 EXPECT_EQ(received.pid(), source.pid());
926
Adithya Srinivasan01189672020-10-20 14:23:05 -0700927 ASSERT_TRUE(received.has_present_type());
928 EXPECT_EQ(received.present_type(), source.present_type());
929 ASSERT_TRUE(received.has_on_time_finish());
930 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
931 ASSERT_TRUE(received.has_gpu_composition());
932 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
933 ASSERT_TRUE(received.has_jank_type());
934 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000935 ASSERT_TRUE(received.has_prediction_type());
936 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700937}
938
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000939void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
940 const ProtoExpectedSurfaceFrameStart& source) {
941 ASSERT_TRUE(received.has_cookie());
942 EXPECT_EQ(received.cookie(), source.cookie());
943
Adithya Srinivasan01189672020-10-20 14:23:05 -0700944 ASSERT_TRUE(received.has_token());
945 EXPECT_EQ(received.token(), source.token());
946
947 ASSERT_TRUE(received.has_display_frame_token());
948 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
949
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000950 ASSERT_TRUE(received.has_pid());
951 EXPECT_EQ(received.pid(), source.pid());
952
953 ASSERT_TRUE(received.has_layer_name());
954 EXPECT_EQ(received.layer_name(), source.layer_name());
955}
956
957void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
958 const ProtoActualSurfaceFrameStart& source) {
959 ASSERT_TRUE(received.has_cookie());
960 EXPECT_EQ(received.cookie(), source.cookie());
961
962 ASSERT_TRUE(received.has_token());
963 EXPECT_EQ(received.token(), source.token());
964
965 ASSERT_TRUE(received.has_display_frame_token());
966 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
967
968 ASSERT_TRUE(received.has_pid());
969 EXPECT_EQ(received.pid(), source.pid());
970
971 ASSERT_TRUE(received.has_layer_name());
972 EXPECT_EQ(received.layer_name(), source.layer_name());
973
Adithya Srinivasan01189672020-10-20 14:23:05 -0700974 ASSERT_TRUE(received.has_present_type());
975 EXPECT_EQ(received.present_type(), source.present_type());
976 ASSERT_TRUE(received.has_on_time_finish());
977 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
978 ASSERT_TRUE(received.has_gpu_composition());
979 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
980 ASSERT_TRUE(received.has_jank_type());
981 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000982 ASSERT_TRUE(received.has_prediction_type());
983 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000984 ASSERT_TRUE(received.has_is_buffer());
985 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000986}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700987
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000988void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
989 ASSERT_TRUE(received.has_cookie());
990 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700991}
992
993TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
994 auto tracingSession = getTracingSessionForTest();
995 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700996
997 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000998 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700999
1000 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001001 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001002 mFrameTimeline->setSfPresent(26, presentFence1);
1003 presentFence1->signalForTest(31);
1004
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001005 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001006 auto protoExpectedDisplayFrameStart =
1007 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1008 kSurfaceFlingerPid);
1009 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1010 auto protoActualDisplayFrameStart =
1011 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1012 kSurfaceFlingerPid,
1013 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001014 FrameTimelineEvent::JANK_NONE,
1015 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001016 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001017
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001018 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001019 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001020 tracingSession->StopBlocking();
1021
1022 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001023 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001024
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001025 // Packet - 0 : ExpectedDisplayFrameStart
1026 const auto& packet0 = packets[0];
1027 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001028 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001029 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001030
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001031 const auto& event0 = packet0.frame_timeline_event();
1032 ASSERT_TRUE(event0.has_expected_display_frame_start());
1033 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1034 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1035
1036 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1037 const auto& packet1 = packets[1];
1038 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001039 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001040 ASSERT_TRUE(packet1.has_frame_timeline_event());
1041
1042 const auto& event1 = packet1.frame_timeline_event();
1043 ASSERT_TRUE(event1.has_frame_end());
1044 const auto& expectedDisplayFrameEnd = event1.frame_end();
1045 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1046
1047 // Packet - 2 : ActualDisplayFrameStart
1048 const auto& packet2 = packets[2];
1049 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001050 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001051 ASSERT_TRUE(packet2.has_frame_timeline_event());
1052
1053 const auto& event2 = packet2.frame_timeline_event();
1054 ASSERT_TRUE(event2.has_actual_display_frame_start());
1055 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1056 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1057
1058 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1059 const auto& packet3 = packets[3];
1060 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001061 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001062 ASSERT_TRUE(packet3.has_frame_timeline_event());
1063
1064 const auto& event3 = packet3.frame_timeline_event();
1065 ASSERT_TRUE(event3.has_frame_end());
1066 const auto& actualDisplayFrameEnd = event3.frame_end();
1067 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001068}
1069
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001070TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1071 auto tracingSession = getTracingSessionForTest();
1072 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1073
1074 tracingSession->StartBlocking();
1075 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1076 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001077 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001078
1079 // Set up the display frame
1080 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1081 mFrameTimeline->setSfPresent(26, presentFence1);
1082 presentFence1->signalForTest(31);
1083
1084 int64_t traceCookie = snoopCurrentTraceCookie();
1085
1086 auto protoActualDisplayFrameStart =
1087 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1088 kSurfaceFlingerPid,
1089 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001090 false, FrameTimelineEvent::JANK_UNKNOWN,
1091 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001092 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1093
1094 addEmptyDisplayFrame();
1095 flushTrace();
1096 tracingSession->StopBlocking();
1097
1098 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1099 // Only actual timeline packets should be in the trace
1100 EXPECT_EQ(packets.size(), 2u);
1101
1102 // Packet - 0 : ActualDisplayFrameStart
1103 const auto& packet0 = packets[0];
1104 ASSERT_TRUE(packet0.has_timestamp());
1105 EXPECT_EQ(packet0.timestamp(), 20u);
1106 ASSERT_TRUE(packet0.has_frame_timeline_event());
1107
1108 const auto& event0 = packet0.frame_timeline_event();
1109 ASSERT_TRUE(event0.has_actual_display_frame_start());
1110 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1111 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1112
1113 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1114 const auto& packet1 = packets[1];
1115 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001116 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001117 ASSERT_TRUE(packet1.has_frame_timeline_event());
1118
1119 const auto& event1 = packet1.frame_timeline_event();
1120 ASSERT_TRUE(event1.has_frame_end());
1121 const auto& actualDisplayFrameEnd = event1.frame_end();
1122 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1123}
1124
Adithya Srinivasan01189672020-10-20 14:23:05 -07001125TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1126 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001127 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001128 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001129 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1130 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1131
1132 tracingSession->StartBlocking();
1133 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1134 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001135
1136 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001137 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001138 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001139 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001140 auto surfaceFrame2 =
1141 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001142 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001143 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001144 surfaceFrame1->setActualQueueTime(10);
1145 surfaceFrame1->setDropTime(15);
1146
1147 surfaceFrame2->setActualQueueTime(15);
1148 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001149
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001150 // First 2 cookies will be used by the DisplayFrame
1151 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1152
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001153 auto protoDroppedSurfaceFrameExpectedStart =
1154 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1155 displayFrameToken1, sPidOne, sLayerNameOne);
1156 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1157 auto protoDroppedSurfaceFrameActualStart =
1158 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1159 displayFrameToken1, sPidOne, sLayerNameOne,
1160 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001161 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001162 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001163 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001164
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001165 auto protoPresentedSurfaceFrameExpectedStart =
1166 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1167 displayFrameToken1, sPidOne, sLayerNameOne);
1168 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1169 auto protoPresentedSurfaceFrameActualStart =
1170 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1171 displayFrameToken1, sPidOne, sLayerNameOne,
1172 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001173 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001174 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001175 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001176
1177 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001178 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001179 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1180 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001181 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001182 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001183 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001184 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001185
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001186 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001187 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001188 tracingSession->StopBlocking();
1189
1190 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001191 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1192 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001193
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001194 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001195 const auto& packet4 = packets[4];
1196 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001197 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001198 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001199
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001200 const auto& event4 = packet4.frame_timeline_event();
1201 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001202 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1203 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001204
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001205 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001206 const auto& packet5 = packets[5];
1207 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001208 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001209 ASSERT_TRUE(packet5.has_frame_timeline_event());
1210
1211 const auto& event5 = packet5.frame_timeline_event();
1212 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001213 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1214 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001215
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001216 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001217 const auto& packet6 = packets[6];
1218 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001219 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001220 ASSERT_TRUE(packet6.has_frame_timeline_event());
1221
1222 const auto& event6 = packet6.frame_timeline_event();
1223 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001224 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1225 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001226
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001227 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001228 const auto& packet7 = packets[7];
1229 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001230 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001231 ASSERT_TRUE(packet7.has_frame_timeline_event());
1232
1233 const auto& event7 = packet7.frame_timeline_event();
1234 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001235 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1236 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1237
1238 // Packet - 8 : ExpectedSurfaceFrameStart2
1239 const auto& packet8 = packets[8];
1240 ASSERT_TRUE(packet8.has_timestamp());
1241 EXPECT_EQ(packet8.timestamp(), 10u);
1242 ASSERT_TRUE(packet8.has_frame_timeline_event());
1243
1244 const auto& event8 = packet8.frame_timeline_event();
1245 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1246 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1247 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1248
1249 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1250 const auto& packet9 = packets[9];
1251 ASSERT_TRUE(packet9.has_timestamp());
1252 EXPECT_EQ(packet9.timestamp(), 25u);
1253 ASSERT_TRUE(packet9.has_frame_timeline_event());
1254
1255 const auto& event9 = packet9.frame_timeline_event();
1256 ASSERT_TRUE(event9.has_frame_end());
1257 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1258 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1259
1260 // Packet - 10 : ActualSurfaceFrameStart2
1261 const auto& packet10 = packets[10];
1262 ASSERT_TRUE(packet10.has_timestamp());
1263 EXPECT_EQ(packet10.timestamp(), 10u);
1264 ASSERT_TRUE(packet10.has_frame_timeline_event());
1265
1266 const auto& event10 = packet10.frame_timeline_event();
1267 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1268 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1269 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1270
1271 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1272 const auto& packet11 = packets[11];
1273 ASSERT_TRUE(packet11.has_timestamp());
1274 EXPECT_EQ(packet11.timestamp(), 20u);
1275 ASSERT_TRUE(packet11.has_frame_timeline_event());
1276
1277 const auto& event11 = packet11.frame_timeline_event();
1278 ASSERT_TRUE(event11.has_frame_end());
1279 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1280 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1281}
1282
Ady Abrahame43ff722022-02-15 14:44:25 -08001283TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001284 auto tracingSession = getTracingSessionForTest();
1285 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1286
1287 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001288 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1289 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1290 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001291 int64_t surfaceFrameToken =
1292 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1293
1294 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001295 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001296 auto surfaceFrame1 =
1297 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001298 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001299 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001300 surfaceFrame1->setActualQueueTime(appEndTime);
1301 surfaceFrame1->setAcquireFenceTime(appEndTime);
1302
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001303 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1304 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1305 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001306 int64_t displayFrameToken =
1307 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1308
1309 // First 2 cookies will be used by the DisplayFrame
1310 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1311
1312 auto protoActualSurfaceFrameStart =
1313 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1314 displayFrameToken, sPidOne, sLayerNameOne,
1315 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001316 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001317 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001318 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1319
1320 // Set up the display frame
1321 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1322 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1323 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1324 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1325 presentFence1->signalForTest(sfPresentTime);
1326
1327 addEmptyDisplayFrame();
1328 flushTrace();
1329 tracingSession->StopBlocking();
1330
1331 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1332 // Display Frame 4 packets + SurfaceFrame 2 packets
1333 ASSERT_EQ(packets.size(), 6u);
1334
1335 // Packet - 4 : ActualSurfaceFrameStart
1336 const auto& packet4 = packets[4];
1337 ASSERT_TRUE(packet4.has_timestamp());
1338 EXPECT_EQ(packet4.timestamp(),
1339 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1340 ASSERT_TRUE(packet4.has_frame_timeline_event());
1341
1342 const auto& event4 = packet4.frame_timeline_event();
1343 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1344 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1345 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1346
1347 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1348 const auto& packet5 = packets[5];
1349 ASSERT_TRUE(packet5.has_timestamp());
1350 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1351 ASSERT_TRUE(packet5.has_frame_timeline_event());
1352
1353 const auto& event5 = packet5.frame_timeline_event();
1354 ASSERT_TRUE(event5.has_frame_end());
1355 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001356 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001357}
1358
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001359TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1360 auto tracingSession = getTracingSessionForTest();
1361 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1362
1363 tracingSession->StartBlocking();
1364 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1365 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1366 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1367 int64_t surfaceFrameToken =
1368 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1369
1370 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001371 flushTokens();
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001372 auto surfaceFrame1 =
1373 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
1374 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001375 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001376
1377 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1378 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1379 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1380 int64_t displayFrameToken =
1381 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1382
1383 // First 2 cookies will be used by the DisplayFrame
1384 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1385
1386 auto protoActualSurfaceFrameStart =
1387 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1388 displayFrameToken, sPidOne, sLayerNameOne,
1389 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1390 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001391 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001392 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1393
1394 // Set up the display frame
1395 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1396 surfaceFrame1->setDropTime(sfStartTime);
1397 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1398 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1399 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1400 presentFence1->signalForTest(sfPresentTime);
1401
1402 addEmptyDisplayFrame();
1403 flushTrace();
1404 tracingSession->StopBlocking();
1405
1406 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1407 // Display Frame 4 packets + SurfaceFrame 2 packets
1408 ASSERT_EQ(packets.size(), 6u);
1409
1410 // Packet - 4 : ActualSurfaceFrameStart
1411 const auto& packet4 = packets[4];
1412 ASSERT_TRUE(packet4.has_timestamp());
1413 EXPECT_EQ(packet4.timestamp(),
1414 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1415 ASSERT_TRUE(packet4.has_frame_timeline_event());
1416
1417 const auto& event4 = packet4.frame_timeline_event();
1418 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1419 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1420 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1421
1422 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1423 const auto& packet5 = packets[5];
1424 ASSERT_TRUE(packet5.has_timestamp());
1425 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1426 ASSERT_TRUE(packet5.has_frame_timeline_event());
1427
1428 const auto& event5 = packet5.frame_timeline_event();
1429 ASSERT_TRUE(event5.has_frame_end());
1430 const auto& actualSurfaceFrameEnd = event5.frame_end();
1431 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1432}
1433
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001434// Tests for Jank classification
1435TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001436 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001437 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001438 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1439 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001440 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001441 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001442 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001443 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001444 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001445 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001446 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1447 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1448 mFrameTimeline->setSfPresent(26, presentFence1);
1449 auto displayFrame = getDisplayFrame(0);
1450 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1451 presentFence1->signalForTest(29);
1452
1453 // Fences haven't been flushed yet, so it should be 0
1454 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1455 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1456
1457 addEmptyDisplayFrame();
1458 displayFrame = getDisplayFrame(0);
1459
1460 // Fences have flushed, so the present timestamps should be updated
1461 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1462 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1463 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1464 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1465 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1466}
1467
1468TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001469 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001470 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001471 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1472 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001473 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001474 mFrameTimeline->setSfPresent(26, presentFence1);
1475 auto displayFrame = getDisplayFrame(0);
1476 presentFence1->signalForTest(30);
1477
1478 // Fences for the first frame haven't been flushed yet, so it should be 0
1479 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1480
1481 // Trigger a flush by finalizing the next DisplayFrame
1482 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001483 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001484 mFrameTimeline->setSfPresent(56, presentFence2);
1485 displayFrame = getDisplayFrame(0);
1486
1487 // Fences for the first frame have flushed, so the present timestamps should be updated
1488 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1489 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1490 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1491 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1492
1493 // Fences for the second frame haven't been flushed yet, so it should be 0
1494 auto displayFrame2 = getDisplayFrame(1);
1495 presentFence2->signalForTest(65);
1496 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001497 addEmptyDisplayFrame();
1498 displayFrame2 = getDisplayFrame(1);
1499
1500 // Fences for the second frame have flushed, so the present timestamps should be updated
1501 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1502 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1503 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1504 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1505}
1506
1507TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001508 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001509 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001510 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1511 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001512 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001513 mFrameTimeline->setSfPresent(26, presentFence1);
1514 auto displayFrame = getDisplayFrame(0);
1515 presentFence1->signalForTest(50);
1516
1517 // Fences for the first frame haven't been flushed yet, so it should be 0
1518 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1519
1520 // Trigger a flush by finalizing the next DisplayFrame
1521 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001522 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001523 mFrameTimeline->setSfPresent(56, presentFence2);
1524 displayFrame = getDisplayFrame(0);
1525
1526 // Fences for the first frame have flushed, so the present timestamps should be updated
1527 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1528 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1529 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1530 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1531
1532 // Fences for the second frame haven't been flushed yet, so it should be 0
1533 auto displayFrame2 = getDisplayFrame(1);
1534 presentFence2->signalForTest(75);
1535 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1536
1537 addEmptyDisplayFrame();
1538 displayFrame2 = getDisplayFrame(1);
1539
1540 // Fences for the second frame have flushed, so the present timestamps should be updated
1541 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1542 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1543 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1544 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1545}
1546
1547TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001548 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1549 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001550 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001551
1552 mFrameTimeline->setSfPresent(22, presentFence1);
1553 auto displayFrame = getDisplayFrame(0);
1554 presentFence1->signalForTest(28);
1555
1556 // Fences haven't been flushed yet, so it should be 0
1557 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1558
1559 addEmptyDisplayFrame();
1560 displayFrame = getDisplayFrame(0);
1561
1562 // Fences have flushed, so the present timestamps should be updated
1563 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1564 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1565 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1566 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1567}
1568
1569TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001570 /*
1571 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1572 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001573 * Case 3 - previous frame ran longer -> sf_stuffing
1574 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001575 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001576 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001577 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001578 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1579 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001580 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1581 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001582 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1583 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001584 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001585 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001586 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1587 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1588
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001589 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Alec Mouri7d436ec2021-01-27 20:40:50 -08001590 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001591 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1592 auto displayFrame0 = getDisplayFrame(0);
1593 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001594 presentFence1->signalForTest(52);
1595
1596 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001597 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1598
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001599 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
1600 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001601 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1602 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001603 gpuFence2->signalForTest(76);
1604 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001605
1606 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1607 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1608 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1609 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1610 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1611 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001612
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001613 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
1614 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
1615 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1616 auto displayFrame2 = getDisplayFrame(2);
1617 gpuFence3->signalForTest(116);
1618 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001619
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001620 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001621 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001622 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001623 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1624 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1625 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001626
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001627 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
1628 mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30));
1629 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1630 auto displayFrame3 = getDisplayFrame(3);
1631 gpuFence4->signalForTest(156);
1632 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001633
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001634 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1635 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1636 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1637 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1638 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1639 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001640
1641 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001642
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001643 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1644 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1645 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1646 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1647 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001648}
1649
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001650TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001651 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001652 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001653 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1654 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001655 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1656 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1657 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001658 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001659 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001660 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001661 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001662 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001663 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1664 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001665 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001666 auto displayFrame1 = getDisplayFrame(0);
1667 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1668 presentFence1->signalForTest(30);
1669
1670 // Fences for the first frame haven't been flushed yet, so it should be 0
1671 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1672 auto actuals1 = presentedSurfaceFrame1.getActuals();
1673 EXPECT_EQ(actuals1.presentTime, 0);
1674
1675 // Trigger a flush by finalizing the next DisplayFrame
1676 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1677 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001678 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001679 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001680 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001681 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001682 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001683 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1684 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001685 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001686 auto displayFrame2 = getDisplayFrame(1);
1687 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1688
1689 // Fences for the first frame have flushed, so the present timestamps should be updated
1690 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1691 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1692 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1693 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1694
1695 actuals1 = presentedSurfaceFrame1.getActuals();
1696 EXPECT_EQ(actuals1.presentTime, 30);
1697 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1698 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1699 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1700
1701 // Fences for the second frame haven't been flushed yet, so it should be 0
1702 presentFence2->signalForTest(65);
1703 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1704 auto actuals2 = presentedSurfaceFrame2.getActuals();
1705 EXPECT_EQ(actuals2.presentTime, 0);
1706
Alec Mouri363faf02021-01-29 16:34:55 -08001707 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1708
1709 EXPECT_CALL(*mTimeStats,
1710 incrementJankyFrames(
1711 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001712 sLayerNameOne, sGameMode,
1713 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001714
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001715 addEmptyDisplayFrame();
1716
1717 // Fences for the second frame have flushed, so the present timestamps should be updated
1718 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1719 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1720 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1721 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1722
1723 actuals2 = presentedSurfaceFrame2.getActuals();
1724 EXPECT_EQ(actuals2.presentTime, 65);
1725 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1726 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1727 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1728}
1729
1730TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001731 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001732 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001733 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1734 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001735 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1736 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1737 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001738 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001739 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001740 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001741 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001742 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001743 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1744 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1745 mFrameTimeline->setSfPresent(26, presentFence1);
1746 auto displayFrame1 = getDisplayFrame(0);
1747 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1748 presentFence1->signalForTest(50);
1749
1750 // Fences for the first frame haven't been flushed yet, so it should be 0
1751 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1752 auto actuals1 = presentedSurfaceFrame1.getActuals();
1753 EXPECT_EQ(actuals1.presentTime, 0);
1754
1755 // Trigger a flush by finalizing the next DisplayFrame
1756 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1757 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001758 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001759 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001760 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001761 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001762 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001763 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1764 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001765 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001766 auto displayFrame2 = getDisplayFrame(1);
1767 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1768
1769 // Fences for the first frame have flushed, so the present timestamps should be updated
1770 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1771 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1772 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1773 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1774
1775 actuals1 = presentedSurfaceFrame1.getActuals();
1776 EXPECT_EQ(actuals1.presentTime, 50);
1777 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1778 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1779 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1780
1781 // Fences for the second frame haven't been flushed yet, so it should be 0
1782 presentFence2->signalForTest(86);
1783 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1784 auto actuals2 = presentedSurfaceFrame2.getActuals();
1785 EXPECT_EQ(actuals2.presentTime, 0);
1786
Alec Mouri363faf02021-01-29 16:34:55 -08001787 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1788
1789 EXPECT_CALL(*mTimeStats,
1790 incrementJankyFrames(
1791 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001792 sLayerNameOne, sGameMode,
1793 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001794
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001795 addEmptyDisplayFrame();
1796
1797 // Fences for the second frame have flushed, so the present timestamps should be updated
1798 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1799 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1800 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1801 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1802
1803 actuals2 = presentedSurfaceFrame2.getActuals();
1804 EXPECT_EQ(actuals2.presentTime, 86);
1805 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1806 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1807 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1808}
1809
1810TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001811 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001812
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001813 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001814 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001815 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1816 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001817 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001818 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001819 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001820 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001821 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001822 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1823 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1824 mFrameTimeline->setSfPresent(46, presentFence1);
1825 auto displayFrame1 = getDisplayFrame(0);
1826 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1827 presentFence1->signalForTest(50);
1828
1829 // Fences for the first frame haven't been flushed yet, so it should be 0
1830 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1831 auto actuals1 = presentedSurfaceFrame1.getActuals();
1832 EXPECT_EQ(actuals1.presentTime, 0);
1833
1834 addEmptyDisplayFrame();
1835
1836 // Fences for the first frame have flushed, so the present timestamps should be updated
1837 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1838 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1839 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1840 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1841
1842 actuals1 = presentedSurfaceFrame1.getActuals();
1843 EXPECT_EQ(actuals1.presentTime, 50);
1844 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1845 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1846 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1847}
1848
1849TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001850 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001851 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001852 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001853
Alec Mouri363faf02021-01-29 16:34:55 -08001854 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001855 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001856 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1857 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001858 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1859 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1860 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001861 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001862 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001863 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001864 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001865 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001866 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1867 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1868 mFrameTimeline->setSfPresent(36, presentFence1);
1869 auto displayFrame1 = getDisplayFrame(0);
1870 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1871 presentFence1->signalForTest(40);
1872
1873 // Fences for the first frame haven't been flushed yet, so it should be 0
1874 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1875 auto actuals1 = presentedSurfaceFrame1.getActuals();
1876 EXPECT_EQ(actuals1.presentTime, 0);
1877
1878 // Trigger a flush by finalizing the next DisplayFrame
1879 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1880 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001881 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001882 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001883 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001884 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001885 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001886 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1887 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1888 mFrameTimeline->setSfPresent(56, presentFence2);
1889 auto displayFrame2 = getDisplayFrame(1);
1890 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1891
1892 // Fences for the first frame have flushed, so the present timestamps should be updated
1893 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1894 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1895 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1896 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1897
1898 actuals1 = presentedSurfaceFrame1.getActuals();
1899 EXPECT_EQ(actuals1.presentTime, 40);
1900 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1901 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1902 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1903
1904 // Fences for the second frame haven't been flushed yet, so it should be 0
1905 presentFence2->signalForTest(60);
1906 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1907 auto actuals2 = presentedSurfaceFrame2.getActuals();
1908 EXPECT_EQ(actuals2.presentTime, 0);
1909
1910 addEmptyDisplayFrame();
1911
1912 // Fences for the second frame have flushed, so the present timestamps should be updated
1913 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1914 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1915 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1916 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1917
1918 actuals2 = presentedSurfaceFrame2.getActuals();
1919 EXPECT_EQ(actuals2.presentTime, 60);
1920 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1921 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001922 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1923 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001924}
1925
1926TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001927 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001928 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001929 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1930 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1931 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1932
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001933 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1934 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001935 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001936 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001937 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001938 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001939 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001940 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001941 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1942 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1943 mFrameTimeline->setSfPresent(56, presentFence1);
1944 auto displayFrame1 = getDisplayFrame(0);
1945 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1946 presentFence1->signalForTest(60);
1947
1948 // Fences for the first frame haven't been flushed yet, so it should be 0
1949 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1950 auto actuals1 = presentedSurfaceFrame1.getActuals();
1951 EXPECT_EQ(actuals1.presentTime, 0);
1952
1953 // Trigger a flush by finalizing the next DisplayFrame
1954 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1955 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001956 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001957 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001958 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001959 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001960 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001961 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1962 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1963 mFrameTimeline->setSfPresent(116, presentFence2);
1964 auto displayFrame2 = getDisplayFrame(1);
1965 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1966 presentFence2->signalForTest(120);
1967
1968 // Fences for the first frame have flushed, so the present timestamps should be updated
1969 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1970 actuals1 = presentedSurfaceFrame1.getActuals();
1971 EXPECT_EQ(actuals1.endTime, 50);
1972 EXPECT_EQ(actuals1.presentTime, 60);
1973
1974 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1975 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1976 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1977
1978 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1979 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1980 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1981
1982 // Fences for the second frame haven't been flushed yet, so it should be 0
1983 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1984 auto actuals2 = presentedSurfaceFrame2.getActuals();
1985 EXPECT_EQ(actuals2.presentTime, 0);
1986
1987 addEmptyDisplayFrame();
1988
1989 // Fences for the second frame have flushed, so the present timestamps should be updated
1990 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1991 actuals2 = presentedSurfaceFrame2.getActuals();
1992 EXPECT_EQ(actuals2.presentTime, 120);
1993
1994 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1995 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1996 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1997
1998 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1999 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2000 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2001 JankType::AppDeadlineMissed | JankType::BufferStuffing);
2002}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002003
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002004TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2005 // Layer specific increment
2006 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2007 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2008 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2009 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2010
2011 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2012 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
2013 auto surfaceFrame1 =
2014 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
2015 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002016 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002017 surfaceFrame1->setAcquireFenceTime(50);
2018 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2019 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2020 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2021 mFrameTimeline->setSfPresent(56, presentFence1);
2022 auto displayFrame1 = getDisplayFrame(0);
2023 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2024 presentFence1->signalForTest(60);
2025
2026 // Fences for the first frame haven't been flushed yet, so it should be 0
2027 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2028 auto actuals1 = presentedSurfaceFrame1.getActuals();
2029 EXPECT_EQ(actuals1.presentTime, 0);
2030
2031 // Trigger a flush by finalizing the next DisplayFrame
2032 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2033 auto surfaceFrame2 =
2034 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
2035 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002036 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002037 surfaceFrame2->setAcquireFenceTime(80);
2038 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
2039 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2040 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2041 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2042 mFrameTimeline->setSfPresent(86, presentFence2);
2043 auto displayFrame2 = getDisplayFrame(1);
2044 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2045 presentFence2->signalForTest(90);
2046
2047 // Fences for the first frame have flushed, so the present timestamps should be updated
2048 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2049 actuals1 = presentedSurfaceFrame1.getActuals();
2050 EXPECT_EQ(actuals1.endTime, 50);
2051 EXPECT_EQ(actuals1.presentTime, 60);
2052
2053 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2054 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2055 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2056
2057 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2058 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2059 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2060
2061 // Fences for the second frame haven't been flushed yet, so it should be 0
2062 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2063 auto actuals2 = presentedSurfaceFrame2.getActuals();
2064 EXPECT_EQ(actuals2.presentTime, 0);
2065
2066 addEmptyDisplayFrame();
2067
2068 // Fences for the second frame have flushed, so the present timestamps should be updated
2069 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2070 actuals2 = presentedSurfaceFrame2.getActuals();
2071 EXPECT_EQ(actuals2.presentTime, 90);
2072
2073 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2074 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2075 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2076
2077 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2078 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2079 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2080}
2081
Alec Mouriadebf5c2021-01-05 12:57:36 -08002082TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2083 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2084}
2085
2086TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002087 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002088
2089 auto surfaceFrame1 =
2090 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002091 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002092 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002093 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2094 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2095 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2096 presentFence1->signalForTest(oneHundredMs);
2097 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2098
2099 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2100}
2101
2102TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002103 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2104 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002105 auto surfaceFrame1 =
2106 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002107 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002108 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002109 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2110 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2111 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2112 presentFence1->signalForTest(oneHundredMs);
2113 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2114
2115 auto surfaceFrame2 =
2116 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002117 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002118 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002119 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2120 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2121 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2122 presentFence2->signalForTest(twoHundredMs);
2123 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2124
2125 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2126}
2127
2128TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002129 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2130 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002131 auto surfaceFrame1 =
2132 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002133 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002134 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002135 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2136 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2137 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2138 presentFence1->signalForTest(oneHundredMs);
2139 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2140
2141 auto surfaceFrame2 =
2142 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002143 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002144 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002145 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2146 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2147 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2148 presentFence2->signalForTest(twoHundredMs);
2149 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2150
2151 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2152}
2153
2154TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002155 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2156 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002157 auto surfaceFrame1 =
2158 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002159 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002160 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002161 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2162 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2163 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2164 presentFence1->signalForTest(oneHundredMs);
2165 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2166
2167 auto surfaceFrame2 =
2168 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002169 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002170 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002171 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2172 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2173 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2174 presentFence2->signalForTest(twoHundredMs);
2175 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2176
2177 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2178}
2179
2180TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002181 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2182 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2183 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2184 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2185 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002186 auto surfaceFrame1 =
2187 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002188 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002189 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002190 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2191 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2192 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2193 presentFence1->signalForTest(oneHundredMs);
2194 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2195
2196 auto surfaceFrame2 =
2197 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002198 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002199 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002200 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2201 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2202 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2203 presentFence2->signalForTest(twoHundredMs);
2204 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2205
2206 auto surfaceFrame3 =
2207 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002208 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002209 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002210 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2211 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2212 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2213 presentFence3->signalForTest(threeHundredMs);
2214 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2215
2216 auto surfaceFrame4 =
2217 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002218 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002219 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002220 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2221 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2222 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2223 presentFence4->signalForTest(fiveHundredMs);
2224 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2225
2226 auto surfaceFrame5 =
2227 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002228 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002229 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002230 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2231 // Dropped frames will be excluded from fps computation
2232 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2233 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2234 presentFence5->signalForTest(sixHundredMs);
2235 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2236
2237 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2238}
2239
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002240} // namespace android::frametimeline