blob: b8c1607562cccb93187cdfda5758645a8ee279ee [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;
Alec Mouri9a29e672020-09-14 12:39:14 -070043
Adithya Srinivasanf279e042020-08-17 14:56:27 -070044namespace android::frametimeline {
45
46class FrameTimelineTest : public testing::Test {
47public:
48 FrameTimelineTest() {
49 const ::testing::TestInfo* const test_info =
50 ::testing::UnitTest::GetInstance()->current_test_info();
51 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
52 }
53
54 ~FrameTimelineTest() {
55 const ::testing::TestInfo* const test_info =
56 ::testing::UnitTest::GetInstance()->current_test_info();
57 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
58 }
59
Adithya Srinivasan01189672020-10-20 14:23:05 -070060 static void SetUpTestSuite() {
61 // Need to initialize tracing in process for testing, and only once per test suite.
62 perfetto::TracingInitArgs args;
63 args.backends = perfetto::kInProcessBackend;
64 perfetto::Tracing::Initialize(args);
65 }
66
Adithya Srinivasanf279e042020-08-17 14:56:27 -070067 void SetUp() override {
Alec Mouri9a29e672020-09-14 12:39:14 -070068 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000069 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080070 kTestThresholds);
Adithya Srinivasan01189672020-10-20 14:23:05 -070071 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070072 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000073 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070074 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070075 maxTokenRetentionTime = mTokenManager->kMaxRetentionTime;
76 }
77
Adithya Srinivasan01189672020-10-20 14:23:05 -070078 // Each tracing session can be used for a single block of Start -> Stop.
79 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
80 perfetto::TraceConfig cfg;
81 cfg.set_duration_ms(500);
82 cfg.add_buffers()->set_size_kb(1024);
83 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
84 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
85
86 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
87 tracingSession->Setup(cfg);
88 return tracingSession;
89 }
90
91 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
92 perfetto::TracingSession* tracingSession) {
93 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
94 perfetto::protos::Trace trace;
95 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
96
97 std::vector<perfetto::protos::TracePacket> packets;
98 for (const auto& packet : trace.packet()) {
99 if (!packet.has_frame_timeline_event()) {
100 continue;
101 }
102 packets.emplace_back(packet);
103 }
104 return packets;
105 }
106
107 void addEmptyDisplayFrame() {
108 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000109 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700110 mFrameTimeline->setSfPresent(2500, presentFence1);
111 }
112
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700113 void flushTokens(nsecs_t flushTime) {
114 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
115 mTokenManager->flushTokens(flushTime);
116 }
117
118 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
119 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800120 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
121 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700122 }
123
124 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
125 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
126 return mFrameTimeline->mDisplayFrames[idx];
127 }
128
129 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
130 return a.startTime == b.startTime && a.endTime == b.endTime &&
131 a.presentTime == b.presentTime;
132 }
133
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000134 const std::map<int64_t, TokenManagerPrediction>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700135 return mTokenManager->mPredictions;
136 }
137
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000138 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700139 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
140 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
141 }
142
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000143 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
144
145 void flushTrace() {
146 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
147 FrameTimelineDataSource::Trace(
148 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
149 }
150
Alec Mouri9a29e672020-09-14 12:39:14 -0700151 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700152 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
153 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000154 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700155 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700156 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700157 nsecs_t maxTokenRetentionTime;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000158 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000159 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
160 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(2ns).count();
161 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800162 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
163 kDeadlineThreshold,
164 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700165};
166
Alec Mouri9a29e672020-09-14 12:39:14 -0700167static const std::string sLayerNameOne = "layer1";
168static const std::string sLayerNameTwo = "layer2";
169static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700170static constexpr pid_t sPidOne = 10;
171static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000172static constexpr int32_t sInputEventId = 5;
Alec Mouri9a29e672020-09-14 12:39:14 -0700173
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700174TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
175 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000176 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700177 flushTokens(systemTime() + maxTokenRetentionTime);
178 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
179 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
180
181 // token1 should have expired
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000182 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700183 EXPECT_EQ(predictions.has_value(), false);
184
185 predictions = mTokenManager->getPredictionsForToken(token2);
186 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
187}
188
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700189TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000190 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800191 sLayerNameOne, sLayerNameOne);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000192 auto surfaceFrame2 = mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800193 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700194 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
195 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
196}
197
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700198TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000199 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800200 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700201 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
202}
203
204TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
205 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
206 flushTokens(systemTime() + maxTokenRetentionTime);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000207 auto surfaceFrame =
208 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
209 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700210
211 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
212}
213
214TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
215 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000216 auto surfaceFrame =
217 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
218 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700219
220 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
221 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
222}
223
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000224TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
225 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
226 constexpr int32_t inputEventId = 1;
227 auto surfaceFrame =
228 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
229 sLayerNameOne, sLayerNameOne);
230
231 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
232}
233
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700234TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
235 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700236 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000237 auto surfaceFrame1 =
238 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
239 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700240
241 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800242 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000243 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800244 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
245 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700246 mFrameTimeline->setSfPresent(25, presentFence1);
247 presentFence1->signalForTest(30);
248
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000249 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700250
251 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
252 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000253 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
254 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700255 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
256}
257
258TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800259 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800260 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).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});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700263 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700264 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000265 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
266 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700267 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000268 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
269 sUidOne, sLayerNameTwo, sLayerNameTwo);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800270 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800271 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
272 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
273 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
274 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700275 mFrameTimeline->setSfPresent(26, presentFence1);
276 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800277 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
278 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700279 presentFence1->signalForTest(42);
280
281 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800282 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700283 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
284 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
285
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000286 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700287
288 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800289 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700290 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
291 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100292 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
293 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700294}
295
296TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
297 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
298 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800299 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800300 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800301 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700302 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700303 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
304 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
305 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
306 int64_t sfToken = mTokenManager->generateTokenForPredictions(
307 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700308 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000309 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
310 sPidOne, sUidOne, sLayerNameOne,
311 sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800312 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800313 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
314 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700315 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
316 presentFence->signalForTest(32 + frameTimeFactor);
317 frameTimeFactor += 30;
318 }
319 auto displayFrame0 = getDisplayFrame(0);
320
321 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800322 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700323
324 // Add one more display frame
325 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
326 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
327 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
328 int64_t sfToken = mTokenManager->generateTokenForPredictions(
329 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700330 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000331 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
332 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800333 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800334 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
335 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700336 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
337 presentFence->signalForTest(32 + frameTimeFactor);
338 displayFrame0 = getDisplayFrame(0);
339
340 // The window should have slided by 1 now and the previous 0th display frame
341 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800342 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700343}
344
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700345TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000346 auto surfaceFrame =
347 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
348 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700349 surfaceFrame->setActualQueueTime(123);
350 surfaceFrame->setAcquireFenceTime(456);
351 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
352}
353
354TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000355 auto surfaceFrame =
356 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
357 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700358 surfaceFrame->setActualQueueTime(456);
359 surfaceFrame->setAcquireFenceTime(123);
360 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
361}
362
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700363TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
364 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
365 presentFence->signalForTest(2);
366
367 // Size shouldn't exceed maxDisplayFrames - 64
368 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700369 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000370 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
371 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700372 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800373 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800374 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
375 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700376 mFrameTimeline->setSfPresent(27, presentFence);
377 }
378 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
379
380 // Increase the size to 256
381 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000382 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700383
384 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700385 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000386 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
387 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700388 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800389 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800390 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 // Shrink the size to 128
397 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000398 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700399
400 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700401 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000402 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
403 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700404 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800405 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800406 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
407 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700408 mFrameTimeline->setSfPresent(27, presentFence);
409 }
410 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
411}
Alec Mouri9a29e672020-09-14 12:39:14 -0700412
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800413// Tests related to TimeStats
Alec Mouri9a29e672020-09-14 12:39:14 -0700414TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Alec Mouri363faf02021-01-29 16:34:55 -0800415 Fps refreshRate = Fps(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700416 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800417 incrementJankyFrames(
418 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
419 sLayerNameOne,
420 JankType::SurfaceFlingerCpuDeadlineMissed,
421 std::chrono::duration_cast<
422 std::chrono::nanoseconds>(3ms)
423 .count(),
424 std::chrono::duration_cast<
425 std::chrono::nanoseconds>(10ms)
426 .count(),
427 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700428 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
429 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasanead17162021-02-18 02:17:37 +0000430 {std::chrono::nanoseconds(10ms).count(), std::chrono::nanoseconds(20ms).count(),
431 std::chrono::nanoseconds(60ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700432 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasanead17162021-02-18 02:17:37 +0000433 {std::chrono::nanoseconds(52ms).count(), std::chrono::nanoseconds(56ms).count(),
434 std::chrono::nanoseconds(60ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700435 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000436 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
437 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000438 mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
439 surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(20ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800440 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
441 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000442 presentFence1->signalForTest(std::chrono::nanoseconds(70ms).count());
Alec Mouri9a29e672020-09-14 12:39:14 -0700443
Adithya Srinivasanead17162021-02-18 02:17:37 +0000444 mFrameTimeline->setSfPresent(std::chrono::nanoseconds(59ms).count(), presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700445}
446
447TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800448 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700449 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800450 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
451 sLayerNameOne, JankType::DisplayHAL,
452 0, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800453
Alec Mouri9a29e672020-09-14 12:39:14 -0700454 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
455 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasanead17162021-02-18 02:17:37 +0000456 {std::chrono::nanoseconds(10ms).count(), std::chrono::nanoseconds(20ms).count(),
457 std::chrono::nanoseconds(60ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700458 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasanead17162021-02-18 02:17:37 +0000459 {std::chrono::nanoseconds(52ms).count(), std::chrono::nanoseconds(56ms).count(),
460 std::chrono::nanoseconds(60ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700461 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000462 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
463 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000464 mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800465 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000466 surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(20ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800467 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000468 presentFence1->signalForTest(std::chrono::nanoseconds(90ms).count());
469 mFrameTimeline->setSfPresent(std::chrono::nanoseconds(56ms).count(), presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800470 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700471}
472
473TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800474 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700475 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800476 incrementJankyFrames(
477 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
478 sLayerNameOne, JankType::AppDeadlineMissed, 0, 0,
479 std::chrono::duration_cast<
480 std::chrono::nanoseconds>(25ms)
481 .count()}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700482 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
483 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasanead17162021-02-18 02:17:37 +0000484 {std::chrono::nanoseconds(10ms).count(), std::chrono::nanoseconds(20ms).count(),
485 std::chrono::nanoseconds(60ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700486 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasanead17162021-02-18 02:17:37 +0000487 {std::chrono::nanoseconds(82ms).count(), std::chrono::nanoseconds(86ms).count(),
488 std::chrono::nanoseconds(90ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700489 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000490 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
491 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000492 surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(45ms).count());
493 mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700494
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800495 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
496 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000497 presentFence1->signalForTest(std::chrono::nanoseconds(90ms).count());
498 mFrameTimeline->setSfPresent(std::chrono::nanoseconds(86ms).count(), presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100499
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800500 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700501}
502
Adithya Srinivasanead17162021-02-18 02:17:37 +0000503TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
504 Fps refreshRate = Fps::fromPeriodNsecs(std::chrono::nanoseconds(32ms).count());
505 EXPECT_CALL(*mTimeStats,
506 incrementJankyFrames(
507 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
508 sLayerNameOne,
509 JankType::SurfaceFlingerScheduling, 0, 0,
510 std::chrono::duration_cast<
511 std::chrono::nanoseconds>(-10ms)
512 .count()}));
513 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
514 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
515 {std::chrono::nanoseconds(40ms).count(), std::chrono::nanoseconds(60ms).count(),
516 std::chrono::nanoseconds(92ms).count()});
517 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
518 {std::chrono::nanoseconds(52ms).count(), std::chrono::nanoseconds(56ms).count(),
519 std::chrono::nanoseconds(60ms).count()});
520 auto surfaceFrame1 =
521 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
522 sUidOne, sLayerNameOne, sLayerNameOne);
523 surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(50ms).count());
524 mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
525
526 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
527 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
528 presentFence1->signalForTest(std::chrono::nanoseconds(60ms).count());
529 mFrameTimeline->setSfPresent(std::chrono::nanoseconds(56ms).count(), presentFence1);
530
531 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
532}
533
534TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
535 Fps refreshRate = Fps(16.66f);
536 EXPECT_CALL(*mTimeStats,
537 incrementJankyFrames(
538 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
539 sLayerNameOne, JankType::PredictionError, 0,
540 std::chrono::duration_cast<
541 std::chrono::nanoseconds>(5ms)
542 .count(),
543 0}));
544 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
545 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
546 {std::chrono::nanoseconds(30ms).count(), std::chrono::nanoseconds(40ms).count(),
547 std::chrono::nanoseconds(60ms).count()});
548 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
549 {std::chrono::nanoseconds(52ms).count(), std::chrono::nanoseconds(56ms).count(),
550 std::chrono::nanoseconds(60ms).count()});
551 auto surfaceFrame1 =
552 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
553 sUidOne, sLayerNameOne, sLayerNameOne);
554 surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(40ms).count());
555 mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
556
557 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
558 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
559 presentFence1->signalForTest(std::chrono::nanoseconds(65ms).count());
560 mFrameTimeline->setSfPresent(std::chrono::nanoseconds(56ms).count(), presentFence1);
561
562 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
563}
564
565TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
566 Fps refreshRate = Fps::fromPeriodNsecs(std::chrono::nanoseconds(32ms).count());
567 EXPECT_CALL(*mTimeStats,
568 incrementJankyFrames(
569 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
570 sLayerNameOne,
571 JankType::BufferStuffing |
572 JankType::SurfaceFlingerScheduling,
573 0, 0, 0}));
574 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
575 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
576 {std::chrono::nanoseconds(30ms).count(), std::chrono::nanoseconds(40ms).count(),
577 std::chrono::nanoseconds(58ms).count()});
578 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
579 {std::chrono::nanoseconds(82ms).count(), std::chrono::nanoseconds(86ms).count(),
580 std::chrono::nanoseconds(90ms).count()});
581 auto surfaceFrame1 =
582 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
583 sUidOne, sLayerNameOne, sLayerNameOne);
584 surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(40ms).count());
585 mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(82ms).count(), refreshRate);
586
587 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
588 /*previousLatchTime*/
589 std::chrono::nanoseconds(56ms).count());
590 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
591 presentFence1->signalForTest(std::chrono::nanoseconds(90ms).count());
592 mFrameTimeline->setSfPresent(std::chrono::nanoseconds(86ms).count(), presentFence1);
593
594 EXPECT_EQ(surfaceFrame1->getJankType(),
595 JankType::BufferStuffing | JankType::SurfaceFlingerScheduling);
596}
597
Alec Mouri363faf02021-01-29 16:34:55 -0800598TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
599 Fps refreshRate = Fps(11.0);
600 Fps renderRate = Fps(30.0);
601 EXPECT_CALL(*mTimeStats,
602 incrementJankyFrames(
603 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
604 JankType::AppDeadlineMissed, 0, 0,
605 std::chrono::duration_cast<
606 std::chrono::nanoseconds>(25ms)
607 .count()}));
608 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
609 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasanead17162021-02-18 02:17:37 +0000610 {std::chrono::nanoseconds(10ms).count(), std::chrono::nanoseconds(20ms).count(),
611 std::chrono::nanoseconds(60ms).count()});
Alec Mouri363faf02021-01-29 16:34:55 -0800612 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasanead17162021-02-18 02:17:37 +0000613 {std::chrono::nanoseconds(82ms).count(), std::chrono::nanoseconds(86ms).count(),
614 std::chrono::nanoseconds(90ms).count()});
Alec Mouri363faf02021-01-29 16:34:55 -0800615 auto surfaceFrame1 =
616 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
617 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000618 surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(45ms).count());
619 mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800620
621 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
622 surfaceFrame1->setRenderRate(renderRate);
623 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000624 presentFence1->signalForTest(std::chrono::nanoseconds(90ms).count());
625 mFrameTimeline->setSfPresent(std::chrono::nanoseconds(86ms).count(), presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800626
627 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
628}
629
Adithya Srinivasan01189672020-10-20 14:23:05 -0700630/*
631 * Tracing Tests
632 *
633 * Trace packets are flushed all the way only when the next packet is traced.
634 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
635 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
636 * will have additional empty frames created for this reason.
637 */
638TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
639 auto tracingSession = getTracingSessionForTest();
640 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700641 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000642 auto surfaceFrame1 =
643 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
644 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700645
646 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800647 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800648 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
649 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700650 mFrameTimeline->setSfPresent(25, presentFence1);
651 presentFence1->signalForTest(30);
652
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000653 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700654
655 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000656 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700657}
658
659TEST_F(FrameTimelineTest, tracing_sanityTest) {
660 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800661 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800662 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700663 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700664
665 tracingSession->StartBlocking();
666 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
667 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000668 auto surfaceFrame1 =
669 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
670 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700671
672 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800673 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800674 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
675 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700676 mFrameTimeline->setSfPresent(25, presentFence1);
677 presentFence1->signalForTest(30);
678
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000679 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000680 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700681 tracingSession->StopBlocking();
682
683 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000684 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000685 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700686}
687
688TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
689 auto tracingSession = getTracingSessionForTest();
690 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700691
692 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700693
694 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800695 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700696 mFrameTimeline->setSfPresent(25, presentFence1);
697 presentFence1->signalForTest(30);
698
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000699 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000700 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700701 tracingSession->StopBlocking();
702
703 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000704 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700705}
706
707TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
708 auto tracingSession = getTracingSessionForTest();
709 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700710
711 tracingSession->StartBlocking();
712 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000713 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800714 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700715
716 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800717 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800718 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
719 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700720 mFrameTimeline->setSfPresent(25, presentFence1);
721 presentFence1->signalForTest(30);
722
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000723 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000724 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700725 tracingSession->StopBlocking();
726
727 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000728 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
729 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000730 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700731}
732
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000733ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
734 pid_t pid) {
735 ProtoExpectedDisplayFrameStart proto;
736 proto.set_cookie(cookie);
737 proto.set_token(token);
738 proto.set_pid(pid);
739 return proto;
740}
741
742ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
743 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
744 bool gpuComposition, ProtoJankType jankType) {
745 ProtoActualDisplayFrameStart proto;
746 proto.set_cookie(cookie);
747 proto.set_token(token);
748 proto.set_pid(pid);
749 proto.set_present_type(presentType);
750 proto.set_on_time_finish(onTimeFinish);
751 proto.set_gpu_composition(gpuComposition);
752 proto.set_jank_type(jankType);
753 return proto;
754}
755
756ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
757 int64_t displayFrameToken,
758 pid_t pid,
759 std::string layerName) {
760 ProtoExpectedSurfaceFrameStart proto;
761 proto.set_cookie(cookie);
762 proto.set_token(token);
763 proto.set_display_frame_token(displayFrameToken);
764 proto.set_pid(pid);
765 proto.set_layer_name(layerName);
766 return proto;
767}
768
769ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
770 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
771 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
772 ProtoJankType jankType) {
773 ProtoActualSurfaceFrameStart proto;
774 proto.set_cookie(cookie);
775 proto.set_token(token);
776 proto.set_display_frame_token(displayFrameToken);
777 proto.set_pid(pid);
778 proto.set_layer_name(layerName);
779 proto.set_present_type(presentType);
780 proto.set_on_time_finish(onTimeFinish);
781 proto.set_gpu_composition(gpuComposition);
782 proto.set_jank_type(jankType);
783 return proto;
784}
785
786ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
787 ProtoFrameEnd proto;
788 proto.set_cookie(cookie);
789 return proto;
790}
791
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000792void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
793 const ProtoExpectedDisplayFrameStart& source) {
794 ASSERT_TRUE(received.has_cookie());
795 EXPECT_EQ(received.cookie(), source.cookie());
796
Adithya Srinivasan01189672020-10-20 14:23:05 -0700797 ASSERT_TRUE(received.has_token());
798 EXPECT_EQ(received.token(), source.token());
799
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000800 ASSERT_TRUE(received.has_pid());
801 EXPECT_EQ(received.pid(), source.pid());
802}
803
804void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
805 const ProtoActualDisplayFrameStart& source) {
806 ASSERT_TRUE(received.has_cookie());
807 EXPECT_EQ(received.cookie(), source.cookie());
808
809 ASSERT_TRUE(received.has_token());
810 EXPECT_EQ(received.token(), source.token());
811
812 ASSERT_TRUE(received.has_pid());
813 EXPECT_EQ(received.pid(), source.pid());
814
Adithya Srinivasan01189672020-10-20 14:23:05 -0700815 ASSERT_TRUE(received.has_present_type());
816 EXPECT_EQ(received.present_type(), source.present_type());
817 ASSERT_TRUE(received.has_on_time_finish());
818 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
819 ASSERT_TRUE(received.has_gpu_composition());
820 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
821 ASSERT_TRUE(received.has_jank_type());
822 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700823}
824
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000825void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
826 const ProtoExpectedSurfaceFrameStart& source) {
827 ASSERT_TRUE(received.has_cookie());
828 EXPECT_EQ(received.cookie(), source.cookie());
829
Adithya Srinivasan01189672020-10-20 14:23:05 -0700830 ASSERT_TRUE(received.has_token());
831 EXPECT_EQ(received.token(), source.token());
832
833 ASSERT_TRUE(received.has_display_frame_token());
834 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
835
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000836 ASSERT_TRUE(received.has_pid());
837 EXPECT_EQ(received.pid(), source.pid());
838
839 ASSERT_TRUE(received.has_layer_name());
840 EXPECT_EQ(received.layer_name(), source.layer_name());
841}
842
843void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
844 const ProtoActualSurfaceFrameStart& source) {
845 ASSERT_TRUE(received.has_cookie());
846 EXPECT_EQ(received.cookie(), source.cookie());
847
848 ASSERT_TRUE(received.has_token());
849 EXPECT_EQ(received.token(), source.token());
850
851 ASSERT_TRUE(received.has_display_frame_token());
852 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
853
854 ASSERT_TRUE(received.has_pid());
855 EXPECT_EQ(received.pid(), source.pid());
856
857 ASSERT_TRUE(received.has_layer_name());
858 EXPECT_EQ(received.layer_name(), source.layer_name());
859
Adithya Srinivasan01189672020-10-20 14:23:05 -0700860 ASSERT_TRUE(received.has_present_type());
861 EXPECT_EQ(received.present_type(), source.present_type());
862 ASSERT_TRUE(received.has_on_time_finish());
863 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
864 ASSERT_TRUE(received.has_gpu_composition());
865 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
866 ASSERT_TRUE(received.has_jank_type());
867 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000868}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700869
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000870void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
871 ASSERT_TRUE(received.has_cookie());
872 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700873}
874
875TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
876 auto tracingSession = getTracingSessionForTest();
877 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700878
879 tracingSession->StartBlocking();
880 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700881
882 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800883 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700884 mFrameTimeline->setSfPresent(26, presentFence1);
885 presentFence1->signalForTest(31);
886
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000887 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000888 auto protoExpectedDisplayFrameStart =
889 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
890 kSurfaceFlingerPid);
891 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
892 auto protoActualDisplayFrameStart =
893 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
894 kSurfaceFlingerPid,
895 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
896 FrameTimelineEvent::JANK_NONE);
897 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000898
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000899 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000900 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700901 tracingSession->StopBlocking();
902
903 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000904 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700905
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000906 // Packet - 0 : ExpectedDisplayFrameStart
907 const auto& packet0 = packets[0];
908 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000909 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000910 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700911
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000912 const auto& event0 = packet0.frame_timeline_event();
913 ASSERT_TRUE(event0.has_expected_display_frame_start());
914 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
915 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
916
917 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
918 const auto& packet1 = packets[1];
919 ASSERT_TRUE(packet1.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000920 EXPECT_EQ(packet1.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000921 ASSERT_TRUE(packet1.has_frame_timeline_event());
922
923 const auto& event1 = packet1.frame_timeline_event();
924 ASSERT_TRUE(event1.has_frame_end());
925 const auto& expectedDisplayFrameEnd = event1.frame_end();
926 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
927
928 // Packet - 2 : ActualDisplayFrameStart
929 const auto& packet2 = packets[2];
930 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000931 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000932 ASSERT_TRUE(packet2.has_frame_timeline_event());
933
934 const auto& event2 = packet2.frame_timeline_event();
935 ASSERT_TRUE(event2.has_actual_display_frame_start());
936 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
937 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
938
939 // Packet - 3 : FrameEnd (ActualDisplayFrame)
940 const auto& packet3 = packets[3];
941 ASSERT_TRUE(packet3.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000942 EXPECT_EQ(packet3.timestamp(), 26u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000943 ASSERT_TRUE(packet3.has_frame_timeline_event());
944
945 const auto& event3 = packet3.frame_timeline_event();
946 ASSERT_TRUE(event3.has_frame_end());
947 const auto& actualDisplayFrameEnd = event3.frame_end();
948 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700949}
950
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000951TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
952 auto tracingSession = getTracingSessionForTest();
953 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
954
955 tracingSession->StartBlocking();
956 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
957 // Flush the token so that it would expire
958 flushTokens(systemTime() + maxTokenRetentionTime);
959
960 // Set up the display frame
961 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
962 mFrameTimeline->setSfPresent(26, presentFence1);
963 presentFence1->signalForTest(31);
964
965 int64_t traceCookie = snoopCurrentTraceCookie();
966
967 auto protoActualDisplayFrameStart =
968 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
969 kSurfaceFlingerPid,
970 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
971 false, FrameTimelineEvent::JANK_UNKNOWN);
972 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
973
974 addEmptyDisplayFrame();
975 flushTrace();
976 tracingSession->StopBlocking();
977
978 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
979 // Only actual timeline packets should be in the trace
980 EXPECT_EQ(packets.size(), 2u);
981
982 // Packet - 0 : ActualDisplayFrameStart
983 const auto& packet0 = packets[0];
984 ASSERT_TRUE(packet0.has_timestamp());
985 EXPECT_EQ(packet0.timestamp(), 20u);
986 ASSERT_TRUE(packet0.has_frame_timeline_event());
987
988 const auto& event0 = packet0.frame_timeline_event();
989 ASSERT_TRUE(event0.has_actual_display_frame_start());
990 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
991 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
992
993 // Packet - 1 : FrameEnd (ActualDisplayFrame)
994 const auto& packet1 = packets[1];
995 ASSERT_TRUE(packet1.has_timestamp());
996 EXPECT_EQ(packet1.timestamp(), 26u);
997 ASSERT_TRUE(packet1.has_frame_timeline_event());
998
999 const auto& event1 = packet1.frame_timeline_event();
1000 ASSERT_TRUE(event1.has_frame_end());
1001 const auto& actualDisplayFrameEnd = event1.frame_end();
1002 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1003}
1004
Adithya Srinivasan01189672020-10-20 14:23:05 -07001005TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1006 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001007 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001008 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001009 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1010 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1011
1012 tracingSession->StartBlocking();
1013 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1014 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001015
1016 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001017 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
1018 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001019 auto surfaceFrame2 =
1020 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
1021 sUidOne, sLayerNameOne, sLayerNameOne);
1022 surfaceFrame1->setActualQueueTime(10);
1023 surfaceFrame1->setDropTime(15);
1024
1025 surfaceFrame2->setActualQueueTime(15);
1026 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001027
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001028 // First 2 cookies will be used by the DisplayFrame
1029 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1030
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001031 auto protoDroppedSurfaceFrameExpectedStart =
1032 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1033 displayFrameToken1, sPidOne, sLayerNameOne);
1034 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1035 auto protoDroppedSurfaceFrameActualStart =
1036 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1037 displayFrameToken1, sPidOne, sLayerNameOne,
1038 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1039 FrameTimelineEvent::JANK_NONE);
1040 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001041
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001042 auto protoPresentedSurfaceFrameExpectedStart =
1043 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1044 displayFrameToken1, sPidOne, sLayerNameOne);
1045 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1046 auto protoPresentedSurfaceFrameActualStart =
1047 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1048 displayFrameToken1, sPidOne, sLayerNameOne,
1049 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
1050 FrameTimelineEvent::JANK_NONE);
1051 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001052
1053 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001054 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001055 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1056 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001057 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001058 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001059 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001060 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001061
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001062 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001063 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001064 tracingSession->StopBlocking();
1065
1066 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001067 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1068 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001069
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001070 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001071 const auto& packet4 = packets[4];
1072 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001073 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001074 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001075
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001076 const auto& event4 = packet4.frame_timeline_event();
1077 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001078 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1079 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001080
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001081 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001082 const auto& packet5 = packets[5];
1083 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001084 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001085 ASSERT_TRUE(packet5.has_frame_timeline_event());
1086
1087 const auto& event5 = packet5.frame_timeline_event();
1088 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001089 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1090 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001091
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001092 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001093 const auto& packet6 = packets[6];
1094 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001095 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001096 ASSERT_TRUE(packet6.has_frame_timeline_event());
1097
1098 const auto& event6 = packet6.frame_timeline_event();
1099 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001100 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1101 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001102
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001103 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001104 const auto& packet7 = packets[7];
1105 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001106 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001107 ASSERT_TRUE(packet7.has_frame_timeline_event());
1108
1109 const auto& event7 = packet7.frame_timeline_event();
1110 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001111 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1112 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1113
1114 // Packet - 8 : ExpectedSurfaceFrameStart2
1115 const auto& packet8 = packets[8];
1116 ASSERT_TRUE(packet8.has_timestamp());
1117 EXPECT_EQ(packet8.timestamp(), 10u);
1118 ASSERT_TRUE(packet8.has_frame_timeline_event());
1119
1120 const auto& event8 = packet8.frame_timeline_event();
1121 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1122 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1123 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1124
1125 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1126 const auto& packet9 = packets[9];
1127 ASSERT_TRUE(packet9.has_timestamp());
1128 EXPECT_EQ(packet9.timestamp(), 25u);
1129 ASSERT_TRUE(packet9.has_frame_timeline_event());
1130
1131 const auto& event9 = packet9.frame_timeline_event();
1132 ASSERT_TRUE(event9.has_frame_end());
1133 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1134 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1135
1136 // Packet - 10 : ActualSurfaceFrameStart2
1137 const auto& packet10 = packets[10];
1138 ASSERT_TRUE(packet10.has_timestamp());
1139 EXPECT_EQ(packet10.timestamp(), 10u);
1140 ASSERT_TRUE(packet10.has_frame_timeline_event());
1141
1142 const auto& event10 = packet10.frame_timeline_event();
1143 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1144 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1145 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1146
1147 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1148 const auto& packet11 = packets[11];
1149 ASSERT_TRUE(packet11.has_timestamp());
1150 EXPECT_EQ(packet11.timestamp(), 20u);
1151 ASSERT_TRUE(packet11.has_frame_timeline_event());
1152
1153 const auto& event11 = packet11.frame_timeline_event();
1154 ASSERT_TRUE(event11.has_frame_end());
1155 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1156 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1157}
1158
1159TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1160 auto tracingSession = getTracingSessionForTest();
1161 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1162
1163 tracingSession->StartBlocking();
1164 constexpr nsecs_t appStartTime =
1165 std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count();
1166 constexpr nsecs_t appEndTime =
1167 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count();
1168 constexpr nsecs_t appPresentTime =
1169 std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
1170 int64_t surfaceFrameToken =
1171 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1172
1173 // Flush the token so that it would expire
1174 flushTokens(systemTime() + maxTokenRetentionTime);
1175 auto surfaceFrame1 =
1176 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
1177 sPidOne, sUidOne, sLayerNameOne,
1178 sLayerNameOne);
1179 surfaceFrame1->setActualQueueTime(appEndTime);
1180 surfaceFrame1->setAcquireFenceTime(appEndTime);
1181
1182 constexpr nsecs_t sfStartTime =
1183 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count();
1184 constexpr nsecs_t sfEndTime =
1185 std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
1186 constexpr nsecs_t sfPresentTime =
1187 std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
1188 int64_t displayFrameToken =
1189 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1190
1191 // First 2 cookies will be used by the DisplayFrame
1192 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1193
1194 auto protoActualSurfaceFrameStart =
1195 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1196 displayFrameToken, sPidOne, sLayerNameOne,
1197 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
1198 false, FrameTimelineEvent::JANK_UNKNOWN);
1199 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1200
1201 // Set up the display frame
1202 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1203 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1204 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1205 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1206 presentFence1->signalForTest(sfPresentTime);
1207
1208 addEmptyDisplayFrame();
1209 flushTrace();
1210 tracingSession->StopBlocking();
1211
1212 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1213 // Display Frame 4 packets + SurfaceFrame 2 packets
1214 ASSERT_EQ(packets.size(), 6u);
1215
1216 // Packet - 4 : ActualSurfaceFrameStart
1217 const auto& packet4 = packets[4];
1218 ASSERT_TRUE(packet4.has_timestamp());
1219 EXPECT_EQ(packet4.timestamp(),
1220 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1221 ASSERT_TRUE(packet4.has_frame_timeline_event());
1222
1223 const auto& event4 = packet4.frame_timeline_event();
1224 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1225 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1226 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1227
1228 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1229 const auto& packet5 = packets[5];
1230 ASSERT_TRUE(packet5.has_timestamp());
1231 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1232 ASSERT_TRUE(packet5.has_frame_timeline_event());
1233
1234 const auto& event5 = packet5.frame_timeline_event();
1235 ASSERT_TRUE(event5.has_frame_end());
1236 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001237 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001238}
1239
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001240// Tests for Jank classification
1241TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001242 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001243 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001244 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1245 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
1246 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
1247 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001248 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
1249 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001250 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001251 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1252 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1253 mFrameTimeline->setSfPresent(26, presentFence1);
1254 auto displayFrame = getDisplayFrame(0);
1255 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1256 presentFence1->signalForTest(29);
1257
1258 // Fences haven't been flushed yet, so it should be 0
1259 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1260 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1261
1262 addEmptyDisplayFrame();
1263 displayFrame = getDisplayFrame(0);
1264
1265 // Fences have flushed, so the present timestamps should be updated
1266 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1267 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1268 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1269 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1270 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1271}
1272
1273TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001274 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001275 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1276 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1277 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001278 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001279 mFrameTimeline->setSfPresent(26, presentFence1);
1280 auto displayFrame = getDisplayFrame(0);
1281 presentFence1->signalForTest(30);
1282
1283 // Fences for the first frame haven't been flushed yet, so it should be 0
1284 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1285
1286 // Trigger a flush by finalizing the next DisplayFrame
1287 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001288 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001289 mFrameTimeline->setSfPresent(56, presentFence2);
1290 displayFrame = getDisplayFrame(0);
1291
1292 // Fences for the first frame have flushed, so the present timestamps should be updated
1293 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1294 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1295 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1296 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1297
1298 // Fences for the second frame haven't been flushed yet, so it should be 0
1299 auto displayFrame2 = getDisplayFrame(1);
1300 presentFence2->signalForTest(65);
1301 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001302 addEmptyDisplayFrame();
1303 displayFrame2 = getDisplayFrame(1);
1304
1305 // Fences for the second frame have flushed, so the present timestamps should be updated
1306 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1307 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1308 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1309 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1310}
1311
1312TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001313 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001314 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1315 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1316 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001317 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001318 mFrameTimeline->setSfPresent(26, presentFence1);
1319 auto displayFrame = getDisplayFrame(0);
1320 presentFence1->signalForTest(50);
1321
1322 // Fences for the first frame haven't been flushed yet, so it should be 0
1323 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1324
1325 // Trigger a flush by finalizing the next DisplayFrame
1326 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001327 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001328 mFrameTimeline->setSfPresent(56, presentFence2);
1329 displayFrame = getDisplayFrame(0);
1330
1331 // Fences for the first frame have flushed, so the present timestamps should be updated
1332 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1333 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1334 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1335 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1336
1337 // Fences for the second frame haven't been flushed yet, so it should be 0
1338 auto displayFrame2 = getDisplayFrame(1);
1339 presentFence2->signalForTest(75);
1340 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1341
1342 addEmptyDisplayFrame();
1343 displayFrame2 = getDisplayFrame(1);
1344
1345 // Fences for the second frame have flushed, so the present timestamps should be updated
1346 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1347 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1348 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1349 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1350}
1351
1352TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001353 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1354 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001355 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001356
1357 mFrameTimeline->setSfPresent(22, presentFence1);
1358 auto displayFrame = getDisplayFrame(0);
1359 presentFence1->signalForTest(28);
1360
1361 // Fences haven't been flushed yet, so it should be 0
1362 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1363
1364 addEmptyDisplayFrame();
1365 displayFrame = getDisplayFrame(0);
1366
1367 // Fences have flushed, so the present timestamps should be updated
1368 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1369 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1370 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1371 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1372}
1373
1374TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001375 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1376 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001377 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001378 mFrameTimeline->setSfPresent(36, presentFence1);
1379 auto displayFrame = getDisplayFrame(0);
1380 presentFence1->signalForTest(52);
1381
1382 // Fences haven't been flushed yet, so it should be 0
1383 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1384
1385 addEmptyDisplayFrame();
1386 displayFrame = getDisplayFrame(0);
1387
1388 // Fences have flushed, so the present timestamps should be updated
1389 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1390 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1391 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1392 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1393}
1394
1395TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001396 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001397 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1398 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1399 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1400 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1401 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1402 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001403 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1404 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001405 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001406 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001407 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1408 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1409 mFrameTimeline->setSfPresent(26, presentFence1);
1410 auto displayFrame1 = getDisplayFrame(0);
1411 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1412 presentFence1->signalForTest(30);
1413
1414 // Fences for the first frame haven't been flushed yet, so it should be 0
1415 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1416 auto actuals1 = presentedSurfaceFrame1.getActuals();
1417 EXPECT_EQ(actuals1.presentTime, 0);
1418
1419 // Trigger a flush by finalizing the next DisplayFrame
1420 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1421 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001422 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1423 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001424 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001425 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001426 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1427 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1428 mFrameTimeline->setSfPresent(56, presentFence2);
1429 auto displayFrame2 = getDisplayFrame(1);
1430 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1431
1432 // Fences for the first frame have flushed, so the present timestamps should be updated
1433 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1434 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1435 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1436 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1437
1438 actuals1 = presentedSurfaceFrame1.getActuals();
1439 EXPECT_EQ(actuals1.presentTime, 30);
1440 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1441 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1442 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1443
1444 // Fences for the second frame haven't been flushed yet, so it should be 0
1445 presentFence2->signalForTest(65);
1446 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1447 auto actuals2 = presentedSurfaceFrame2.getActuals();
1448 EXPECT_EQ(actuals2.presentTime, 0);
1449
Alec Mouri363faf02021-01-29 16:34:55 -08001450 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1451
1452 EXPECT_CALL(*mTimeStats,
1453 incrementJankyFrames(
1454 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1455 sLayerNameOne, JankType::PredictionError, 0, 5,
1456 0}));
1457
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001458 addEmptyDisplayFrame();
1459
1460 // Fences for the second frame have flushed, so the present timestamps should be updated
1461 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1462 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1463 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1464 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1465
1466 actuals2 = presentedSurfaceFrame2.getActuals();
1467 EXPECT_EQ(actuals2.presentTime, 65);
1468 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1469 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1470 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1471}
1472
1473TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001474 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001475 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1476 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1477 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1478 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1479 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1480 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001481 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1482 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001483 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001484 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001485 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1486 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1487 mFrameTimeline->setSfPresent(26, presentFence1);
1488 auto displayFrame1 = getDisplayFrame(0);
1489 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1490 presentFence1->signalForTest(50);
1491
1492 // Fences for the first frame haven't been flushed yet, so it should be 0
1493 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1494 auto actuals1 = presentedSurfaceFrame1.getActuals();
1495 EXPECT_EQ(actuals1.presentTime, 0);
1496
1497 // Trigger a flush by finalizing the next DisplayFrame
1498 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1499 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001500 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1501 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001502 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001503 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001504 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1505 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1506 mFrameTimeline->setSfPresent(56, presentFence2);
1507 auto displayFrame2 = getDisplayFrame(1);
1508 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1509
1510 // Fences for the first frame have flushed, so the present timestamps should be updated
1511 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1512 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1513 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1514 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1515
1516 actuals1 = presentedSurfaceFrame1.getActuals();
1517 EXPECT_EQ(actuals1.presentTime, 50);
1518 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1519 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1520 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1521
1522 // Fences for the second frame haven't been flushed yet, so it should be 0
1523 presentFence2->signalForTest(86);
1524 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1525 auto actuals2 = presentedSurfaceFrame2.getActuals();
1526 EXPECT_EQ(actuals2.presentTime, 0);
1527
Alec Mouri363faf02021-01-29 16:34:55 -08001528 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1529
1530 EXPECT_CALL(*mTimeStats,
1531 incrementJankyFrames(
1532 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1533 sLayerNameOne, JankType::PredictionError, 0, 5,
1534 0}));
1535
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001536 addEmptyDisplayFrame();
1537
1538 // Fences for the second frame have flushed, so the present timestamps should be updated
1539 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1540 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1541 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1542 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1543
1544 actuals2 = presentedSurfaceFrame2.getActuals();
1545 EXPECT_EQ(actuals2.presentTime, 86);
1546 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1547 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1548 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1549}
1550
1551TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001552 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001553
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001554 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1555 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1556 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1557 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001558 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1559 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001560 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001561 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001562 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1563 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1564 mFrameTimeline->setSfPresent(46, presentFence1);
1565 auto displayFrame1 = getDisplayFrame(0);
1566 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1567 presentFence1->signalForTest(50);
1568
1569 // Fences for the first frame haven't been flushed yet, so it should be 0
1570 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1571 auto actuals1 = presentedSurfaceFrame1.getActuals();
1572 EXPECT_EQ(actuals1.presentTime, 0);
1573
1574 addEmptyDisplayFrame();
1575
1576 // Fences for the first frame have flushed, so the present timestamps should be updated
1577 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1578 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1579 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1580 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1581
1582 actuals1 = presentedSurfaceFrame1.getActuals();
1583 EXPECT_EQ(actuals1.presentTime, 50);
1584 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1585 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1586 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1587}
1588
1589TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1590 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1591 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1592 // jank to the SurfaceFrame.
1593
Alec Mouri363faf02021-01-29 16:34:55 -08001594 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001595 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1596 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 36, 40});
1597 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1598 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1599 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1600 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001601 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1602 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001603 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001604 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001605 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1606 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1607 mFrameTimeline->setSfPresent(36, presentFence1);
1608 auto displayFrame1 = getDisplayFrame(0);
1609 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1610 presentFence1->signalForTest(40);
1611
1612 // Fences for the first frame haven't been flushed yet, so it should be 0
1613 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1614 auto actuals1 = presentedSurfaceFrame1.getActuals();
1615 EXPECT_EQ(actuals1.presentTime, 0);
1616
1617 // Trigger a flush by finalizing the next DisplayFrame
1618 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1619 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001620 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1621 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001622 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001623 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001624 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1625 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1626 mFrameTimeline->setSfPresent(56, presentFence2);
1627 auto displayFrame2 = getDisplayFrame(1);
1628 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1629
1630 // Fences for the first frame have flushed, so the present timestamps should be updated
1631 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1632 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1633 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1634 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1635
1636 actuals1 = presentedSurfaceFrame1.getActuals();
1637 EXPECT_EQ(actuals1.presentTime, 40);
1638 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1639 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1640 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1641
1642 // Fences for the second frame haven't been flushed yet, so it should be 0
1643 presentFence2->signalForTest(60);
1644 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1645 auto actuals2 = presentedSurfaceFrame2.getActuals();
1646 EXPECT_EQ(actuals2.presentTime, 0);
1647
1648 addEmptyDisplayFrame();
1649
1650 // Fences for the second frame have flushed, so the present timestamps should be updated
1651 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1652 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1653 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1654 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1655
1656 actuals2 = presentedSurfaceFrame2.getActuals();
1657 EXPECT_EQ(actuals2.presentTime, 60);
1658 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1659 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1660 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1661}
1662
1663TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001664 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001665 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001666 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1667 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1668 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1669
1670 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 56, 60});
1671 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 116, 120});
1672 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001673 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1674 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001675 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001676 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001677 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1678 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1679 mFrameTimeline->setSfPresent(56, presentFence1);
1680 auto displayFrame1 = getDisplayFrame(0);
1681 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1682 presentFence1->signalForTest(60);
1683
1684 // Fences for the first frame haven't been flushed yet, so it should be 0
1685 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1686 auto actuals1 = presentedSurfaceFrame1.getActuals();
1687 EXPECT_EQ(actuals1.presentTime, 0);
1688
1689 // Trigger a flush by finalizing the next DisplayFrame
1690 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1691 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001692 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1693 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001694 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001695 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001696 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1697 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1698 mFrameTimeline->setSfPresent(116, presentFence2);
1699 auto displayFrame2 = getDisplayFrame(1);
1700 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1701 presentFence2->signalForTest(120);
1702
1703 // Fences for the first frame have flushed, so the present timestamps should be updated
1704 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1705 actuals1 = presentedSurfaceFrame1.getActuals();
1706 EXPECT_EQ(actuals1.endTime, 50);
1707 EXPECT_EQ(actuals1.presentTime, 60);
1708
1709 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1710 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1711 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1712
1713 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1714 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1715 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1716
1717 // Fences for the second frame haven't been flushed yet, so it should be 0
1718 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1719 auto actuals2 = presentedSurfaceFrame2.getActuals();
1720 EXPECT_EQ(actuals2.presentTime, 0);
1721
1722 addEmptyDisplayFrame();
1723
1724 // Fences for the second frame have flushed, so the present timestamps should be updated
1725 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1726 actuals2 = presentedSurfaceFrame2.getActuals();
1727 EXPECT_EQ(actuals2.presentTime, 120);
1728
1729 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1730 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1731 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1732
1733 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1734 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1735 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1736 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1737}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001738} // namespace android::frametimeline