blob: e2584e266d923ac907681a3062e83d6a0c7be9ae [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// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wextra"
20
Alec Mouri9a29e672020-09-14 12:39:14 -070021#include "gmock/gmock-spec-builders.h"
22#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070023#undef LOG_TAG
24#define LOG_TAG "LibSurfaceFlingerUnittests"
25
26#include <FrameTimeline/FrameTimeline.h>
27#include <gtest/gtest.h>
28#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070029#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070030#include <cinttypes>
31
32using namespace std::chrono_literals;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080033using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070034using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070035using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000036using ProtoExpectedDisplayFrameStart =
37 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
38using ProtoExpectedSurfaceFrameStart =
39 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
40using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
41using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
42using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070043using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
44using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Alec Mouri9a29e672020-09-14 12:39:14 -070045
46MATCHER_P(HasBit, bit, "") {
47 return (arg & bit) != 0;
48}
Adithya Srinivasanf279e042020-08-17 14:56:27 -070049
50namespace android::frametimeline {
51
52class FrameTimelineTest : public testing::Test {
53public:
54 FrameTimelineTest() {
55 const ::testing::TestInfo* const test_info =
56 ::testing::UnitTest::GetInstance()->current_test_info();
57 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
58 }
59
60 ~FrameTimelineTest() {
61 const ::testing::TestInfo* const test_info =
62 ::testing::UnitTest::GetInstance()->current_test_info();
63 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
64 }
65
Adithya Srinivasan01189672020-10-20 14:23:05 -070066 static void SetUpTestSuite() {
67 // Need to initialize tracing in process for testing, and only once per test suite.
68 perfetto::TracingInitArgs args;
69 args.backends = perfetto::kInProcessBackend;
70 perfetto::Tracing::Initialize(args);
71 }
72
Adithya Srinivasanf279e042020-08-17 14:56:27 -070073 void SetUp() override {
Alec Mouri9a29e672020-09-14 12:39:14 -070074 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000075 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080076 kTestThresholds);
Adithya Srinivasan01189672020-10-20 14:23:05 -070077 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070078 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000079 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070080 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070081 maxTokenRetentionTime = mTokenManager->kMaxRetentionTime;
82 }
83
Adithya Srinivasan01189672020-10-20 14:23:05 -070084 // Each tracing session can be used for a single block of Start -> Stop.
85 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
86 perfetto::TraceConfig cfg;
87 cfg.set_duration_ms(500);
88 cfg.add_buffers()->set_size_kb(1024);
89 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
90 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
91
92 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
93 tracingSession->Setup(cfg);
94 return tracingSession;
95 }
96
97 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
98 perfetto::TracingSession* tracingSession) {
99 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
100 perfetto::protos::Trace trace;
101 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
102
103 std::vector<perfetto::protos::TracePacket> packets;
104 for (const auto& packet : trace.packet()) {
105 if (!packet.has_frame_timeline_event()) {
106 continue;
107 }
108 packets.emplace_back(packet);
109 }
110 return packets;
111 }
112
113 void addEmptyDisplayFrame() {
114 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
115 mFrameTimeline->setSfPresent(2500, presentFence1);
116 }
117
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700118 void flushTokens(nsecs_t flushTime) {
119 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
120 mTokenManager->flushTokens(flushTime);
121 }
122
123 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
124 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800125 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
126 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700127 }
128
129 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
130 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
131 return mFrameTimeline->mDisplayFrames[idx];
132 }
133
134 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
135 return a.startTime == b.startTime && a.endTime == b.endTime &&
136 a.presentTime == b.presentTime;
137 }
138
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000139 const std::map<int64_t, TokenManagerPrediction>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700140 return mTokenManager->mPredictions;
141 }
142
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000143 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700144 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
145 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
146 }
147
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000148 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
149
150 void flushTrace() {
151 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
152 FrameTimelineDataSource::Trace(
153 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
154 }
155
Alec Mouri9a29e672020-09-14 12:39:14 -0700156 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700157 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
158 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000159 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700160 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700161 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700162 nsecs_t maxTokenRetentionTime;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000163 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800164 static constexpr nsecs_t kPresentThreshold =
165 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
166 static constexpr nsecs_t kDeadlineThreshold =
167 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
168 static constexpr nsecs_t kStartThreshold =
169 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
170 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
171 kDeadlineThreshold,
172 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700173};
174
Alec Mouri9a29e672020-09-14 12:39:14 -0700175static const std::string sLayerNameOne = "layer1";
176static const std::string sLayerNameTwo = "layer2";
177static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700178static constexpr pid_t sPidOne = 10;
179static constexpr pid_t sPidTwo = 20;
Alec Mouri9a29e672020-09-14 12:39:14 -0700180
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700181TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
182 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
183 EXPECT_EQ(getPredictions().size(), 1);
184 flushTokens(systemTime() + maxTokenRetentionTime);
185 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
186 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
187
188 // token1 should have expired
189 EXPECT_EQ(getPredictions().size(), 1);
190 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) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800197 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne,
198 sLayerNameOne, sLayerNameOne);
199 auto surfaceFrame2 = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidTwo, sUidOne,
200 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700201 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
202 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
203}
204
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700205TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800206 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne,
207 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700208 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
209}
210
211TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
212 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
213 flushTokens(systemTime() + maxTokenRetentionTime);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800214 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne,
215 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700216
217 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
218}
219
220TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
221 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800222 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne,
223 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700224
225 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
226 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
227}
228
229TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800230 // Global increment
231 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700232 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
233 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
234
235 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
236 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800237 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne,
238 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700239
240 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800241 mFrameTimeline->setSfWakeUp(token1, 20, 11);
242 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
243 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700244 mFrameTimeline->setSfPresent(25, presentFence1);
245 presentFence1->signalForTest(30);
246
247 // Trigger a flush by calling setSfPresent for the next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800248 mFrameTimeline->setSfWakeUp(token2, 50, 11);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700249 mFrameTimeline->setSfPresent(55, presentFence2);
250
251 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
252 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
253 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
254}
255
256TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800257 // Global increment
258 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
259 // Layer specific increment
260 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700261 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
262 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
263 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
264 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
265 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 60});
Alec Mouri9a29e672020-09-14 12:39:14 -0700266 auto surfaceFrame1 =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800267 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
268 sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700269 auto surfaceFrame2 =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800270 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
271 sLayerNameTwo, sLayerNameTwo);
272 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
273 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
274 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
275 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
276 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700277 mFrameTimeline->setSfPresent(26, presentFence1);
278 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800279 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
280 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700281 presentFence1->signalForTest(42);
282
283 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800284 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700285 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
286 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
287
288 // Trigger a flush by finalizing the next DisplayFrame
289 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri9a29e672020-09-14 12:39:14 -0700290 auto surfaceFrame3 =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800291 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne,
292 sLayerNameOne, sLayerNameOne);
293 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
294 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Dropped);
295 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700296 mFrameTimeline->setSfPresent(56, presentFence2);
297 displayFrame = getDisplayFrame(0);
298
299 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800300 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700301 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
302 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100303 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
304 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700305}
306
307TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
308 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
309 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800310 // Global increment
311 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_))
312 .Times(static_cast<int32_t>(*maxDisplayFrames));
313 // Layer specific increment
314 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_))
315 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700316 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700317 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
318 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
319 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
320 int64_t sfToken = mTokenManager->generateTokenForPredictions(
321 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700322 auto surfaceFrame =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800323 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken, sPidOne, sUidOne,
324 sLayerNameOne, sLayerNameOne);
325 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, 11);
326 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
327 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700328 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
329 presentFence->signalForTest(32 + frameTimeFactor);
330 frameTimeFactor += 30;
331 }
332 auto displayFrame0 = getDisplayFrame(0);
333
334 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800335 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700336
337 // Add one more display frame
338 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
339 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
340 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
341 int64_t sfToken = mTokenManager->generateTokenForPredictions(
342 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700343 auto surfaceFrame =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800344 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken, sPidOne, sUidOne,
345 sLayerNameOne, sLayerNameOne);
346 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, 11);
347 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
348 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700349 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
350 presentFence->signalForTest(32 + frameTimeFactor);
351 displayFrame0 = getDisplayFrame(0);
352
353 // The window should have slided by 1 now and the previous 0th display frame
354 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800355 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700356}
357
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700358TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800359 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, 0,
360 "acquireFenceAfterQueue",
361 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700362 surfaceFrame->setActualQueueTime(123);
363 surfaceFrame->setAcquireFenceTime(456);
364 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
365}
366
367TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800368 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, 0,
369 "acquireFenceAfterQueue",
370 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700371 surfaceFrame->setActualQueueTime(456);
372 surfaceFrame->setAcquireFenceTime(123);
373 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
374}
375
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700376TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800377 // Global increment
378 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_))
379 .Times(static_cast<int32_t>(*maxDisplayFrames + 10));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700380 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
381 presentFence->signalForTest(2);
382
383 // Size shouldn't exceed maxDisplayFrames - 64
384 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700385 auto surfaceFrame =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800386 mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne,
387 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700388 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800389 mFrameTimeline->setSfWakeUp(sfToken, 22, 11);
390 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
391 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700392 mFrameTimeline->setSfPresent(27, presentFence);
393 }
394 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
395
396 // Increase the size to 256
397 mFrameTimeline->setMaxDisplayFrames(256);
398 EXPECT_EQ(*maxDisplayFrames, 256);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800399 // Global increment
400 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_))
401 .Times(static_cast<int32_t>(*maxDisplayFrames + 10));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700402
403 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700404 auto surfaceFrame =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800405 mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne,
406 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700407 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800408 mFrameTimeline->setSfWakeUp(sfToken, 22, 11);
409 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
410 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700411 mFrameTimeline->setSfPresent(27, presentFence);
412 }
413 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
414
415 // Shrink the size to 128
416 mFrameTimeline->setMaxDisplayFrames(128);
417 EXPECT_EQ(*maxDisplayFrames, 128);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800418 // Global increment
419 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_))
420 .Times(static_cast<int32_t>(*maxDisplayFrames + 10));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700421
422 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700423 auto surfaceFrame =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800424 mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne,
425 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700426 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800427 mFrameTimeline->setSfWakeUp(sfToken, 22, 11);
428 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
429 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700430 mFrameTimeline->setSfPresent(27, presentFence);
431 }
432 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
433}
Alec Mouri9a29e672020-09-14 12:39:14 -0700434
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800435// Tests related to TimeStats
Alec Mouri9a29e672020-09-14 12:39:14 -0700436TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
437 EXPECT_CALL(*mTimeStats,
438 incrementJankyFrames(sUidOne, sLayerNameOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800439 HasBit(JankType::SurfaceFlingerCpuDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700440 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800441 incrementJankyFrames(HasBit(JankType::SurfaceFlingerCpuDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700442 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
443 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
444 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
445 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
446 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
447 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
448 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
449 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
450 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
451 auto surfaceFrame1 =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800452 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
453 sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700454 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800455 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
456 11);
457 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
458 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700459 presentFence1->signalForTest(
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100460 std::chrono::duration_cast<std::chrono::nanoseconds>(70ms).count());
Alec Mouri9a29e672020-09-14 12:39:14 -0700461
462 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(59ms).count(),
463 presentFence1);
464}
465
466TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
467 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800468 incrementJankyFrames(sUidOne, sLayerNameOne, HasBit(JankType::DisplayHAL)));
469 EXPECT_CALL(*mTimeStats, incrementJankyFrames(HasBit(JankType::DisplayHAL)));
470
Alec Mouri9a29e672020-09-14 12:39:14 -0700471 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
472 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
473 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
474 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
475 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
476 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
477 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
478 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
479 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
480 auto surfaceFrame1 =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800481 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
482 sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700483 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800484 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
485 30);
486 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
487 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700488 presentFence1->signalForTest(
489 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800490 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700491 presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800492 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700493}
494
495TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
496 EXPECT_CALL(*mTimeStats,
497 incrementJankyFrames(sUidOne, sLayerNameOne,
Jorim Jaggi5814ab82020-12-03 20:45:58 +0100498 HasBit(JankType::AppDeadlineMissed)));
499 EXPECT_CALL(*mTimeStats, incrementJankyFrames(HasBit(JankType::AppDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700500 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
501 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
502 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
503 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
504 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
505 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800506 {std::chrono::duration_cast<std::chrono::nanoseconds>(82ms).count(),
507 std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
508 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700509 auto surfaceFrame1 =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800510 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
511 sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700512 surfaceFrame1->setAcquireFenceTime(
513 std::chrono::duration_cast<std::chrono::nanoseconds>(45ms).count());
514 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800515 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
516 11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700517
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800518 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
519 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700520 presentFence1->signalForTest(
521 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800522 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700523 presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100524
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800525 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700526}
527
Adithya Srinivasan01189672020-10-20 14:23:05 -0700528/*
529 * Tracing Tests
530 *
531 * Trace packets are flushed all the way only when the next packet is traced.
532 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
533 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
534 * will have additional empty frames created for this reason.
535 */
536TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
537 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800538 // Global increment
539 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700540 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
541 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
542
543 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
544 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800545 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne,
546 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700547
548 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800549 mFrameTimeline->setSfWakeUp(token1, 20, 11);
550 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
551 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700552 mFrameTimeline->setSfPresent(25, presentFence1);
553 presentFence1->signalForTest(30);
554
555 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
556 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800557 mFrameTimeline->setSfWakeUp(token2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700558 mFrameTimeline->setSfPresent(55, presentFence2);
559
560 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
561 EXPECT_EQ(packets.size(), 0);
562}
563
564TEST_F(FrameTimelineTest, tracing_sanityTest) {
565 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800566 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000567 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800568 // Layer specific increment
569 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700570 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
571 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
572
573 tracingSession->StartBlocking();
574 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
575 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800576 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne,
577 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700578
579 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800580 mFrameTimeline->setSfWakeUp(token2, 20, 11);
581 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
582 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700583 mFrameTimeline->setSfPresent(25, presentFence1);
584 presentFence1->signalForTest(30);
585
586 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
587 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800588 mFrameTimeline->setSfWakeUp(token2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700589 mFrameTimeline->setSfPresent(55, presentFence2);
590 presentFence2->signalForTest(55);
591
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000592 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700593 tracingSession->StopBlocking();
594
595 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000596 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
597 EXPECT_EQ(packets.size(), 8);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700598}
599
600TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
601 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800602 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000603 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700604 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
605 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
606
607 tracingSession->StartBlocking();
608 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
609
610 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800611 mFrameTimeline->setSfWakeUp(-1, 20, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700612 mFrameTimeline->setSfPresent(25, presentFence1);
613 presentFence1->signalForTest(30);
614
615 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
616 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800617 mFrameTimeline->setSfWakeUp(token1, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700618 mFrameTimeline->setSfPresent(55, presentFence2);
619 presentFence2->signalForTest(60);
620
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000621 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700622 tracingSession->StopBlocking();
623
624 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700625 EXPECT_EQ(packets.size(), 0);
626}
627
628TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
629 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800630 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000631 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700632 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
633 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
634
635 tracingSession->StartBlocking();
636 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
637 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800638 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne,
639 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700640
641 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800642 mFrameTimeline->setSfWakeUp(token1, 20, 11);
643 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
644 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700645 mFrameTimeline->setSfPresent(25, presentFence1);
646 presentFence1->signalForTest(30);
647
648 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
649 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800650 mFrameTimeline->setSfWakeUp(token2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700651 mFrameTimeline->setSfPresent(55, presentFence2);
652 presentFence2->signalForTest(60);
653
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000654 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700655 tracingSession->StopBlocking();
656
657 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000658 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
659 // token).
660 EXPECT_EQ(packets.size(), 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700661}
662
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000663void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
664 const ProtoExpectedDisplayFrameStart& source) {
665 ASSERT_TRUE(received.has_cookie());
666 EXPECT_EQ(received.cookie(), source.cookie());
667
Adithya Srinivasan01189672020-10-20 14:23:05 -0700668 ASSERT_TRUE(received.has_token());
669 EXPECT_EQ(received.token(), source.token());
670
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000671 ASSERT_TRUE(received.has_pid());
672 EXPECT_EQ(received.pid(), source.pid());
673}
674
675void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
676 const ProtoActualDisplayFrameStart& source) {
677 ASSERT_TRUE(received.has_cookie());
678 EXPECT_EQ(received.cookie(), source.cookie());
679
680 ASSERT_TRUE(received.has_token());
681 EXPECT_EQ(received.token(), source.token());
682
683 ASSERT_TRUE(received.has_pid());
684 EXPECT_EQ(received.pid(), source.pid());
685
Adithya Srinivasan01189672020-10-20 14:23:05 -0700686 ASSERT_TRUE(received.has_present_type());
687 EXPECT_EQ(received.present_type(), source.present_type());
688 ASSERT_TRUE(received.has_on_time_finish());
689 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
690 ASSERT_TRUE(received.has_gpu_composition());
691 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
692 ASSERT_TRUE(received.has_jank_type());
693 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700694}
695
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000696void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
697 const ProtoExpectedSurfaceFrameStart& source) {
698 ASSERT_TRUE(received.has_cookie());
699 EXPECT_EQ(received.cookie(), source.cookie());
700
Adithya Srinivasan01189672020-10-20 14:23:05 -0700701 ASSERT_TRUE(received.has_token());
702 EXPECT_EQ(received.token(), source.token());
703
704 ASSERT_TRUE(received.has_display_frame_token());
705 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
706
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000707 ASSERT_TRUE(received.has_pid());
708 EXPECT_EQ(received.pid(), source.pid());
709
710 ASSERT_TRUE(received.has_layer_name());
711 EXPECT_EQ(received.layer_name(), source.layer_name());
712}
713
714void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
715 const ProtoActualSurfaceFrameStart& source) {
716 ASSERT_TRUE(received.has_cookie());
717 EXPECT_EQ(received.cookie(), source.cookie());
718
719 ASSERT_TRUE(received.has_token());
720 EXPECT_EQ(received.token(), source.token());
721
722 ASSERT_TRUE(received.has_display_frame_token());
723 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
724
725 ASSERT_TRUE(received.has_pid());
726 EXPECT_EQ(received.pid(), source.pid());
727
728 ASSERT_TRUE(received.has_layer_name());
729 EXPECT_EQ(received.layer_name(), source.layer_name());
730
Adithya Srinivasan01189672020-10-20 14:23:05 -0700731 ASSERT_TRUE(received.has_present_type());
732 EXPECT_EQ(received.present_type(), source.present_type());
733 ASSERT_TRUE(received.has_on_time_finish());
734 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
735 ASSERT_TRUE(received.has_gpu_composition());
736 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
737 ASSERT_TRUE(received.has_jank_type());
738 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000739}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700740
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000741void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
742 ASSERT_TRUE(received.has_cookie());
743 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700744}
745
746TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
747 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800748 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000749 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700750 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
751 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
752
753 tracingSession->StartBlocking();
754 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
755 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
756
757 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800758 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700759 mFrameTimeline->setSfPresent(26, presentFence1);
760 presentFence1->signalForTest(31);
761
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000762 int64_t traceCookie = snoopCurrentTraceCookie();
763 ProtoExpectedDisplayFrameStart protoExpectedDisplayFrameStart;
764 protoExpectedDisplayFrameStart.set_cookie(traceCookie + 1);
765 protoExpectedDisplayFrameStart.set_token(displayFrameToken1);
766 protoExpectedDisplayFrameStart.set_pid(kSurfaceFlingerPid);
767
768 ProtoFrameEnd protoExpectedDisplayFrameEnd;
769 protoExpectedDisplayFrameEnd.set_cookie(traceCookie + 1);
770
771 ProtoActualDisplayFrameStart protoActualDisplayFrameStart;
772 protoActualDisplayFrameStart.set_cookie(traceCookie + 2);
773 protoActualDisplayFrameStart.set_token(displayFrameToken1);
774 protoActualDisplayFrameStart.set_pid(kSurfaceFlingerPid);
775 protoActualDisplayFrameStart.set_present_type(
776 ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
777 protoActualDisplayFrameStart.set_on_time_finish(true);
778 protoActualDisplayFrameStart.set_gpu_composition(false);
779 protoActualDisplayFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
780
781 ProtoFrameEnd protoActualDisplayFrameEnd;
782 protoActualDisplayFrameEnd.set_cookie(traceCookie + 2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700783
784 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
785 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800786 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700787 mFrameTimeline->setSfPresent(55, presentFence2);
788 presentFence2->signalForTest(55);
789
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000790 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700791 tracingSession->StopBlocking();
792
793 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000794 EXPECT_EQ(packets.size(), 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700795
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000796 // Packet - 0 : ExpectedDisplayFrameStart
797 const auto& packet0 = packets[0];
798 ASSERT_TRUE(packet0.has_timestamp());
799 EXPECT_EQ(packet0.timestamp(), 10);
800 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700801
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000802 const auto& event0 = packet0.frame_timeline_event();
803 ASSERT_TRUE(event0.has_expected_display_frame_start());
804 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
805 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
806
807 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
808 const auto& packet1 = packets[1];
809 ASSERT_TRUE(packet1.has_timestamp());
810 EXPECT_EQ(packet1.timestamp(), 25);
811 ASSERT_TRUE(packet1.has_frame_timeline_event());
812
813 const auto& event1 = packet1.frame_timeline_event();
814 ASSERT_TRUE(event1.has_frame_end());
815 const auto& expectedDisplayFrameEnd = event1.frame_end();
816 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
817
818 // Packet - 2 : ActualDisplayFrameStart
819 const auto& packet2 = packets[2];
820 ASSERT_TRUE(packet2.has_timestamp());
821 EXPECT_EQ(packet2.timestamp(), 20);
822 ASSERT_TRUE(packet2.has_frame_timeline_event());
823
824 const auto& event2 = packet2.frame_timeline_event();
825 ASSERT_TRUE(event2.has_actual_display_frame_start());
826 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
827 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
828
829 // Packet - 3 : FrameEnd (ActualDisplayFrame)
830 const auto& packet3 = packets[3];
831 ASSERT_TRUE(packet3.has_timestamp());
832 EXPECT_EQ(packet3.timestamp(), 26);
833 ASSERT_TRUE(packet3.has_frame_timeline_event());
834
835 const auto& event3 = packet3.frame_timeline_event();
836 ASSERT_TRUE(event3.has_frame_end());
837 const auto& actualDisplayFrameEnd = event3.frame_end();
838 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700839}
840
841TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
842 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800843 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000844 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800845 // Layer specific increment
846 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700847 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
848 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
849
850 tracingSession->StartBlocking();
851 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
852 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
853 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
854
855 auto surfaceFrame1 =
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800856 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken, sPidOne, sUidOne,
857 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700858 surfaceFrame1->setActualStartTime(0);
859 surfaceFrame1->setActualQueueTime(15);
860 surfaceFrame1->setAcquireFenceTime(20);
861
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000862 // First 2 cookies will be used by the DisplayFrame
863 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
864
865 ProtoExpectedSurfaceFrameStart protoExpectedSurfaceFrameStart;
866 protoExpectedSurfaceFrameStart.set_cookie(traceCookie + 1);
867 protoExpectedSurfaceFrameStart.set_token(surfaceFrameToken);
868 protoExpectedSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
869 protoExpectedSurfaceFrameStart.set_pid(sPidOne);
870 protoExpectedSurfaceFrameStart.set_layer_name(sLayerNameOne);
871
872 ProtoFrameEnd protoExpectedSurfaceFrameEnd;
873 protoExpectedSurfaceFrameEnd.set_cookie(traceCookie + 1);
874
875 ProtoActualSurfaceFrameStart protoActualSurfaceFrameStart;
876 protoActualSurfaceFrameStart.set_cookie(traceCookie + 2);
877 protoActualSurfaceFrameStart.set_token(surfaceFrameToken);
878 protoActualSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
879 protoActualSurfaceFrameStart.set_pid(sPidOne);
880 protoActualSurfaceFrameStart.set_layer_name(sLayerNameOne);
881 protoActualSurfaceFrameStart.set_present_type(
882 ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
883 protoActualSurfaceFrameStart.set_on_time_finish(true);
884 protoActualSurfaceFrameStart.set_gpu_composition(false);
885 protoActualSurfaceFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
886
887 ProtoFrameEnd protoActualSurfaceFrameEnd;
888 protoActualSurfaceFrameEnd.set_cookie(traceCookie + 2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700889
890 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800891 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, 11);
892 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
893 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700894 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800895 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700896
897 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
898 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800899 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700900 mFrameTimeline->setSfPresent(55, presentFence2);
901 presentFence2->signalForTest(55);
902
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000903 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700904 tracingSession->StopBlocking();
905
906 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000907 EXPECT_EQ(packets.size(), 8);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700908
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000909 // Packet - 4 : ExpectedSurfaceFrameStart
910 const auto& packet4 = packets[4];
911 ASSERT_TRUE(packet4.has_timestamp());
912 EXPECT_EQ(packet4.timestamp(), 10);
913 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700914
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000915 const auto& event4 = packet4.frame_timeline_event();
916 ASSERT_TRUE(event4.has_expected_surface_frame_start());
917 const auto& expectedSurfaceFrameStart = event4.expected_surface_frame_start();
918 validateTraceEvent(expectedSurfaceFrameStart, protoExpectedSurfaceFrameStart);
919
920 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame)
921 const auto& packet5 = packets[5];
922 ASSERT_TRUE(packet5.has_timestamp());
923 EXPECT_EQ(packet5.timestamp(), 25);
924 ASSERT_TRUE(packet5.has_frame_timeline_event());
925
926 const auto& event5 = packet5.frame_timeline_event();
927 ASSERT_TRUE(event5.has_frame_end());
928 const auto& expectedSurfaceFrameEnd = event5.frame_end();
929 validateTraceEvent(expectedSurfaceFrameEnd, protoExpectedSurfaceFrameEnd);
930
931 // Packet - 6 : ActualSurfaceFrameStart
932 const auto& packet6 = packets[6];
933 ASSERT_TRUE(packet6.has_timestamp());
934 EXPECT_EQ(packet6.timestamp(), 10);
935 ASSERT_TRUE(packet6.has_frame_timeline_event());
936
937 const auto& event6 = packet6.frame_timeline_event();
938 ASSERT_TRUE(event6.has_actual_surface_frame_start());
939 const auto& actualSurfaceFrameStart = event6.actual_surface_frame_start();
940 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
941
942 // Packet - 7 : FrameEnd (ActualSurfaceFrame)
943 const auto& packet7 = packets[7];
944 ASSERT_TRUE(packet7.has_timestamp());
945 EXPECT_EQ(packet7.timestamp(), 20);
946 ASSERT_TRUE(packet7.has_frame_timeline_event());
947
948 const auto& event7 = packet7.frame_timeline_event();
949 ASSERT_TRUE(event7.has_frame_end());
950 const auto& actualSurfaceFrameEnd = event7.frame_end();
951 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700952}
953
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800954// Tests for Jank classification
955TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
956 // Global increment
957 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
958 // Layer specific increment
959 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_));
960 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
961 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
962 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
963 auto surfaceFrame =
964 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken, sPidOne, sUidOne,
965 sLayerNameOne, sLayerNameOne);
966 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
967 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
968 mFrameTimeline->addSurfaceFrame(surfaceFrame);
969 mFrameTimeline->setSfPresent(26, presentFence1);
970 auto displayFrame = getDisplayFrame(0);
971 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
972 presentFence1->signalForTest(29);
973
974 // Fences haven't been flushed yet, so it should be 0
975 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
976 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
977
978 addEmptyDisplayFrame();
979 displayFrame = getDisplayFrame(0);
980
981 // Fences have flushed, so the present timestamps should be updated
982 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
983 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
984 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
985 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
986 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
987}
988
989TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
990 // Global increment
991 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
992 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
993 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
994 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
995 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
996 mFrameTimeline->setSfPresent(26, presentFence1);
997 auto displayFrame = getDisplayFrame(0);
998 presentFence1->signalForTest(30);
999
1000 // Fences for the first frame haven't been flushed yet, so it should be 0
1001 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1002
1003 // Trigger a flush by finalizing the next DisplayFrame
1004 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1005 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
1006 mFrameTimeline->setSfPresent(56, presentFence2);
1007 displayFrame = getDisplayFrame(0);
1008
1009 // Fences for the first frame have flushed, so the present timestamps should be updated
1010 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1011 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1012 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1013 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1014
1015 // Fences for the second frame haven't been flushed yet, so it should be 0
1016 auto displayFrame2 = getDisplayFrame(1);
1017 presentFence2->signalForTest(65);
1018 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1019
1020 addEmptyDisplayFrame();
1021 displayFrame2 = getDisplayFrame(1);
1022
1023 // Fences for the second frame have flushed, so the present timestamps should be updated
1024 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1025 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1026 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1027 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1028}
1029
1030TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
1031 // Global increment
1032 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1033 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1034 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1035 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1036 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
1037 mFrameTimeline->setSfPresent(26, presentFence1);
1038 auto displayFrame = getDisplayFrame(0);
1039 presentFence1->signalForTest(50);
1040
1041 // Fences for the first frame haven't been flushed yet, so it should be 0
1042 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1043
1044 // Trigger a flush by finalizing the next DisplayFrame
1045 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1046 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
1047 mFrameTimeline->setSfPresent(56, presentFence2);
1048 displayFrame = getDisplayFrame(0);
1049
1050 // Fences for the first frame have flushed, so the present timestamps should be updated
1051 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1052 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1053 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1054 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1055
1056 // Fences for the second frame haven't been flushed yet, so it should be 0
1057 auto displayFrame2 = getDisplayFrame(1);
1058 presentFence2->signalForTest(75);
1059 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1060
1061 addEmptyDisplayFrame();
1062 displayFrame2 = getDisplayFrame(1);
1063
1064 // Fences for the second frame have flushed, so the present timestamps should be updated
1065 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1066 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1067 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1068 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1069}
1070
1071TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
1072 // Global increment
1073 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
1074 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1075 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
1076 mFrameTimeline->setSfWakeUp(sfToken1, 12, 11);
1077
1078 mFrameTimeline->setSfPresent(22, presentFence1);
1079 auto displayFrame = getDisplayFrame(0);
1080 presentFence1->signalForTest(28);
1081
1082 // Fences haven't been flushed yet, so it should be 0
1083 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1084
1085 addEmptyDisplayFrame();
1086 displayFrame = getDisplayFrame(0);
1087
1088 // Fences have flushed, so the present timestamps should be updated
1089 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1090 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1091 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1092 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1093}
1094
1095TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
1096 // Global increment
1097 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
1098 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1099 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1100 mFrameTimeline->setSfWakeUp(sfToken1, 12, 11);
1101 mFrameTimeline->setSfPresent(36, presentFence1);
1102 auto displayFrame = getDisplayFrame(0);
1103 presentFence1->signalForTest(52);
1104
1105 // Fences haven't been flushed yet, so it should be 0
1106 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1107
1108 addEmptyDisplayFrame();
1109 displayFrame = getDisplayFrame(0);
1110
1111 // Fences have flushed, so the present timestamps should be updated
1112 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1113 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1114 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1115 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1116}
1117
1118TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
1119 // Global increment
1120 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1121 // Layer specific increment
1122 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
1123 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1124 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1125 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1126 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1127 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1128 auto surfaceFrame1 =
1129 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
1130 sLayerNameOne, sLayerNameOne);
1131 surfaceFrame1->setAcquireFenceTime(16);
1132 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
1133 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1134 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1135 mFrameTimeline->setSfPresent(26, presentFence1);
1136 auto displayFrame1 = getDisplayFrame(0);
1137 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1138 presentFence1->signalForTest(30);
1139
1140 // Fences for the first frame haven't been flushed yet, so it should be 0
1141 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1142 auto actuals1 = presentedSurfaceFrame1.getActuals();
1143 EXPECT_EQ(actuals1.presentTime, 0);
1144
1145 // Trigger a flush by finalizing the next DisplayFrame
1146 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1147 auto surfaceFrame2 =
1148 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne,
1149 sLayerNameOne, sLayerNameOne);
1150 surfaceFrame2->setAcquireFenceTime(36);
1151 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
1152 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1153 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1154 mFrameTimeline->setSfPresent(56, presentFence2);
1155 auto displayFrame2 = getDisplayFrame(1);
1156 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1157
1158 // Fences for the first frame have flushed, so the present timestamps should be updated
1159 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1160 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1161 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1162 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1163
1164 actuals1 = presentedSurfaceFrame1.getActuals();
1165 EXPECT_EQ(actuals1.presentTime, 30);
1166 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1167 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1168 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1169
1170 // Fences for the second frame haven't been flushed yet, so it should be 0
1171 presentFence2->signalForTest(65);
1172 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1173 auto actuals2 = presentedSurfaceFrame2.getActuals();
1174 EXPECT_EQ(actuals2.presentTime, 0);
1175
1176 addEmptyDisplayFrame();
1177
1178 // Fences for the second frame have flushed, so the present timestamps should be updated
1179 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1180 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1181 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1182 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1183
1184 actuals2 = presentedSurfaceFrame2.getActuals();
1185 EXPECT_EQ(actuals2.presentTime, 65);
1186 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1187 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1188 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1189}
1190
1191TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
1192 // Global increment
1193 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1194 // Layer specific increment
1195 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
1196 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1197 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1198 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1199 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1200 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1201 auto surfaceFrame1 =
1202 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
1203 sLayerNameOne, sLayerNameOne);
1204 surfaceFrame1->setAcquireFenceTime(16);
1205 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
1206 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1207 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1208 mFrameTimeline->setSfPresent(26, presentFence1);
1209 auto displayFrame1 = getDisplayFrame(0);
1210 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1211 presentFence1->signalForTest(50);
1212
1213 // Fences for the first frame haven't been flushed yet, so it should be 0
1214 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1215 auto actuals1 = presentedSurfaceFrame1.getActuals();
1216 EXPECT_EQ(actuals1.presentTime, 0);
1217
1218 // Trigger a flush by finalizing the next DisplayFrame
1219 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1220 auto surfaceFrame2 =
1221 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne,
1222 sLayerNameOne, sLayerNameOne);
1223 surfaceFrame2->setAcquireFenceTime(36);
1224 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
1225 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1226 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1227 mFrameTimeline->setSfPresent(56, presentFence2);
1228 auto displayFrame2 = getDisplayFrame(1);
1229 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1230
1231 // Fences for the first frame have flushed, so the present timestamps should be updated
1232 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1233 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1234 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1235 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1236
1237 actuals1 = presentedSurfaceFrame1.getActuals();
1238 EXPECT_EQ(actuals1.presentTime, 50);
1239 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1240 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1241 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1242
1243 // Fences for the second frame haven't been flushed yet, so it should be 0
1244 presentFence2->signalForTest(86);
1245 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1246 auto actuals2 = presentedSurfaceFrame2.getActuals();
1247 EXPECT_EQ(actuals2.presentTime, 0);
1248
1249 addEmptyDisplayFrame();
1250
1251 // Fences for the second frame have flushed, so the present timestamps should be updated
1252 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1253 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1254 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1255 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1256
1257 actuals2 = presentedSurfaceFrame2.getActuals();
1258 EXPECT_EQ(actuals2.presentTime, 86);
1259 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1260 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1261 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1262}
1263
1264TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
1265 // Global increment
1266 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
1267 // Layer specific increment
1268 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_));
1269 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1270 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1271 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1272 auto surfaceFrame1 =
1273 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
1274 sLayerNameOne, sLayerNameOne);
1275 surfaceFrame1->setAcquireFenceTime(40);
1276 mFrameTimeline->setSfWakeUp(sfToken1, 42, 11);
1277 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1278 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1279 mFrameTimeline->setSfPresent(46, presentFence1);
1280 auto displayFrame1 = getDisplayFrame(0);
1281 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1282 presentFence1->signalForTest(50);
1283
1284 // Fences for the first frame haven't been flushed yet, so it should be 0
1285 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1286 auto actuals1 = presentedSurfaceFrame1.getActuals();
1287 EXPECT_EQ(actuals1.presentTime, 0);
1288
1289 addEmptyDisplayFrame();
1290
1291 // Fences for the first frame have flushed, so the present timestamps should be updated
1292 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1293 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1294 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1295 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1296
1297 actuals1 = presentedSurfaceFrame1.getActuals();
1298 EXPECT_EQ(actuals1.presentTime, 50);
1299 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1300 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1301 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1302}
1303
1304TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1305 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1306 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1307 // jank to the SurfaceFrame.
1308
1309 // Global increment
1310 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1311 // Layer specific increment
1312 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
1313 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1314 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 36, 40});
1315 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1316 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1317 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1318 auto surfaceFrame1 =
1319 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
1320 sLayerNameOne, sLayerNameOne);
1321 surfaceFrame1->setAcquireFenceTime(26);
1322 mFrameTimeline->setSfWakeUp(sfToken1, 32, 11);
1323 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1324 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1325 mFrameTimeline->setSfPresent(36, presentFence1);
1326 auto displayFrame1 = getDisplayFrame(0);
1327 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1328 presentFence1->signalForTest(40);
1329
1330 // Fences for the first frame haven't been flushed yet, so it should be 0
1331 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1332 auto actuals1 = presentedSurfaceFrame1.getActuals();
1333 EXPECT_EQ(actuals1.presentTime, 0);
1334
1335 // Trigger a flush by finalizing the next DisplayFrame
1336 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1337 auto surfaceFrame2 =
1338 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne,
1339 sLayerNameOne, sLayerNameOne);
1340 surfaceFrame2->setAcquireFenceTime(40);
1341 mFrameTimeline->setSfWakeUp(sfToken2, 43, 11);
1342 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1343 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1344 mFrameTimeline->setSfPresent(56, presentFence2);
1345 auto displayFrame2 = getDisplayFrame(1);
1346 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1347
1348 // Fences for the first frame have flushed, so the present timestamps should be updated
1349 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1350 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1351 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1352 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1353
1354 actuals1 = presentedSurfaceFrame1.getActuals();
1355 EXPECT_EQ(actuals1.presentTime, 40);
1356 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1357 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1358 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1359
1360 // Fences for the second frame haven't been flushed yet, so it should be 0
1361 presentFence2->signalForTest(60);
1362 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1363 auto actuals2 = presentedSurfaceFrame2.getActuals();
1364 EXPECT_EQ(actuals2.presentTime, 0);
1365
1366 addEmptyDisplayFrame();
1367
1368 // Fences for the second frame have flushed, so the present timestamps should be updated
1369 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1370 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1371 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1372 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1373
1374 actuals2 = presentedSurfaceFrame2.getActuals();
1375 EXPECT_EQ(actuals2.presentTime, 60);
1376 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1377 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1378 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1379}
1380
1381TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
1382 // Global increment
1383 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1384 // Layer specific increment
1385 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
1386 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1387 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1388 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1389
1390 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 56, 60});
1391 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 116, 120});
1392 auto surfaceFrame1 =
1393 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne,
1394 sLayerNameOne, sLayerNameOne);
1395 surfaceFrame1->setAcquireFenceTime(50);
1396 mFrameTimeline->setSfWakeUp(sfToken1, 52, 30);
1397 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1398 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1399 mFrameTimeline->setSfPresent(56, presentFence1);
1400 auto displayFrame1 = getDisplayFrame(0);
1401 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1402 presentFence1->signalForTest(60);
1403
1404 // Fences for the first frame haven't been flushed yet, so it should be 0
1405 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1406 auto actuals1 = presentedSurfaceFrame1.getActuals();
1407 EXPECT_EQ(actuals1.presentTime, 0);
1408
1409 // Trigger a flush by finalizing the next DisplayFrame
1410 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1411 auto surfaceFrame2 =
1412 mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne,
1413 sLayerNameOne, sLayerNameOne);
1414 surfaceFrame2->setAcquireFenceTime(84);
1415 mFrameTimeline->setSfWakeUp(sfToken2, 112, 30);
1416 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1417 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1418 mFrameTimeline->setSfPresent(116, presentFence2);
1419 auto displayFrame2 = getDisplayFrame(1);
1420 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1421 presentFence2->signalForTest(120);
1422
1423 // Fences for the first frame have flushed, so the present timestamps should be updated
1424 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1425 actuals1 = presentedSurfaceFrame1.getActuals();
1426 EXPECT_EQ(actuals1.endTime, 50);
1427 EXPECT_EQ(actuals1.presentTime, 60);
1428
1429 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1430 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1431 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1432
1433 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1434 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1435 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1436
1437 // Fences for the second frame haven't been flushed yet, so it should be 0
1438 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1439 auto actuals2 = presentedSurfaceFrame2.getActuals();
1440 EXPECT_EQ(actuals2.presentTime, 0);
1441
1442 addEmptyDisplayFrame();
1443
1444 // Fences for the second frame have flushed, so the present timestamps should be updated
1445 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1446 actuals2 = presentedSurfaceFrame2.getActuals();
1447 EXPECT_EQ(actuals2.presentTime, 120);
1448
1449 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1450 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1451 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1452
1453 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1454 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1455 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1456 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1457}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001458} // namespace android::frametimeline
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001459
1460// TODO(b/129481165): remove the #pragma below and fix conversion issues
1461#pragma clang diagnostic pop // ignored "-Wextra"