blob: a53655d6fa8c88f9f4be092a5ca590433f128dde [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;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080030using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070031using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070032using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000033using ProtoExpectedDisplayFrameStart =
34 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
35using ProtoExpectedSurfaceFrameStart =
36 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
37using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
38using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
39using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070040using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
41using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Alec Mouri9a29e672020-09-14 12:39:14 -070042
43MATCHER_P(HasBit, bit, "") {
44 return (arg & bit) != 0;
45}
Adithya Srinivasanf279e042020-08-17 14:56:27 -070046
47namespace android::frametimeline {
48
49class FrameTimelineTest : public testing::Test {
50public:
51 FrameTimelineTest() {
52 const ::testing::TestInfo* const test_info =
53 ::testing::UnitTest::GetInstance()->current_test_info();
54 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
55 }
56
57 ~FrameTimelineTest() {
58 const ::testing::TestInfo* const test_info =
59 ::testing::UnitTest::GetInstance()->current_test_info();
60 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
61 }
62
Adithya Srinivasan01189672020-10-20 14:23:05 -070063 static void SetUpTestSuite() {
64 // Need to initialize tracing in process for testing, and only once per test suite.
65 perfetto::TracingInitArgs args;
66 args.backends = perfetto::kInProcessBackend;
67 perfetto::Tracing::Initialize(args);
68 }
69
Adithya Srinivasanf279e042020-08-17 14:56:27 -070070 void SetUp() override {
Alec Mouri9a29e672020-09-14 12:39:14 -070071 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000072 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080073 kTestThresholds);
Adithya Srinivasan01189672020-10-20 14:23:05 -070074 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070075 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000076 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070077 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070078 maxTokenRetentionTime = mTokenManager->kMaxRetentionTime;
79 }
80
Adithya Srinivasan01189672020-10-20 14:23:05 -070081 // Each tracing session can be used for a single block of Start -> Stop.
82 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
83 perfetto::TraceConfig cfg;
84 cfg.set_duration_ms(500);
85 cfg.add_buffers()->set_size_kb(1024);
86 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
87 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
88
89 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
90 tracingSession->Setup(cfg);
91 return tracingSession;
92 }
93
94 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
95 perfetto::TracingSession* tracingSession) {
96 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
97 perfetto::protos::Trace trace;
98 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
99
100 std::vector<perfetto::protos::TracePacket> packets;
101 for (const auto& packet : trace.packet()) {
102 if (!packet.has_frame_timeline_event()) {
103 continue;
104 }
105 packets.emplace_back(packet);
106 }
107 return packets;
108 }
109
110 void addEmptyDisplayFrame() {
111 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
112 mFrameTimeline->setSfPresent(2500, presentFence1);
113 }
114
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700115 void flushTokens(nsecs_t flushTime) {
116 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
117 mTokenManager->flushTokens(flushTime);
118 }
119
120 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
121 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800122 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
123 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700124 }
125
126 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
127 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
128 return mFrameTimeline->mDisplayFrames[idx];
129 }
130
131 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
132 return a.startTime == b.startTime && a.endTime == b.endTime &&
133 a.presentTime == b.presentTime;
134 }
135
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000136 const std::map<int64_t, TokenManagerPrediction>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700137 return mTokenManager->mPredictions;
138 }
139
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000140 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700141 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
142 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
143 }
144
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000145 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
146
147 void flushTrace() {
148 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
149 FrameTimelineDataSource::Trace(
150 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
151 }
152
Alec Mouri9a29e672020-09-14 12:39:14 -0700153 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700154 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
155 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000156 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700157 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700158 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700159 nsecs_t maxTokenRetentionTime;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000160 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800161 static constexpr nsecs_t kPresentThreshold =
162 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
163 static constexpr nsecs_t kDeadlineThreshold =
164 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
165 static constexpr nsecs_t kStartThreshold =
166 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
167 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
168 kDeadlineThreshold,
169 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700170};
171
Alec Mouri9a29e672020-09-14 12:39:14 -0700172static const std::string sLayerNameOne = "layer1";
173static const std::string sLayerNameTwo = "layer2";
174static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700175static constexpr pid_t sPidOne = 10;
176static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000177static constexpr int32_t sInputEventId = 5;
Alec Mouri9a29e672020-09-14 12:39:14 -0700178
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700179TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
180 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000181 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700182 flushTokens(systemTime() + maxTokenRetentionTime);
183 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
184 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
185
186 // token1 should have expired
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000187 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700188 EXPECT_EQ(predictions.has_value(), false);
189
190 predictions = mTokenManager->getPredictionsForToken(token2);
191 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
192}
193
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700194TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000195 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800196 sLayerNameOne, sLayerNameOne);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000197 auto surfaceFrame2 = mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800198 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700199 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
200 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
201}
202
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700203TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000204 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800205 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700206 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
207}
208
209TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
210 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
211 flushTokens(systemTime() + maxTokenRetentionTime);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000212 auto surfaceFrame =
213 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
214 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700215
216 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
217}
218
219TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
220 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000221 auto surfaceFrame =
222 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
223 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700224
225 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
226 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
227}
228
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000229TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
230 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
231 constexpr int32_t inputEventId = 1;
232 auto surfaceFrame =
233 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
234 sLayerNameOne, sLayerNameOne);
235
236 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
237}
238
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700239TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800240 // Global increment
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700241 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
242 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
243
244 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
245 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000246 auto surfaceFrame1 =
247 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
248 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700249
250 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800251 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800252 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
253 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700254 mFrameTimeline->setSfPresent(25, presentFence1);
255 presentFence1->signalForTest(30);
256
257 // Trigger a flush by calling setSfPresent for the next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800258 mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700259 mFrameTimeline->setSfPresent(55, presentFence2);
260
261 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
262 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
263 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
264}
265
266TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800267 // Layer specific increment
Alec Mouri7d436ec2021-01-27 20:40:50 -0800268 EXPECT_CALL(*mTimeStats,
269 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_))
270 .Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700271 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
272 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
273 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
274 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
275 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 60});
Alec Mouri9a29e672020-09-14 12:39:14 -0700276 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000277 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
278 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700279 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000280 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
281 sUidOne, sLayerNameTwo, sLayerNameTwo);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800282 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800283 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
284 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
285 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
286 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700287 mFrameTimeline->setSfPresent(26, presentFence1);
288 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800289 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
290 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700291 presentFence1->signalForTest(42);
292
293 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800294 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700295 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
296 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
297
298 // Trigger a flush by finalizing the next DisplayFrame
299 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri9a29e672020-09-14 12:39:14 -0700300 auto surfaceFrame3 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000301 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
302 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800303 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800304 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Dropped);
305 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700306 mFrameTimeline->setSfPresent(56, presentFence2);
307 displayFrame = getDisplayFrame(0);
308
309 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800310 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700311 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
312 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100313 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
314 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700315}
316
317TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
318 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
319 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800320 // Layer specific increment
Alec Mouri7d436ec2021-01-27 20:40:50 -0800321 EXPECT_CALL(*mTimeStats,
322 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800323 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700324 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700325 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},
332 sPidOne, sUidOne, sLayerNameOne,
333 sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800334 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800335 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
336 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700337 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
338 presentFence->signalForTest(32 + frameTimeFactor);
339 frameTimeFactor += 30;
340 }
341 auto displayFrame0 = getDisplayFrame(0);
342
343 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800344 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700345
346 // Add one more display frame
347 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
348 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
349 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
350 int64_t sfToken = mTokenManager->generateTokenForPredictions(
351 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700352 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000353 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
354 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800355 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800356 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
357 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700358 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
359 presentFence->signalForTest(32 + frameTimeFactor);
360 displayFrame0 = getDisplayFrame(0);
361
362 // The window should have slided by 1 now and the previous 0th display frame
363 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800364 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700365}
366
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700367TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000368 auto surfaceFrame =
369 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
370 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700371 surfaceFrame->setActualQueueTime(123);
372 surfaceFrame->setAcquireFenceTime(456);
373 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
374}
375
376TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000377 auto surfaceFrame =
378 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
379 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700380 surfaceFrame->setActualQueueTime(456);
381 surfaceFrame->setAcquireFenceTime(123);
382 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
383}
384
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700385TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
386 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
387 presentFence->signalForTest(2);
388
389 // Size shouldn't exceed maxDisplayFrames - 64
390 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700391 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000392 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
393 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700394 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800395 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800396 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
397 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700398 mFrameTimeline->setSfPresent(27, presentFence);
399 }
400 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
401
402 // Increase the size to 256
403 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000404 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700405
406 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700407 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000408 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
409 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700410 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800411 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800412 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
413 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700414 mFrameTimeline->setSfPresent(27, presentFence);
415 }
416 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
417
418 // Shrink the size to 128
419 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000420 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700421
422 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700423 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000424 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
425 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700426 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800427 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800428 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
429 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700430 mFrameTimeline->setSfPresent(27, presentFence);
431 }
432 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
433}
Alec Mouri9a29e672020-09-14 12:39:14 -0700434
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800435// Tests related to TimeStats
Alec Mouri9a29e672020-09-14 12:39:14 -0700436TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
437 EXPECT_CALL(*mTimeStats,
Alec Mouri7d436ec2021-01-27 20:40:50 -0800438 incrementJankyFrames(testing::_, testing::_, sUidOne, sLayerNameOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800439 HasBit(JankType::SurfaceFlingerCpuDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700440 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
441 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
442 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
443 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
444 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
445 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
446 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
447 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
448 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
449 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000450 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
451 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700452 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800453 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri7d436ec2021-01-27 20:40:50 -0800454 Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800455 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
456 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700457 presentFence1->signalForTest(
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100458 std::chrono::duration_cast<std::chrono::nanoseconds>(70ms).count());
Alec Mouri9a29e672020-09-14 12:39:14 -0700459
460 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(59ms).count(),
461 presentFence1);
462}
463
464TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
465 EXPECT_CALL(*mTimeStats,
Alec Mouri7d436ec2021-01-27 20:40:50 -0800466 incrementJankyFrames(testing::_, testing::_, sUidOne, sLayerNameOne,
467 HasBit(JankType::DisplayHAL)));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800468
Alec Mouri9a29e672020-09-14 12:39:14 -0700469 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
470 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
471 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
472 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
473 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
474 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
475 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
476 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
477 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
478 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000479 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
480 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700481 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800482 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri7d436ec2021-01-27 20:40:50 -0800483 Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800484 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
485 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700486 presentFence1->signalForTest(
487 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800488 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700489 presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800490 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700491}
492
493TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
494 EXPECT_CALL(*mTimeStats,
Alec Mouri7d436ec2021-01-27 20:40:50 -0800495 incrementJankyFrames(testing::_, testing::_, sUidOne, sLayerNameOne,
Jorim Jaggi5814ab82020-12-03 20:45:58 +0100496 HasBit(JankType::AppDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700497 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
498 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
499 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
500 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
501 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
502 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800503 {std::chrono::duration_cast<std::chrono::nanoseconds>(82ms).count(),
504 std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
505 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700506 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000507 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
508 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700509 surfaceFrame1->setAcquireFenceTime(
510 std::chrono::duration_cast<std::chrono::nanoseconds>(45ms).count());
511 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800512 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri7d436ec2021-01-27 20:40:50 -0800513 Fps::fromPeriodNsecs(11));
Alec Mouri9a29e672020-09-14 12:39:14 -0700514
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800515 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
516 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700517 presentFence1->signalForTest(
518 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800519 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700520 presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100521
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800522 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700523}
524
Adithya Srinivasan01189672020-10-20 14:23:05 -0700525/*
526 * Tracing Tests
527 *
528 * Trace packets are flushed all the way only when the next packet is traced.
529 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
530 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
531 * will have additional empty frames created for this reason.
532 */
533TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
534 auto tracingSession = getTracingSessionForTest();
535 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
536 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
537
538 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
539 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000540 auto surfaceFrame1 =
541 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
542 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700543
544 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800545 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800546 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
547 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700548 mFrameTimeline->setSfPresent(25, presentFence1);
549 presentFence1->signalForTest(30);
550
551 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
552 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800553 mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700554 mFrameTimeline->setSfPresent(55, presentFence2);
555
556 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000557 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700558}
559
560TEST_F(FrameTimelineTest, tracing_sanityTest) {
561 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800562 // Layer specific increment
Alec Mouri7d436ec2021-01-27 20:40:50 -0800563 EXPECT_CALL(*mTimeStats,
564 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700565 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
566 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
567
568 tracingSession->StartBlocking();
569 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
570 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000571 auto surfaceFrame1 =
572 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
573 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700574
575 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800576 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800577 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
578 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700579 mFrameTimeline->setSfPresent(25, presentFence1);
580 presentFence1->signalForTest(30);
581
582 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
583 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800584 mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700585 mFrameTimeline->setSfPresent(55, presentFence2);
586 presentFence2->signalForTest(55);
587
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000588 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700589 tracingSession->StopBlocking();
590
591 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000592 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000593 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700594}
595
596TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
597 auto tracingSession = getTracingSessionForTest();
598 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
599 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
600
601 tracingSession->StartBlocking();
602 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
603
604 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800605 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700606 mFrameTimeline->setSfPresent(25, presentFence1);
607 presentFence1->signalForTest(30);
608
609 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
610 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800611 mFrameTimeline->setSfWakeUp(token1, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700612 mFrameTimeline->setSfPresent(55, presentFence2);
613 presentFence2->signalForTest(60);
614
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000615 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700616 tracingSession->StopBlocking();
617
618 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000619 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700620}
621
622TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
623 auto tracingSession = getTracingSessionForTest();
624 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
625 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
626
627 tracingSession->StartBlocking();
628 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
629 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000630 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800631 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700632
633 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800634 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800635 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
636 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700637 mFrameTimeline->setSfPresent(25, presentFence1);
638 presentFence1->signalForTest(30);
639
640 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
641 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800642 mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700643 mFrameTimeline->setSfPresent(55, presentFence2);
644 presentFence2->signalForTest(60);
645
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000646 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700647 tracingSession->StopBlocking();
648
649 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000650 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
651 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000652 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700653}
654
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000655void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
656 const ProtoExpectedDisplayFrameStart& source) {
657 ASSERT_TRUE(received.has_cookie());
658 EXPECT_EQ(received.cookie(), source.cookie());
659
Adithya Srinivasan01189672020-10-20 14:23:05 -0700660 ASSERT_TRUE(received.has_token());
661 EXPECT_EQ(received.token(), source.token());
662
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000663 ASSERT_TRUE(received.has_pid());
664 EXPECT_EQ(received.pid(), source.pid());
665}
666
667void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
668 const ProtoActualDisplayFrameStart& source) {
669 ASSERT_TRUE(received.has_cookie());
670 EXPECT_EQ(received.cookie(), source.cookie());
671
672 ASSERT_TRUE(received.has_token());
673 EXPECT_EQ(received.token(), source.token());
674
675 ASSERT_TRUE(received.has_pid());
676 EXPECT_EQ(received.pid(), source.pid());
677
Adithya Srinivasan01189672020-10-20 14:23:05 -0700678 ASSERT_TRUE(received.has_present_type());
679 EXPECT_EQ(received.present_type(), source.present_type());
680 ASSERT_TRUE(received.has_on_time_finish());
681 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
682 ASSERT_TRUE(received.has_gpu_composition());
683 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
684 ASSERT_TRUE(received.has_jank_type());
685 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700686}
687
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000688void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
689 const ProtoExpectedSurfaceFrameStart& source) {
690 ASSERT_TRUE(received.has_cookie());
691 EXPECT_EQ(received.cookie(), source.cookie());
692
Adithya Srinivasan01189672020-10-20 14:23:05 -0700693 ASSERT_TRUE(received.has_token());
694 EXPECT_EQ(received.token(), source.token());
695
696 ASSERT_TRUE(received.has_display_frame_token());
697 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
698
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000699 ASSERT_TRUE(received.has_pid());
700 EXPECT_EQ(received.pid(), source.pid());
701
702 ASSERT_TRUE(received.has_layer_name());
703 EXPECT_EQ(received.layer_name(), source.layer_name());
704}
705
706void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
707 const ProtoActualSurfaceFrameStart& source) {
708 ASSERT_TRUE(received.has_cookie());
709 EXPECT_EQ(received.cookie(), source.cookie());
710
711 ASSERT_TRUE(received.has_token());
712 EXPECT_EQ(received.token(), source.token());
713
714 ASSERT_TRUE(received.has_display_frame_token());
715 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
716
717 ASSERT_TRUE(received.has_pid());
718 EXPECT_EQ(received.pid(), source.pid());
719
720 ASSERT_TRUE(received.has_layer_name());
721 EXPECT_EQ(received.layer_name(), source.layer_name());
722
Adithya Srinivasan01189672020-10-20 14:23:05 -0700723 ASSERT_TRUE(received.has_present_type());
724 EXPECT_EQ(received.present_type(), source.present_type());
725 ASSERT_TRUE(received.has_on_time_finish());
726 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
727 ASSERT_TRUE(received.has_gpu_composition());
728 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
729 ASSERT_TRUE(received.has_jank_type());
730 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000731}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700732
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000733void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
734 ASSERT_TRUE(received.has_cookie());
735 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700736}
737
738TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
739 auto tracingSession = getTracingSessionForTest();
740 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
741 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
742
743 tracingSession->StartBlocking();
744 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
745 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
746
747 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800748 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700749 mFrameTimeline->setSfPresent(26, presentFence1);
750 presentFence1->signalForTest(31);
751
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000752 int64_t traceCookie = snoopCurrentTraceCookie();
753 ProtoExpectedDisplayFrameStart protoExpectedDisplayFrameStart;
754 protoExpectedDisplayFrameStart.set_cookie(traceCookie + 1);
755 protoExpectedDisplayFrameStart.set_token(displayFrameToken1);
756 protoExpectedDisplayFrameStart.set_pid(kSurfaceFlingerPid);
757
758 ProtoFrameEnd protoExpectedDisplayFrameEnd;
759 protoExpectedDisplayFrameEnd.set_cookie(traceCookie + 1);
760
761 ProtoActualDisplayFrameStart protoActualDisplayFrameStart;
762 protoActualDisplayFrameStart.set_cookie(traceCookie + 2);
763 protoActualDisplayFrameStart.set_token(displayFrameToken1);
764 protoActualDisplayFrameStart.set_pid(kSurfaceFlingerPid);
765 protoActualDisplayFrameStart.set_present_type(
766 ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
767 protoActualDisplayFrameStart.set_on_time_finish(true);
768 protoActualDisplayFrameStart.set_gpu_composition(false);
769 protoActualDisplayFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
770
771 ProtoFrameEnd protoActualDisplayFrameEnd;
772 protoActualDisplayFrameEnd.set_cookie(traceCookie + 2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700773
774 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
775 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800776 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700777 mFrameTimeline->setSfPresent(55, presentFence2);
778 presentFence2->signalForTest(55);
779
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000780 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700781 tracingSession->StopBlocking();
782
783 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000784 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700785
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000786 // Packet - 0 : ExpectedDisplayFrameStart
787 const auto& packet0 = packets[0];
788 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000789 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000790 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700791
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000792 const auto& event0 = packet0.frame_timeline_event();
793 ASSERT_TRUE(event0.has_expected_display_frame_start());
794 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
795 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
796
797 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
798 const auto& packet1 = packets[1];
799 ASSERT_TRUE(packet1.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000800 EXPECT_EQ(packet1.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000801 ASSERT_TRUE(packet1.has_frame_timeline_event());
802
803 const auto& event1 = packet1.frame_timeline_event();
804 ASSERT_TRUE(event1.has_frame_end());
805 const auto& expectedDisplayFrameEnd = event1.frame_end();
806 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
807
808 // Packet - 2 : ActualDisplayFrameStart
809 const auto& packet2 = packets[2];
810 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000811 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000812 ASSERT_TRUE(packet2.has_frame_timeline_event());
813
814 const auto& event2 = packet2.frame_timeline_event();
815 ASSERT_TRUE(event2.has_actual_display_frame_start());
816 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
817 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
818
819 // Packet - 3 : FrameEnd (ActualDisplayFrame)
820 const auto& packet3 = packets[3];
821 ASSERT_TRUE(packet3.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000822 EXPECT_EQ(packet3.timestamp(), 26u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000823 ASSERT_TRUE(packet3.has_frame_timeline_event());
824
825 const auto& event3 = packet3.frame_timeline_event();
826 ASSERT_TRUE(event3.has_frame_end());
827 const auto& actualDisplayFrameEnd = event3.frame_end();
828 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700829}
830
831TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
832 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800833 // Layer specific increment
Alec Mouri7d436ec2021-01-27 20:40:50 -0800834 EXPECT_CALL(*mTimeStats,
835 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700836 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
837 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
838
839 tracingSession->StartBlocking();
840 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
841 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
842 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
843
844 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000845 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
846 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700847 surfaceFrame1->setActualStartTime(0);
848 surfaceFrame1->setActualQueueTime(15);
849 surfaceFrame1->setAcquireFenceTime(20);
850
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000851 // First 2 cookies will be used by the DisplayFrame
852 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
853
854 ProtoExpectedSurfaceFrameStart protoExpectedSurfaceFrameStart;
855 protoExpectedSurfaceFrameStart.set_cookie(traceCookie + 1);
856 protoExpectedSurfaceFrameStart.set_token(surfaceFrameToken);
857 protoExpectedSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
858 protoExpectedSurfaceFrameStart.set_pid(sPidOne);
859 protoExpectedSurfaceFrameStart.set_layer_name(sLayerNameOne);
860
861 ProtoFrameEnd protoExpectedSurfaceFrameEnd;
862 protoExpectedSurfaceFrameEnd.set_cookie(traceCookie + 1);
863
864 ProtoActualSurfaceFrameStart protoActualSurfaceFrameStart;
865 protoActualSurfaceFrameStart.set_cookie(traceCookie + 2);
866 protoActualSurfaceFrameStart.set_token(surfaceFrameToken);
867 protoActualSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
868 protoActualSurfaceFrameStart.set_pid(sPidOne);
869 protoActualSurfaceFrameStart.set_layer_name(sLayerNameOne);
870 protoActualSurfaceFrameStart.set_present_type(
871 ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
872 protoActualSurfaceFrameStart.set_on_time_finish(true);
873 protoActualSurfaceFrameStart.set_gpu_composition(false);
874 protoActualSurfaceFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
875
876 ProtoFrameEnd protoActualSurfaceFrameEnd;
877 protoActualSurfaceFrameEnd.set_cookie(traceCookie + 2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700878
879 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800880 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800881 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
882 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700883 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800884 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700885
886 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
887 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800888 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700889 mFrameTimeline->setSfPresent(55, presentFence2);
890 presentFence2->signalForTest(55);
891
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000892 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700893 tracingSession->StopBlocking();
894
895 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000896 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700897
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000898 // Packet - 4 : ExpectedSurfaceFrameStart
899 const auto& packet4 = packets[4];
900 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000901 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000902 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700903
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000904 const auto& event4 = packet4.frame_timeline_event();
905 ASSERT_TRUE(event4.has_expected_surface_frame_start());
906 const auto& expectedSurfaceFrameStart = event4.expected_surface_frame_start();
907 validateTraceEvent(expectedSurfaceFrameStart, protoExpectedSurfaceFrameStart);
908
909 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame)
910 const auto& packet5 = packets[5];
911 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000912 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000913 ASSERT_TRUE(packet5.has_frame_timeline_event());
914
915 const auto& event5 = packet5.frame_timeline_event();
916 ASSERT_TRUE(event5.has_frame_end());
917 const auto& expectedSurfaceFrameEnd = event5.frame_end();
918 validateTraceEvent(expectedSurfaceFrameEnd, protoExpectedSurfaceFrameEnd);
919
920 // Packet - 6 : ActualSurfaceFrameStart
921 const auto& packet6 = packets[6];
922 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000923 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000924 ASSERT_TRUE(packet6.has_frame_timeline_event());
925
926 const auto& event6 = packet6.frame_timeline_event();
927 ASSERT_TRUE(event6.has_actual_surface_frame_start());
928 const auto& actualSurfaceFrameStart = event6.actual_surface_frame_start();
929 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
930
931 // Packet - 7 : FrameEnd (ActualSurfaceFrame)
932 const auto& packet7 = packets[7];
933 ASSERT_TRUE(packet7.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000934 EXPECT_EQ(packet7.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000935 ASSERT_TRUE(packet7.has_frame_timeline_event());
936
937 const auto& event7 = packet7.frame_timeline_event();
938 ASSERT_TRUE(event7.has_frame_end());
939 const auto& actualSurfaceFrameEnd = event7.frame_end();
940 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700941}
942
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800943// Tests for Jank classification
944TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800945 // Layer specific increment
Alec Mouri7d436ec2021-01-27 20:40:50 -0800946 EXPECT_CALL(*mTimeStats,
947 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800948 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
949 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
950 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
951 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000952 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
953 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800954 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800955 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
956 mFrameTimeline->addSurfaceFrame(surfaceFrame);
957 mFrameTimeline->setSfPresent(26, presentFence1);
958 auto displayFrame = getDisplayFrame(0);
959 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
960 presentFence1->signalForTest(29);
961
962 // Fences haven't been flushed yet, so it should be 0
963 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
964 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
965
966 addEmptyDisplayFrame();
967 displayFrame = getDisplayFrame(0);
968
969 // Fences have flushed, so the present timestamps should be updated
970 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
971 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
972 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
973 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
974 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
975}
976
977TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800978 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
979 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
980 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800981 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800982 mFrameTimeline->setSfPresent(26, presentFence1);
983 auto displayFrame = getDisplayFrame(0);
984 presentFence1->signalForTest(30);
985
986 // Fences for the first frame haven't been flushed yet, so it should be 0
987 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
988
989 // Trigger a flush by finalizing the next DisplayFrame
990 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800991 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800992 mFrameTimeline->setSfPresent(56, presentFence2);
993 displayFrame = getDisplayFrame(0);
994
995 // Fences for the first frame have flushed, so the present timestamps should be updated
996 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
997 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
998 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
999 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1000
1001 // Fences for the second frame haven't been flushed yet, so it should be 0
1002 auto displayFrame2 = getDisplayFrame(1);
1003 presentFence2->signalForTest(65);
1004 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1005
1006 addEmptyDisplayFrame();
1007 displayFrame2 = getDisplayFrame(1);
1008
1009 // Fences for the second frame have flushed, so the present timestamps should be updated
1010 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1011 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1012 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1013 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1014}
1015
1016TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001017 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1018 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1019 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001020 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001021 mFrameTimeline->setSfPresent(26, presentFence1);
1022 auto displayFrame = getDisplayFrame(0);
1023 presentFence1->signalForTest(50);
1024
1025 // Fences for the first frame haven't been flushed yet, so it should be 0
1026 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1027
1028 // Trigger a flush by finalizing the next DisplayFrame
1029 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001030 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001031 mFrameTimeline->setSfPresent(56, presentFence2);
1032 displayFrame = getDisplayFrame(0);
1033
1034 // Fences for the first frame have flushed, so the present timestamps should be updated
1035 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1036 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1037 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1038 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1039
1040 // Fences for the second frame haven't been flushed yet, so it should be 0
1041 auto displayFrame2 = getDisplayFrame(1);
1042 presentFence2->signalForTest(75);
1043 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1044
1045 addEmptyDisplayFrame();
1046 displayFrame2 = getDisplayFrame(1);
1047
1048 // Fences for the second frame have flushed, so the present timestamps should be updated
1049 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1050 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1051 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1052 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1053}
1054
1055TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001056 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1057 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001058 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001059
1060 mFrameTimeline->setSfPresent(22, presentFence1);
1061 auto displayFrame = getDisplayFrame(0);
1062 presentFence1->signalForTest(28);
1063
1064 // Fences haven't been flushed yet, so it should be 0
1065 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1066
1067 addEmptyDisplayFrame();
1068 displayFrame = getDisplayFrame(0);
1069
1070 // Fences have flushed, so the present timestamps should be updated
1071 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1072 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1073 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1074 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1075}
1076
1077TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001078 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1079 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001080 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001081 mFrameTimeline->setSfPresent(36, presentFence1);
1082 auto displayFrame = getDisplayFrame(0);
1083 presentFence1->signalForTest(52);
1084
1085 // Fences haven't been flushed yet, so it should be 0
1086 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1087
1088 addEmptyDisplayFrame();
1089 displayFrame = getDisplayFrame(0);
1090
1091 // Fences have flushed, so the present timestamps should be updated
1092 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1093 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1094 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1095 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1096}
1097
1098TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri7d436ec2021-01-27 20:40:50 -08001099 EXPECT_CALL(*mTimeStats,
1100 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_))
1101 .Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001102 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1103 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1104 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1105 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1106 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1107 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001108 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1109 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001110 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001111 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001112 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1113 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1114 mFrameTimeline->setSfPresent(26, presentFence1);
1115 auto displayFrame1 = getDisplayFrame(0);
1116 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1117 presentFence1->signalForTest(30);
1118
1119 // Fences for the first frame haven't been flushed yet, so it should be 0
1120 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1121 auto actuals1 = presentedSurfaceFrame1.getActuals();
1122 EXPECT_EQ(actuals1.presentTime, 0);
1123
1124 // Trigger a flush by finalizing the next DisplayFrame
1125 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1126 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001127 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1128 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001129 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001130 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001131 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1132 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1133 mFrameTimeline->setSfPresent(56, presentFence2);
1134 auto displayFrame2 = getDisplayFrame(1);
1135 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1136
1137 // Fences for the first frame have flushed, so the present timestamps should be updated
1138 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1139 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1140 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1141 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1142
1143 actuals1 = presentedSurfaceFrame1.getActuals();
1144 EXPECT_EQ(actuals1.presentTime, 30);
1145 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1146 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1147 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1148
1149 // Fences for the second frame haven't been flushed yet, so it should be 0
1150 presentFence2->signalForTest(65);
1151 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1152 auto actuals2 = presentedSurfaceFrame2.getActuals();
1153 EXPECT_EQ(actuals2.presentTime, 0);
1154
1155 addEmptyDisplayFrame();
1156
1157 // Fences for the second frame have flushed, so the present timestamps should be updated
1158 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1159 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1160 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1161 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1162
1163 actuals2 = presentedSurfaceFrame2.getActuals();
1164 EXPECT_EQ(actuals2.presentTime, 65);
1165 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1166 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1167 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1168}
1169
1170TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri7d436ec2021-01-27 20:40:50 -08001171 EXPECT_CALL(*mTimeStats,
1172 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_))
1173 .Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001174 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1175 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1176 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1177 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1178 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1179 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001180 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1181 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001182 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001183 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001184 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1185 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1186 mFrameTimeline->setSfPresent(26, presentFence1);
1187 auto displayFrame1 = getDisplayFrame(0);
1188 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1189 presentFence1->signalForTest(50);
1190
1191 // Fences for the first frame haven't been flushed yet, so it should be 0
1192 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1193 auto actuals1 = presentedSurfaceFrame1.getActuals();
1194 EXPECT_EQ(actuals1.presentTime, 0);
1195
1196 // Trigger a flush by finalizing the next DisplayFrame
1197 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1198 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001199 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1200 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001201 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001202 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001203 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1204 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1205 mFrameTimeline->setSfPresent(56, presentFence2);
1206 auto displayFrame2 = getDisplayFrame(1);
1207 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1208
1209 // Fences for the first frame have flushed, so the present timestamps should be updated
1210 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1211 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1212 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1213 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1214
1215 actuals1 = presentedSurfaceFrame1.getActuals();
1216 EXPECT_EQ(actuals1.presentTime, 50);
1217 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1218 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1219 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1220
1221 // Fences for the second frame haven't been flushed yet, so it should be 0
1222 presentFence2->signalForTest(86);
1223 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1224 auto actuals2 = presentedSurfaceFrame2.getActuals();
1225 EXPECT_EQ(actuals2.presentTime, 0);
1226
1227 addEmptyDisplayFrame();
1228
1229 // Fences for the second frame have flushed, so the present timestamps should be updated
1230 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1231 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1232 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1233 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1234
1235 actuals2 = presentedSurfaceFrame2.getActuals();
1236 EXPECT_EQ(actuals2.presentTime, 86);
1237 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1238 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1239 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1240}
1241
1242TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri7d436ec2021-01-27 20:40:50 -08001243 EXPECT_CALL(*mTimeStats,
1244 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_));
1245
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001246 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1247 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1248 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1249 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001250 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1251 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001252 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001253 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001254 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1255 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1256 mFrameTimeline->setSfPresent(46, presentFence1);
1257 auto displayFrame1 = getDisplayFrame(0);
1258 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1259 presentFence1->signalForTest(50);
1260
1261 // Fences for the first frame haven't been flushed yet, so it should be 0
1262 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1263 auto actuals1 = presentedSurfaceFrame1.getActuals();
1264 EXPECT_EQ(actuals1.presentTime, 0);
1265
1266 addEmptyDisplayFrame();
1267
1268 // Fences for the first frame have flushed, so the present timestamps should be updated
1269 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1270 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1271 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1272 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1273
1274 actuals1 = presentedSurfaceFrame1.getActuals();
1275 EXPECT_EQ(actuals1.presentTime, 50);
1276 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1277 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1278 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1279}
1280
1281TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1282 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1283 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1284 // jank to the SurfaceFrame.
1285
Alec Mouri7d436ec2021-01-27 20:40:50 -08001286 EXPECT_CALL(*mTimeStats,
1287 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_))
1288 .Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001289 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1290 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 36, 40});
1291 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1292 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1293 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1294 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001295 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1296 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001297 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001298 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001299 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1300 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1301 mFrameTimeline->setSfPresent(36, presentFence1);
1302 auto displayFrame1 = getDisplayFrame(0);
1303 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1304 presentFence1->signalForTest(40);
1305
1306 // Fences for the first frame haven't been flushed yet, so it should be 0
1307 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1308 auto actuals1 = presentedSurfaceFrame1.getActuals();
1309 EXPECT_EQ(actuals1.presentTime, 0);
1310
1311 // Trigger a flush by finalizing the next DisplayFrame
1312 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1313 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001314 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1315 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001316 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001317 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001318 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1319 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1320 mFrameTimeline->setSfPresent(56, presentFence2);
1321 auto displayFrame2 = getDisplayFrame(1);
1322 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1323
1324 // Fences for the first frame have flushed, so the present timestamps should be updated
1325 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1326 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1327 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1328 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1329
1330 actuals1 = presentedSurfaceFrame1.getActuals();
1331 EXPECT_EQ(actuals1.presentTime, 40);
1332 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1333 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1334 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1335
1336 // Fences for the second frame haven't been flushed yet, so it should be 0
1337 presentFence2->signalForTest(60);
1338 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1339 auto actuals2 = presentedSurfaceFrame2.getActuals();
1340 EXPECT_EQ(actuals2.presentTime, 0);
1341
1342 addEmptyDisplayFrame();
1343
1344 // Fences for the second frame have flushed, so the present timestamps should be updated
1345 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1346 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1347 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1348 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1349
1350 actuals2 = presentedSurfaceFrame2.getActuals();
1351 EXPECT_EQ(actuals2.presentTime, 60);
1352 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1353 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1354 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1355}
1356
1357TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001358 // Layer specific increment
Alec Mouri7d436ec2021-01-27 20:40:50 -08001359 EXPECT_CALL(*mTimeStats,
1360 incrementJankyFrames(testing::_, testing::_, testing::_, testing::_, testing::_))
1361 .Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001362 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1363 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1364 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1365
1366 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 56, 60});
1367 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 116, 120});
1368 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001369 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1370 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001371 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001372 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001373 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1374 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1375 mFrameTimeline->setSfPresent(56, presentFence1);
1376 auto displayFrame1 = getDisplayFrame(0);
1377 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1378 presentFence1->signalForTest(60);
1379
1380 // Fences for the first frame haven't been flushed yet, so it should be 0
1381 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1382 auto actuals1 = presentedSurfaceFrame1.getActuals();
1383 EXPECT_EQ(actuals1.presentTime, 0);
1384
1385 // Trigger a flush by finalizing the next DisplayFrame
1386 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1387 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001388 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1389 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001390 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001391 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001392 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1393 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1394 mFrameTimeline->setSfPresent(116, presentFence2);
1395 auto displayFrame2 = getDisplayFrame(1);
1396 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1397 presentFence2->signalForTest(120);
1398
1399 // Fences for the first frame have flushed, so the present timestamps should be updated
1400 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1401 actuals1 = presentedSurfaceFrame1.getActuals();
1402 EXPECT_EQ(actuals1.endTime, 50);
1403 EXPECT_EQ(actuals1.presentTime, 60);
1404
1405 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1406 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1407 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1408
1409 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1410 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1411 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1412
1413 // Fences for the second frame haven't been flushed yet, so it should be 0
1414 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1415 auto actuals2 = presentedSurfaceFrame2.getActuals();
1416 EXPECT_EQ(actuals2.presentTime, 0);
1417
1418 addEmptyDisplayFrame();
1419
1420 // Fences for the second frame have flushed, so the present timestamps should be updated
1421 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1422 actuals2 = presentedSurfaceFrame2.getActuals();
1423 EXPECT_EQ(actuals2.presentTime, 120);
1424
1425 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1426 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1427 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1428
1429 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1430 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1431 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1432 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1433}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001434} // namespace android::frametimeline