blob: 6e9f09bdaa841216b53dd7627710b2eab2ddb7f5 [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
241 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700242 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
243 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
244
245 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
246 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000247 auto surfaceFrame1 =
248 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
249 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700250
251 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800252 mFrameTimeline->setSfWakeUp(token1, 20, 11);
253 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
254 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700255 mFrameTimeline->setSfPresent(25, presentFence1);
256 presentFence1->signalForTest(30);
257
258 // Trigger a flush by calling setSfPresent for the next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800259 mFrameTimeline->setSfWakeUp(token2, 50, 11);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700260 mFrameTimeline->setSfPresent(55, presentFence2);
261
262 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
263 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
264 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
265}
266
267TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800268 // Global increment
269 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
270 // Layer specific increment
271 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700272 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
273 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
274 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
275 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
276 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 60});
Alec Mouri9a29e672020-09-14 12:39:14 -0700277 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000278 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
279 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700280 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000281 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
282 sUidOne, sLayerNameTwo, sLayerNameTwo);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800283 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
284 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
285 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
286 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
287 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700288 mFrameTimeline->setSfPresent(26, presentFence1);
289 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800290 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
291 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700292 presentFence1->signalForTest(42);
293
294 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800295 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700296 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
297 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
298
299 // Trigger a flush by finalizing the next DisplayFrame
300 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri9a29e672020-09-14 12:39:14 -0700301 auto surfaceFrame3 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000302 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
303 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800304 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
305 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Dropped);
306 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700307 mFrameTimeline->setSfPresent(56, presentFence2);
308 displayFrame = getDisplayFrame(0);
309
310 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800311 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700312 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
313 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100314 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
315 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700316}
317
318TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
319 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
320 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800321 // Global increment
322 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_))
323 .Times(static_cast<int32_t>(*maxDisplayFrames));
324 // Layer specific increment
325 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_))
326 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700327 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700328 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
329 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
330 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
331 int64_t sfToken = mTokenManager->generateTokenForPredictions(
332 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700333 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000334 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
335 sPidOne, sUidOne, sLayerNameOne,
336 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800337 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, 11);
338 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
339 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700340 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
341 presentFence->signalForTest(32 + frameTimeFactor);
342 frameTimeFactor += 30;
343 }
344 auto displayFrame0 = getDisplayFrame(0);
345
346 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800347 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700348
349 // Add one more display frame
350 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
351 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
352 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
353 int64_t sfToken = mTokenManager->generateTokenForPredictions(
354 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700355 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000356 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
357 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800358 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, 11);
359 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
360 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700361 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
362 presentFence->signalForTest(32 + frameTimeFactor);
363 displayFrame0 = getDisplayFrame(0);
364
365 // The window should have slided by 1 now and the previous 0th display frame
366 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800367 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700368}
369
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700370TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000371 auto surfaceFrame =
372 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
373 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700374 surfaceFrame->setActualQueueTime(123);
375 surfaceFrame->setAcquireFenceTime(456);
376 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
377}
378
379TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000380 auto surfaceFrame =
381 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
382 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700383 surfaceFrame->setActualQueueTime(456);
384 surfaceFrame->setAcquireFenceTime(123);
385 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
386}
387
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700388TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800389 // Global increment
390 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_))
391 .Times(static_cast<int32_t>(*maxDisplayFrames + 10));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700392 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
393 presentFence->signalForTest(2);
394
395 // Size shouldn't exceed maxDisplayFrames - 64
396 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700397 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000398 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
399 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700400 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800401 mFrameTimeline->setSfWakeUp(sfToken, 22, 11);
402 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
403 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700404 mFrameTimeline->setSfPresent(27, presentFence);
405 }
406 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
407
408 // Increase the size to 256
409 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000410 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800411 // Global increment
412 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_))
413 .Times(static_cast<int32_t>(*maxDisplayFrames + 10));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700414
415 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700416 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000417 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
418 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700419 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800420 mFrameTimeline->setSfWakeUp(sfToken, 22, 11);
421 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
422 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700423 mFrameTimeline->setSfPresent(27, presentFence);
424 }
425 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
426
427 // Shrink the size to 128
428 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000429 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800430 // Global increment
431 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_))
432 .Times(static_cast<int32_t>(*maxDisplayFrames + 10));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700433
434 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700435 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000436 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
437 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700438 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800439 mFrameTimeline->setSfWakeUp(sfToken, 22, 11);
440 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
441 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700442 mFrameTimeline->setSfPresent(27, presentFence);
443 }
444 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
445}
Alec Mouri9a29e672020-09-14 12:39:14 -0700446
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800447// Tests related to TimeStats
Alec Mouri9a29e672020-09-14 12:39:14 -0700448TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
449 EXPECT_CALL(*mTimeStats,
450 incrementJankyFrames(sUidOne, sLayerNameOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800451 HasBit(JankType::SurfaceFlingerCpuDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700452 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800453 incrementJankyFrames(HasBit(JankType::SurfaceFlingerCpuDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700454 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
455 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
456 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
457 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
458 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
459 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
460 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
461 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
462 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
463 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000464 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
465 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700466 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800467 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
468 11);
469 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
470 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700471 presentFence1->signalForTest(
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100472 std::chrono::duration_cast<std::chrono::nanoseconds>(70ms).count());
Alec Mouri9a29e672020-09-14 12:39:14 -0700473
474 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(59ms).count(),
475 presentFence1);
476}
477
478TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
479 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800480 incrementJankyFrames(sUidOne, sLayerNameOne, HasBit(JankType::DisplayHAL)));
481 EXPECT_CALL(*mTimeStats, incrementJankyFrames(HasBit(JankType::DisplayHAL)));
482
Alec Mouri9a29e672020-09-14 12:39:14 -0700483 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
484 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
485 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
486 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
487 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
488 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
489 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
490 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
491 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
492 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000493 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
494 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700495 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800496 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
497 30);
498 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
499 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700500 presentFence1->signalForTest(
501 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800502 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700503 presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800504 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700505}
506
507TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
508 EXPECT_CALL(*mTimeStats,
509 incrementJankyFrames(sUidOne, sLayerNameOne,
Jorim Jaggi5814ab82020-12-03 20:45:58 +0100510 HasBit(JankType::AppDeadlineMissed)));
511 EXPECT_CALL(*mTimeStats, incrementJankyFrames(HasBit(JankType::AppDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700512 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
513 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
514 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
515 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
516 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
517 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800518 {std::chrono::duration_cast<std::chrono::nanoseconds>(82ms).count(),
519 std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
520 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700521 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000522 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
523 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700524 surfaceFrame1->setAcquireFenceTime(
525 std::chrono::duration_cast<std::chrono::nanoseconds>(45ms).count());
526 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800527 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
528 11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700529
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800530 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
531 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700532 presentFence1->signalForTest(
533 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800534 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700535 presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100536
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800537 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700538}
539
Adithya Srinivasan01189672020-10-20 14:23:05 -0700540/*
541 * Tracing Tests
542 *
543 * Trace packets are flushed all the way only when the next packet is traced.
544 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
545 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
546 * will have additional empty frames created for this reason.
547 */
548TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
549 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800550 // Global increment
551 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700552 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
553 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
554
555 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
556 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000557 auto surfaceFrame1 =
558 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
559 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700560
561 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800562 mFrameTimeline->setSfWakeUp(token1, 20, 11);
563 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
564 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700565 mFrameTimeline->setSfPresent(25, presentFence1);
566 presentFence1->signalForTest(30);
567
568 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
569 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800570 mFrameTimeline->setSfWakeUp(token2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700571 mFrameTimeline->setSfPresent(55, presentFence2);
572
573 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000574 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700575}
576
577TEST_F(FrameTimelineTest, tracing_sanityTest) {
578 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800579 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000580 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800581 // Layer specific increment
582 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700583 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
584 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
585
586 tracingSession->StartBlocking();
587 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
588 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000589 auto surfaceFrame1 =
590 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
591 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700592
593 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800594 mFrameTimeline->setSfWakeUp(token2, 20, 11);
595 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
596 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700597 mFrameTimeline->setSfPresent(25, presentFence1);
598 presentFence1->signalForTest(30);
599
600 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
601 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800602 mFrameTimeline->setSfWakeUp(token2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700603 mFrameTimeline->setSfPresent(55, presentFence2);
604 presentFence2->signalForTest(55);
605
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000606 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700607 tracingSession->StopBlocking();
608
609 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000610 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000611 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700612}
613
614TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
615 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800616 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000617 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700618 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
619 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
620
621 tracingSession->StartBlocking();
622 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
623
624 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800625 mFrameTimeline->setSfWakeUp(-1, 20, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700626 mFrameTimeline->setSfPresent(25, presentFence1);
627 presentFence1->signalForTest(30);
628
629 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
630 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800631 mFrameTimeline->setSfWakeUp(token1, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700632 mFrameTimeline->setSfPresent(55, presentFence2);
633 presentFence2->signalForTest(60);
634
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000635 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700636 tracingSession->StopBlocking();
637
638 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000639 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700640}
641
642TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
643 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800644 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000645 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700646 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
647 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
648
649 tracingSession->StartBlocking();
650 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
651 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000652 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800653 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700654
655 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800656 mFrameTimeline->setSfWakeUp(token1, 20, 11);
657 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
658 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700659 mFrameTimeline->setSfPresent(25, presentFence1);
660 presentFence1->signalForTest(30);
661
662 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
663 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800664 mFrameTimeline->setSfWakeUp(token2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700665 mFrameTimeline->setSfPresent(55, presentFence2);
666 presentFence2->signalForTest(60);
667
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000668 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700669 tracingSession->StopBlocking();
670
671 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000672 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
673 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000674 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700675}
676
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000677void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
678 const ProtoExpectedDisplayFrameStart& source) {
679 ASSERT_TRUE(received.has_cookie());
680 EXPECT_EQ(received.cookie(), source.cookie());
681
Adithya Srinivasan01189672020-10-20 14:23:05 -0700682 ASSERT_TRUE(received.has_token());
683 EXPECT_EQ(received.token(), source.token());
684
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000685 ASSERT_TRUE(received.has_pid());
686 EXPECT_EQ(received.pid(), source.pid());
687}
688
689void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
690 const ProtoActualDisplayFrameStart& source) {
691 ASSERT_TRUE(received.has_cookie());
692 EXPECT_EQ(received.cookie(), source.cookie());
693
694 ASSERT_TRUE(received.has_token());
695 EXPECT_EQ(received.token(), source.token());
696
697 ASSERT_TRUE(received.has_pid());
698 EXPECT_EQ(received.pid(), source.pid());
699
Adithya Srinivasan01189672020-10-20 14:23:05 -0700700 ASSERT_TRUE(received.has_present_type());
701 EXPECT_EQ(received.present_type(), source.present_type());
702 ASSERT_TRUE(received.has_on_time_finish());
703 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
704 ASSERT_TRUE(received.has_gpu_composition());
705 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
706 ASSERT_TRUE(received.has_jank_type());
707 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700708}
709
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000710void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
711 const ProtoExpectedSurfaceFrameStart& source) {
712 ASSERT_TRUE(received.has_cookie());
713 EXPECT_EQ(received.cookie(), source.cookie());
714
Adithya Srinivasan01189672020-10-20 14:23:05 -0700715 ASSERT_TRUE(received.has_token());
716 EXPECT_EQ(received.token(), source.token());
717
718 ASSERT_TRUE(received.has_display_frame_token());
719 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
720
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000721 ASSERT_TRUE(received.has_pid());
722 EXPECT_EQ(received.pid(), source.pid());
723
724 ASSERT_TRUE(received.has_layer_name());
725 EXPECT_EQ(received.layer_name(), source.layer_name());
726}
727
728void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
729 const ProtoActualSurfaceFrameStart& source) {
730 ASSERT_TRUE(received.has_cookie());
731 EXPECT_EQ(received.cookie(), source.cookie());
732
733 ASSERT_TRUE(received.has_token());
734 EXPECT_EQ(received.token(), source.token());
735
736 ASSERT_TRUE(received.has_display_frame_token());
737 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
738
739 ASSERT_TRUE(received.has_pid());
740 EXPECT_EQ(received.pid(), source.pid());
741
742 ASSERT_TRUE(received.has_layer_name());
743 EXPECT_EQ(received.layer_name(), source.layer_name());
744
Adithya Srinivasan01189672020-10-20 14:23:05 -0700745 ASSERT_TRUE(received.has_present_type());
746 EXPECT_EQ(received.present_type(), source.present_type());
747 ASSERT_TRUE(received.has_on_time_finish());
748 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
749 ASSERT_TRUE(received.has_gpu_composition());
750 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
751 ASSERT_TRUE(received.has_jank_type());
752 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000753}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700754
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000755void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
756 ASSERT_TRUE(received.has_cookie());
757 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700758}
759
760TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
761 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800762 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000763 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700764 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
765 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
766
767 tracingSession->StartBlocking();
768 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
769 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
770
771 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800772 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700773 mFrameTimeline->setSfPresent(26, presentFence1);
774 presentFence1->signalForTest(31);
775
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000776 int64_t traceCookie = snoopCurrentTraceCookie();
777 ProtoExpectedDisplayFrameStart protoExpectedDisplayFrameStart;
778 protoExpectedDisplayFrameStart.set_cookie(traceCookie + 1);
779 protoExpectedDisplayFrameStart.set_token(displayFrameToken1);
780 protoExpectedDisplayFrameStart.set_pid(kSurfaceFlingerPid);
781
782 ProtoFrameEnd protoExpectedDisplayFrameEnd;
783 protoExpectedDisplayFrameEnd.set_cookie(traceCookie + 1);
784
785 ProtoActualDisplayFrameStart protoActualDisplayFrameStart;
786 protoActualDisplayFrameStart.set_cookie(traceCookie + 2);
787 protoActualDisplayFrameStart.set_token(displayFrameToken1);
788 protoActualDisplayFrameStart.set_pid(kSurfaceFlingerPid);
789 protoActualDisplayFrameStart.set_present_type(
790 ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
791 protoActualDisplayFrameStart.set_on_time_finish(true);
792 protoActualDisplayFrameStart.set_gpu_composition(false);
793 protoActualDisplayFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
794
795 ProtoFrameEnd protoActualDisplayFrameEnd;
796 protoActualDisplayFrameEnd.set_cookie(traceCookie + 2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700797
798 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
799 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800800 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700801 mFrameTimeline->setSfPresent(55, presentFence2);
802 presentFence2->signalForTest(55);
803
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000804 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700805 tracingSession->StopBlocking();
806
807 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000808 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700809
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000810 // Packet - 0 : ExpectedDisplayFrameStart
811 const auto& packet0 = packets[0];
812 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000813 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000814 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700815
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000816 const auto& event0 = packet0.frame_timeline_event();
817 ASSERT_TRUE(event0.has_expected_display_frame_start());
818 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
819 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
820
821 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
822 const auto& packet1 = packets[1];
823 ASSERT_TRUE(packet1.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000824 EXPECT_EQ(packet1.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000825 ASSERT_TRUE(packet1.has_frame_timeline_event());
826
827 const auto& event1 = packet1.frame_timeline_event();
828 ASSERT_TRUE(event1.has_frame_end());
829 const auto& expectedDisplayFrameEnd = event1.frame_end();
830 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
831
832 // Packet - 2 : ActualDisplayFrameStart
833 const auto& packet2 = packets[2];
834 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000835 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000836 ASSERT_TRUE(packet2.has_frame_timeline_event());
837
838 const auto& event2 = packet2.frame_timeline_event();
839 ASSERT_TRUE(event2.has_actual_display_frame_start());
840 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
841 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
842
843 // Packet - 3 : FrameEnd (ActualDisplayFrame)
844 const auto& packet3 = packets[3];
845 ASSERT_TRUE(packet3.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000846 EXPECT_EQ(packet3.timestamp(), 26u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000847 ASSERT_TRUE(packet3.has_frame_timeline_event());
848
849 const auto& event3 = packet3.frame_timeline_event();
850 ASSERT_TRUE(event3.has_frame_end());
851 const auto& actualDisplayFrameEnd = event3.frame_end();
852 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700853}
854
855TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
856 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800857 // Global increment
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000858 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800859 // Layer specific increment
860 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700861 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
862 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
863
864 tracingSession->StartBlocking();
865 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
866 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
867 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
868
869 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000870 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
871 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700872 surfaceFrame1->setActualStartTime(0);
873 surfaceFrame1->setActualQueueTime(15);
874 surfaceFrame1->setAcquireFenceTime(20);
875
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000876 // First 2 cookies will be used by the DisplayFrame
877 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
878
879 ProtoExpectedSurfaceFrameStart protoExpectedSurfaceFrameStart;
880 protoExpectedSurfaceFrameStart.set_cookie(traceCookie + 1);
881 protoExpectedSurfaceFrameStart.set_token(surfaceFrameToken);
882 protoExpectedSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
883 protoExpectedSurfaceFrameStart.set_pid(sPidOne);
884 protoExpectedSurfaceFrameStart.set_layer_name(sLayerNameOne);
885
886 ProtoFrameEnd protoExpectedSurfaceFrameEnd;
887 protoExpectedSurfaceFrameEnd.set_cookie(traceCookie + 1);
888
889 ProtoActualSurfaceFrameStart protoActualSurfaceFrameStart;
890 protoActualSurfaceFrameStart.set_cookie(traceCookie + 2);
891 protoActualSurfaceFrameStart.set_token(surfaceFrameToken);
892 protoActualSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
893 protoActualSurfaceFrameStart.set_pid(sPidOne);
894 protoActualSurfaceFrameStart.set_layer_name(sLayerNameOne);
895 protoActualSurfaceFrameStart.set_present_type(
896 ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
897 protoActualSurfaceFrameStart.set_on_time_finish(true);
898 protoActualSurfaceFrameStart.set_gpu_composition(false);
899 protoActualSurfaceFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
900
901 ProtoFrameEnd protoActualSurfaceFrameEnd;
902 protoActualSurfaceFrameEnd.set_cookie(traceCookie + 2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700903
904 // Set up the display frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800905 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, 11);
906 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
907 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700908 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800909 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700910
911 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
912 // next frame
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800913 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, 11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700914 mFrameTimeline->setSfPresent(55, presentFence2);
915 presentFence2->signalForTest(55);
916
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000917 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700918 tracingSession->StopBlocking();
919
920 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000921 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700922
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000923 // Packet - 4 : ExpectedSurfaceFrameStart
924 const auto& packet4 = packets[4];
925 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000926 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000927 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700928
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000929 const auto& event4 = packet4.frame_timeline_event();
930 ASSERT_TRUE(event4.has_expected_surface_frame_start());
931 const auto& expectedSurfaceFrameStart = event4.expected_surface_frame_start();
932 validateTraceEvent(expectedSurfaceFrameStart, protoExpectedSurfaceFrameStart);
933
934 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame)
935 const auto& packet5 = packets[5];
936 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000937 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000938 ASSERT_TRUE(packet5.has_frame_timeline_event());
939
940 const auto& event5 = packet5.frame_timeline_event();
941 ASSERT_TRUE(event5.has_frame_end());
942 const auto& expectedSurfaceFrameEnd = event5.frame_end();
943 validateTraceEvent(expectedSurfaceFrameEnd, protoExpectedSurfaceFrameEnd);
944
945 // Packet - 6 : ActualSurfaceFrameStart
946 const auto& packet6 = packets[6];
947 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000948 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000949 ASSERT_TRUE(packet6.has_frame_timeline_event());
950
951 const auto& event6 = packet6.frame_timeline_event();
952 ASSERT_TRUE(event6.has_actual_surface_frame_start());
953 const auto& actualSurfaceFrameStart = event6.actual_surface_frame_start();
954 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
955
956 // Packet - 7 : FrameEnd (ActualSurfaceFrame)
957 const auto& packet7 = packets[7];
958 ASSERT_TRUE(packet7.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000959 EXPECT_EQ(packet7.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000960 ASSERT_TRUE(packet7.has_frame_timeline_event());
961
962 const auto& event7 = packet7.frame_timeline_event();
963 ASSERT_TRUE(event7.has_frame_end());
964 const auto& actualSurfaceFrameEnd = event7.frame_end();
965 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700966}
967
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800968// Tests for Jank classification
969TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
970 // Global increment
971 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
972 // Layer specific increment
973 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_));
974 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
975 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
976 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
977 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000978 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
979 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800980 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
981 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
982 mFrameTimeline->addSurfaceFrame(surfaceFrame);
983 mFrameTimeline->setSfPresent(26, presentFence1);
984 auto displayFrame = getDisplayFrame(0);
985 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
986 presentFence1->signalForTest(29);
987
988 // Fences haven't been flushed yet, so it should be 0
989 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
990 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
991
992 addEmptyDisplayFrame();
993 displayFrame = getDisplayFrame(0);
994
995 // Fences have flushed, so the present timestamps should be updated
996 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
997 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
998 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
999 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1000 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1001}
1002
1003TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
1004 // Global increment
1005 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1006 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1007 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1008 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1009 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
1010 mFrameTimeline->setSfPresent(26, presentFence1);
1011 auto displayFrame = getDisplayFrame(0);
1012 presentFence1->signalForTest(30);
1013
1014 // Fences for the first frame haven't been flushed yet, so it should be 0
1015 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1016
1017 // Trigger a flush by finalizing the next DisplayFrame
1018 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1019 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
1020 mFrameTimeline->setSfPresent(56, presentFence2);
1021 displayFrame = getDisplayFrame(0);
1022
1023 // Fences for the first frame have flushed, so the present timestamps should be updated
1024 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1025 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1026 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1027 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1028
1029 // Fences for the second frame haven't been flushed yet, so it should be 0
1030 auto displayFrame2 = getDisplayFrame(1);
1031 presentFence2->signalForTest(65);
1032 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1033
1034 addEmptyDisplayFrame();
1035 displayFrame2 = getDisplayFrame(1);
1036
1037 // Fences for the second frame have flushed, so the present timestamps should be updated
1038 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1039 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1040 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1041 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1042}
1043
1044TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
1045 // Global increment
1046 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1047 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1048 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1049 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1050 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
1051 mFrameTimeline->setSfPresent(26, presentFence1);
1052 auto displayFrame = getDisplayFrame(0);
1053 presentFence1->signalForTest(50);
1054
1055 // Fences for the first frame haven't been flushed yet, so it should be 0
1056 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1057
1058 // Trigger a flush by finalizing the next DisplayFrame
1059 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1060 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
1061 mFrameTimeline->setSfPresent(56, presentFence2);
1062 displayFrame = getDisplayFrame(0);
1063
1064 // Fences for the first frame have flushed, so the present timestamps should be updated
1065 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1066 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1067 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1068 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1069
1070 // Fences for the second frame haven't been flushed yet, so it should be 0
1071 auto displayFrame2 = getDisplayFrame(1);
1072 presentFence2->signalForTest(75);
1073 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1074
1075 addEmptyDisplayFrame();
1076 displayFrame2 = getDisplayFrame(1);
1077
1078 // Fences for the second frame have flushed, so the present timestamps should be updated
1079 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1080 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1081 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1082 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1083}
1084
1085TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
1086 // Global increment
1087 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
1088 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1089 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
1090 mFrameTimeline->setSfWakeUp(sfToken1, 12, 11);
1091
1092 mFrameTimeline->setSfPresent(22, presentFence1);
1093 auto displayFrame = getDisplayFrame(0);
1094 presentFence1->signalForTest(28);
1095
1096 // Fences haven't been flushed yet, so it should be 0
1097 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1098
1099 addEmptyDisplayFrame();
1100 displayFrame = getDisplayFrame(0);
1101
1102 // Fences have flushed, so the present timestamps should be updated
1103 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1104 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1105 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1106 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1107}
1108
1109TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
1110 // Global increment
1111 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
1112 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1113 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1114 mFrameTimeline->setSfWakeUp(sfToken1, 12, 11);
1115 mFrameTimeline->setSfPresent(36, presentFence1);
1116 auto displayFrame = getDisplayFrame(0);
1117 presentFence1->signalForTest(52);
1118
1119 // Fences haven't been flushed yet, so it should be 0
1120 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1121
1122 addEmptyDisplayFrame();
1123 displayFrame = getDisplayFrame(0);
1124
1125 // Fences have flushed, so the present timestamps should be updated
1126 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1127 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1128 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1129 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1130}
1131
1132TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
1133 // Global increment
1134 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1135 // Layer specific increment
1136 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
1137 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1138 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1139 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1140 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1141 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1142 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001143 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1144 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001145 surfaceFrame1->setAcquireFenceTime(16);
1146 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
1147 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1148 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1149 mFrameTimeline->setSfPresent(26, presentFence1);
1150 auto displayFrame1 = getDisplayFrame(0);
1151 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1152 presentFence1->signalForTest(30);
1153
1154 // Fences for the first frame haven't been flushed yet, so it should be 0
1155 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1156 auto actuals1 = presentedSurfaceFrame1.getActuals();
1157 EXPECT_EQ(actuals1.presentTime, 0);
1158
1159 // Trigger a flush by finalizing the next DisplayFrame
1160 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1161 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001162 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1163 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001164 surfaceFrame2->setAcquireFenceTime(36);
1165 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
1166 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1167 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1168 mFrameTimeline->setSfPresent(56, presentFence2);
1169 auto displayFrame2 = getDisplayFrame(1);
1170 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1171
1172 // Fences for the first frame have flushed, so the present timestamps should be updated
1173 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1174 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1175 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1176 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1177
1178 actuals1 = presentedSurfaceFrame1.getActuals();
1179 EXPECT_EQ(actuals1.presentTime, 30);
1180 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1181 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1182 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1183
1184 // Fences for the second frame haven't been flushed yet, so it should be 0
1185 presentFence2->signalForTest(65);
1186 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1187 auto actuals2 = presentedSurfaceFrame2.getActuals();
1188 EXPECT_EQ(actuals2.presentTime, 0);
1189
1190 addEmptyDisplayFrame();
1191
1192 // Fences for the second frame have flushed, so the present timestamps should be updated
1193 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1194 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1195 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1196 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1197
1198 actuals2 = presentedSurfaceFrame2.getActuals();
1199 EXPECT_EQ(actuals2.presentTime, 65);
1200 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1201 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1202 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1203}
1204
1205TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
1206 // Global increment
1207 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1208 // Layer specific increment
1209 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
1210 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1211 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1212 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1213 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1214 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1215 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001216 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1217 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001218 surfaceFrame1->setAcquireFenceTime(16);
1219 mFrameTimeline->setSfWakeUp(sfToken1, 22, 11);
1220 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1221 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1222 mFrameTimeline->setSfPresent(26, presentFence1);
1223 auto displayFrame1 = getDisplayFrame(0);
1224 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1225 presentFence1->signalForTest(50);
1226
1227 // Fences for the first frame haven't been flushed yet, so it should be 0
1228 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1229 auto actuals1 = presentedSurfaceFrame1.getActuals();
1230 EXPECT_EQ(actuals1.presentTime, 0);
1231
1232 // Trigger a flush by finalizing the next DisplayFrame
1233 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1234 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001235 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1236 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001237 surfaceFrame2->setAcquireFenceTime(36);
1238 mFrameTimeline->setSfWakeUp(sfToken2, 52, 11);
1239 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1240 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1241 mFrameTimeline->setSfPresent(56, presentFence2);
1242 auto displayFrame2 = getDisplayFrame(1);
1243 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1244
1245 // Fences for the first frame have flushed, so the present timestamps should be updated
1246 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1247 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1248 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1249 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1250
1251 actuals1 = presentedSurfaceFrame1.getActuals();
1252 EXPECT_EQ(actuals1.presentTime, 50);
1253 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1254 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1255 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1256
1257 // Fences for the second frame haven't been flushed yet, so it should be 0
1258 presentFence2->signalForTest(86);
1259 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1260 auto actuals2 = presentedSurfaceFrame2.getActuals();
1261 EXPECT_EQ(actuals2.presentTime, 0);
1262
1263 addEmptyDisplayFrame();
1264
1265 // Fences for the second frame have flushed, so the present timestamps should be updated
1266 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1267 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1268 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1269 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1270
1271 actuals2 = presentedSurfaceFrame2.getActuals();
1272 EXPECT_EQ(actuals2.presentTime, 86);
1273 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1274 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1275 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1276}
1277
1278TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
1279 // Global increment
1280 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_));
1281 // Layer specific increment
1282 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_));
1283 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1284 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1285 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1286 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001287 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1288 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001289 surfaceFrame1->setAcquireFenceTime(40);
1290 mFrameTimeline->setSfWakeUp(sfToken1, 42, 11);
1291 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1292 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1293 mFrameTimeline->setSfPresent(46, presentFence1);
1294 auto displayFrame1 = getDisplayFrame(0);
1295 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1296 presentFence1->signalForTest(50);
1297
1298 // Fences for the first frame haven't been flushed yet, so it should be 0
1299 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1300 auto actuals1 = presentedSurfaceFrame1.getActuals();
1301 EXPECT_EQ(actuals1.presentTime, 0);
1302
1303 addEmptyDisplayFrame();
1304
1305 // Fences for the first frame have flushed, so the present timestamps should be updated
1306 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1307 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1308 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1309 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1310
1311 actuals1 = presentedSurfaceFrame1.getActuals();
1312 EXPECT_EQ(actuals1.presentTime, 50);
1313 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1314 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1315 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1316}
1317
1318TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1319 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1320 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1321 // jank to the SurfaceFrame.
1322
1323 // Global increment
1324 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1325 // Layer specific increment
1326 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
1327 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1328 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 36, 40});
1329 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1330 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1331 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1332 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001333 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1334 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001335 surfaceFrame1->setAcquireFenceTime(26);
1336 mFrameTimeline->setSfWakeUp(sfToken1, 32, 11);
1337 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1338 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1339 mFrameTimeline->setSfPresent(36, presentFence1);
1340 auto displayFrame1 = getDisplayFrame(0);
1341 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1342 presentFence1->signalForTest(40);
1343
1344 // Fences for the first frame haven't been flushed yet, so it should be 0
1345 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1346 auto actuals1 = presentedSurfaceFrame1.getActuals();
1347 EXPECT_EQ(actuals1.presentTime, 0);
1348
1349 // Trigger a flush by finalizing the next DisplayFrame
1350 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1351 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001352 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1353 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001354 surfaceFrame2->setAcquireFenceTime(40);
1355 mFrameTimeline->setSfWakeUp(sfToken2, 43, 11);
1356 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1357 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1358 mFrameTimeline->setSfPresent(56, presentFence2);
1359 auto displayFrame2 = getDisplayFrame(1);
1360 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1361
1362 // Fences for the first frame have flushed, so the present timestamps should be updated
1363 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1364 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1365 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1366 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1367
1368 actuals1 = presentedSurfaceFrame1.getActuals();
1369 EXPECT_EQ(actuals1.presentTime, 40);
1370 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1371 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1372 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1373
1374 // Fences for the second frame haven't been flushed yet, so it should be 0
1375 presentFence2->signalForTest(60);
1376 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1377 auto actuals2 = presentedSurfaceFrame2.getActuals();
1378 EXPECT_EQ(actuals2.presentTime, 0);
1379
1380 addEmptyDisplayFrame();
1381
1382 // Fences for the second frame have flushed, so the present timestamps should be updated
1383 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1384 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1385 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1386 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1387
1388 actuals2 = presentedSurfaceFrame2.getActuals();
1389 EXPECT_EQ(actuals2.presentTime, 60);
1390 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1391 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1392 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1393}
1394
1395TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
1396 // Global increment
1397 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)).Times(2);
1398 // Layer specific increment
1399 EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_, testing::_, testing::_)).Times(2);
1400 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1401 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1402 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1403
1404 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 56, 60});
1405 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 116, 120});
1406 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001407 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1408 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001409 surfaceFrame1->setAcquireFenceTime(50);
1410 mFrameTimeline->setSfWakeUp(sfToken1, 52, 30);
1411 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1412 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1413 mFrameTimeline->setSfPresent(56, presentFence1);
1414 auto displayFrame1 = getDisplayFrame(0);
1415 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1416 presentFence1->signalForTest(60);
1417
1418 // Fences for the first frame haven't been flushed yet, so it should be 0
1419 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1420 auto actuals1 = presentedSurfaceFrame1.getActuals();
1421 EXPECT_EQ(actuals1.presentTime, 0);
1422
1423 // Trigger a flush by finalizing the next DisplayFrame
1424 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1425 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001426 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1427 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001428 surfaceFrame2->setAcquireFenceTime(84);
1429 mFrameTimeline->setSfWakeUp(sfToken2, 112, 30);
1430 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1431 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1432 mFrameTimeline->setSfPresent(116, presentFence2);
1433 auto displayFrame2 = getDisplayFrame(1);
1434 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1435 presentFence2->signalForTest(120);
1436
1437 // Fences for the first frame have flushed, so the present timestamps should be updated
1438 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1439 actuals1 = presentedSurfaceFrame1.getActuals();
1440 EXPECT_EQ(actuals1.endTime, 50);
1441 EXPECT_EQ(actuals1.presentTime, 60);
1442
1443 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1444 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1445 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1446
1447 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1448 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1449 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1450
1451 // Fences for the second frame haven't been flushed yet, so it should be 0
1452 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1453 auto actuals2 = presentedSurfaceFrame2.getActuals();
1454 EXPECT_EQ(actuals2.presentTime, 0);
1455
1456 addEmptyDisplayFrame();
1457
1458 // Fences for the second frame have flushed, so the present timestamps should be updated
1459 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1460 actuals2 = presentedSurfaceFrame2.getActuals();
1461 EXPECT_EQ(actuals2.presentTime, 120);
1462
1463 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1464 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1465 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1466
1467 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1468 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1469 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1470 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1471}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001472} // namespace android::frametimeline