blob: 43b5afe9e2776eb160a76b822d7bc033a89f4bf4 [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
Alec Mouri9a29e672020-09-14 12:39:14 -070017#include "gmock/gmock-spec-builders.h"
18#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070019#undef LOG_TAG
20#define LOG_TAG "LibSurfaceFlingerUnittests"
21
22#include <FrameTimeline/FrameTimeline.h>
23#include <gtest/gtest.h>
24#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070025#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070026#include <cinttypes>
27
28using namespace std::chrono_literals;
Alec Mouri9a29e672020-09-14 12:39:14 -070029using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070030using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
31using ProtoDisplayFrame = perfetto::protos::FrameTimelineEvent_DisplayFrame;
32using ProtoSurfaceFrame = perfetto::protos::FrameTimelineEvent_SurfaceFrame;
33using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
34using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Alec Mouri9a29e672020-09-14 12:39:14 -070035
36MATCHER_P(HasBit, bit, "") {
37 return (arg & bit) != 0;
38}
Adithya Srinivasanf279e042020-08-17 14:56:27 -070039
40namespace android::frametimeline {
41
42class FrameTimelineTest : public testing::Test {
43public:
44 FrameTimelineTest() {
45 const ::testing::TestInfo* const test_info =
46 ::testing::UnitTest::GetInstance()->current_test_info();
47 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
48 }
49
50 ~FrameTimelineTest() {
51 const ::testing::TestInfo* const test_info =
52 ::testing::UnitTest::GetInstance()->current_test_info();
53 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
54 }
55
Adithya Srinivasan01189672020-10-20 14:23:05 -070056 static void SetUpTestSuite() {
57 // Need to initialize tracing in process for testing, and only once per test suite.
58 perfetto::TracingInitArgs args;
59 args.backends = perfetto::kInProcessBackend;
60 perfetto::Tracing::Initialize(args);
61 }
62
Adithya Srinivasanf279e042020-08-17 14:56:27 -070063 void SetUp() override {
Alec Mouri9a29e672020-09-14 12:39:14 -070064 mTimeStats = std::make_shared<mock::TimeStats>();
65 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats);
Adithya Srinivasan01189672020-10-20 14:23:05 -070066 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070067 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070068 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070069 maxTokenRetentionTime = mTokenManager->kMaxRetentionTime;
70 }
71
Adithya Srinivasan01189672020-10-20 14:23:05 -070072 // Each tracing session can be used for a single block of Start -> Stop.
73 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
74 perfetto::TraceConfig cfg;
75 cfg.set_duration_ms(500);
76 cfg.add_buffers()->set_size_kb(1024);
77 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
78 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
79
80 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
81 tracingSession->Setup(cfg);
82 return tracingSession;
83 }
84
85 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
86 perfetto::TracingSession* tracingSession) {
87 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
88 perfetto::protos::Trace trace;
89 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
90
91 std::vector<perfetto::protos::TracePacket> packets;
92 for (const auto& packet : trace.packet()) {
93 if (!packet.has_frame_timeline_event()) {
94 continue;
95 }
96 packets.emplace_back(packet);
97 }
98 return packets;
99 }
100
101 void addEmptyDisplayFrame() {
102 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
103 mFrameTimeline->setSfPresent(2500, presentFence1);
104 }
105
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700106 void flushTokens(nsecs_t flushTime) {
107 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
108 mTokenManager->flushTokens(flushTime);
109 }
110
111 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
112 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
113 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]->surfaceFrames[surfaceFrameIdx]);
114 }
115
116 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
117 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
118 return mFrameTimeline->mDisplayFrames[idx];
119 }
120
121 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
122 return a.startTime == b.startTime && a.endTime == b.endTime &&
123 a.presentTime == b.presentTime;
124 }
125
126 const std::unordered_map<int64_t, TimelineItem>& getPredictions() {
127 return mTokenManager->mPredictions;
128 }
129
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700130 uint32_t getNumberOfDisplayFrames() {
131 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
132 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
133 }
134
Alec Mouri9a29e672020-09-14 12:39:14 -0700135 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700136 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
137 impl::TokenManager* mTokenManager;
138 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700139 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700140 nsecs_t maxTokenRetentionTime;
141};
142
Alec Mouri9a29e672020-09-14 12:39:14 -0700143static const std::string sLayerNameOne = "layer1";
144static const std::string sLayerNameTwo = "layer2";
145static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700146static constexpr pid_t sPidOne = 10;
147static constexpr pid_t sPidTwo = 20;
Alec Mouri9a29e672020-09-14 12:39:14 -0700148
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700149TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
150 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
151 EXPECT_EQ(getPredictions().size(), 1);
152 flushTokens(systemTime() + maxTokenRetentionTime);
153 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
154 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
155
156 // token1 should have expired
157 EXPECT_EQ(getPredictions().size(), 1);
158 EXPECT_EQ(predictions.has_value(), false);
159
160 predictions = mTokenManager->getPredictionsForToken(token2);
161 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
162}
163
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700164TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
165 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
166 sLayerNameOne, std::nullopt);
167 auto surfaceFrame2 = mFrameTimeline->createSurfaceFrameForToken(sPidTwo, sUidOne, sLayerNameOne,
168 sLayerNameOne, std::nullopt);
169 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
170 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
171}
172
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700173TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700174 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
Alec Mouri9a29e672020-09-14 12:39:14 -0700175 sLayerNameOne, std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700176 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
177}
178
179TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
180 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
181 flushTokens(systemTime() + maxTokenRetentionTime);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700182 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
Alec Mouri9a29e672020-09-14 12:39:14 -0700183 sLayerNameOne, token1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700184
185 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
186}
187
188TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
189 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700190 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
Alec Mouri9a29e672020-09-14 12:39:14 -0700191 sLayerNameOne, token1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700192
193 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
194 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
195}
196
197TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
198 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
199 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
200
201 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
202 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700203 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
Alec Mouri9a29e672020-09-14 12:39:14 -0700204 sLayerNameOne, token1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700205
206 // Set up the display frame
207 mFrameTimeline->setSfWakeUp(token1, 20);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100208 mFrameTimeline->addSurfaceFrame(surfaceFrame1, SurfaceFrame::PresentState::Dropped);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700209 mFrameTimeline->setSfPresent(25, presentFence1);
210 presentFence1->signalForTest(30);
211
212 // Trigger a flush by calling setSfPresent for the next frame
213 mFrameTimeline->setSfWakeUp(token2, 50);
214 mFrameTimeline->setSfPresent(55, presentFence2);
215
216 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
217 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
218 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
219}
220
221TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
222 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
223 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
224 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
225 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
226 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 60});
Alec Mouri9a29e672020-09-14 12:39:14 -0700227 auto surfaceFrame1 =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700228 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
229 sLayerNameOne, surfaceFrameToken1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700230 auto surfaceFrame2 =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700231 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameTwo,
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100232 sLayerNameTwo, surfaceFrameToken2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700233 mFrameTimeline->setSfWakeUp(sfToken1, 22);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100234 mFrameTimeline->addSurfaceFrame(surfaceFrame1,
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700235 SurfaceFrame::PresentState::Presented);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100236 mFrameTimeline->addSurfaceFrame(surfaceFrame2,
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700237 SurfaceFrame::PresentState::Presented);
238 mFrameTimeline->setSfPresent(26, presentFence1);
239 auto displayFrame = getDisplayFrame(0);
240 SurfaceFrame& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
241 SurfaceFrame& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
242 presentFence1->signalForTest(42);
243
244 // Fences haven't been flushed yet, so it should be 0
245 EXPECT_EQ(displayFrame->surfaceFlingerActuals.presentTime, 0);
246 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
247 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
248
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100249 EXPECT_EQ(surfaceFrame1->getToken(), surfaceFrameToken1);
250 EXPECT_EQ(surfaceFrame2->getToken(), surfaceFrameToken2);
251
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700252 // Trigger a flush by finalizing the next DisplayFrame
253 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri9a29e672020-09-14 12:39:14 -0700254 auto surfaceFrame3 =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700255 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
256 sLayerNameOne, surfaceFrameToken2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700257 mFrameTimeline->setSfWakeUp(sfToken2, 52);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100258 mFrameTimeline->addSurfaceFrame(surfaceFrame3, SurfaceFrame::PresentState::Dropped);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700259 mFrameTimeline->setSfPresent(56, presentFence2);
260 displayFrame = getDisplayFrame(0);
261
262 // Fences have flushed, so the present timestamps should be updated
263 EXPECT_EQ(displayFrame->surfaceFlingerActuals.presentTime, 42);
264 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
265 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100266 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
267 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700268}
269
270TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
271 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
272 int frameTimeFactor = 0;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700273 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700274 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
275 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
276 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
277 int64_t sfToken = mTokenManager->generateTokenForPredictions(
278 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700279 auto surfaceFrame =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700280 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
281 sLayerNameOne, surfaceFrameToken);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700282 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100283 mFrameTimeline->addSurfaceFrame(surfaceFrame,
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700284 SurfaceFrame::PresentState::Presented);
285 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
286 presentFence->signalForTest(32 + frameTimeFactor);
287 frameTimeFactor += 30;
288 }
289 auto displayFrame0 = getDisplayFrame(0);
290
291 // The 0th Display Frame should have actuals 22, 27, 32
292 EXPECT_EQ(compareTimelineItems(displayFrame0->surfaceFlingerActuals, TimelineItem(22, 27, 32)),
293 true);
294
295 // Add one more display frame
296 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
297 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
298 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
299 int64_t sfToken = mTokenManager->generateTokenForPredictions(
300 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700301 auto surfaceFrame =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700302 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
303 sLayerNameOne, surfaceFrameToken);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700304 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100305 mFrameTimeline->addSurfaceFrame(surfaceFrame, SurfaceFrame::PresentState::Presented);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700306 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
307 presentFence->signalForTest(32 + frameTimeFactor);
308 displayFrame0 = getDisplayFrame(0);
309
310 // The window should have slided by 1 now and the previous 0th display frame
311 // should have been removed from the deque
312 EXPECT_EQ(compareTimelineItems(displayFrame0->surfaceFlingerActuals, TimelineItem(52, 57, 62)),
313 true);
314}
315
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700316TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
317 auto surfaceFrame =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700318 mFrameTimeline->createSurfaceFrameForToken(sPidOne, 0, "acquireFenceAfterQueue",
Alec Mouri9a29e672020-09-14 12:39:14 -0700319 "acquireFenceAfterQueue", std::nullopt);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700320 surfaceFrame->setActualQueueTime(123);
321 surfaceFrame->setAcquireFenceTime(456);
322 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
323}
324
325TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
326 auto surfaceFrame =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700327 mFrameTimeline->createSurfaceFrameForToken(sPidOne, 0, "acquireFenceAfterQueue",
Alec Mouri9a29e672020-09-14 12:39:14 -0700328 "acquireFenceAfterQueue", std::nullopt);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700329 surfaceFrame->setActualQueueTime(456);
330 surfaceFrame->setAcquireFenceTime(123);
331 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
332}
333
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700334TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
335 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
336 presentFence->signalForTest(2);
337
338 // Size shouldn't exceed maxDisplayFrames - 64
339 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700340 auto surfaceFrame =
341 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
342 sLayerNameOne, std::nullopt);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700343 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
344 mFrameTimeline->setSfWakeUp(sfToken, 22);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100345 mFrameTimeline->addSurfaceFrame(surfaceFrame,
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700346 SurfaceFrame::PresentState::Presented);
347 mFrameTimeline->setSfPresent(27, presentFence);
348 }
349 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
350
351 // Increase the size to 256
352 mFrameTimeline->setMaxDisplayFrames(256);
353 EXPECT_EQ(*maxDisplayFrames, 256);
354
355 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700356 auto surfaceFrame =
357 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
358 sLayerNameOne, std::nullopt);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700359 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
360 mFrameTimeline->setSfWakeUp(sfToken, 22);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100361 mFrameTimeline->addSurfaceFrame(surfaceFrame,
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700362 SurfaceFrame::PresentState::Presented);
363 mFrameTimeline->setSfPresent(27, presentFence);
364 }
365 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
366
367 // Shrink the size to 128
368 mFrameTimeline->setMaxDisplayFrames(128);
369 EXPECT_EQ(*maxDisplayFrames, 128);
370
371 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700372 auto surfaceFrame =
373 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
374 sLayerNameOne, std::nullopt);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700375 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
376 mFrameTimeline->setSfWakeUp(sfToken, 22);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100377 mFrameTimeline->addSurfaceFrame(surfaceFrame,
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700378 SurfaceFrame::PresentState::Presented);
379 mFrameTimeline->setSfPresent(27, presentFence);
380 }
381 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
382}
Alec Mouri9a29e672020-09-14 12:39:14 -0700383
384TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
385 EXPECT_CALL(*mTimeStats,
386 incrementJankyFrames(sUidOne, sLayerNameOne,
Jorim Jaggi5814ab82020-12-03 20:45:58 +0100387 HasBit(JankType::SurfaceFlingerDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700388 EXPECT_CALL(*mTimeStats,
Jorim Jaggi5814ab82020-12-03 20:45:58 +0100389 incrementJankyFrames(HasBit(JankType::SurfaceFlingerDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700390 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
391 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
392 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
393 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
394 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
395 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
396 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
397 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
398 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
399 auto surfaceFrame1 =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700400 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
401 sLayerNameOne, surfaceFrameToken1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700402 mFrameTimeline->setSfWakeUp(sfToken1,
403 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count());
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100404 mFrameTimeline->addSurfaceFrame(surfaceFrame1,
Alec Mouri9a29e672020-09-14 12:39:14 -0700405 SurfaceFrame::PresentState::Presented);
406 presentFence1->signalForTest(
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100407 std::chrono::duration_cast<std::chrono::nanoseconds>(70ms).count());
Alec Mouri9a29e672020-09-14 12:39:14 -0700408
409 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(59ms).count(),
410 presentFence1);
411}
412
413TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
414 EXPECT_CALL(*mTimeStats,
Jorim Jaggi5814ab82020-12-03 20:45:58 +0100415 incrementJankyFrames(sUidOne, sLayerNameOne, HasBit(JankType::Display)));
416 EXPECT_CALL(*mTimeStats, incrementJankyFrames(HasBit(JankType::Display)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700417 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
418 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
419 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
420 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
421 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
422 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
423 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
424 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
425 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
426 auto surfaceFrame1 =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700427 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
428 sLayerNameOne, surfaceFrameToken1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700429 mFrameTimeline->setSfWakeUp(sfToken1,
430 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count());
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100431 mFrameTimeline->addSurfaceFrame(surfaceFrame1,
Alec Mouri9a29e672020-09-14 12:39:14 -0700432 SurfaceFrame::PresentState::Presented);
433 presentFence1->signalForTest(
434 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
435 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(59ms).count(),
436 presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100437 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
438 EXPECT_TRUE((surfaceFrame1->getJankType().value() & JankType::Display) != 0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700439}
440
441TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
442 EXPECT_CALL(*mTimeStats,
443 incrementJankyFrames(sUidOne, sLayerNameOne,
Jorim Jaggi5814ab82020-12-03 20:45:58 +0100444 HasBit(JankType::AppDeadlineMissed)));
445 EXPECT_CALL(*mTimeStats, incrementJankyFrames(HasBit(JankType::AppDeadlineMissed)));
Alec Mouri9a29e672020-09-14 12:39:14 -0700446 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
447 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
448 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
449 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
450 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
451 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
452 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
453 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
454 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
455 auto surfaceFrame1 =
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700456 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
457 sLayerNameOne, surfaceFrameToken1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700458 surfaceFrame1->setAcquireFenceTime(
459 std::chrono::duration_cast<std::chrono::nanoseconds>(45ms).count());
460 mFrameTimeline->setSfWakeUp(sfToken1,
461 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count());
462
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100463 mFrameTimeline->addSurfaceFrame(surfaceFrame1,
Alec Mouri9a29e672020-09-14 12:39:14 -0700464 SurfaceFrame::PresentState::Presented);
465 presentFence1->signalForTest(
466 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
467 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
468 presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100469
470 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
471 EXPECT_TRUE((surfaceFrame1->getJankType().value() & JankType::AppDeadlineMissed) != 0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700472}
473
Adithya Srinivasan01189672020-10-20 14:23:05 -0700474/*
475 * Tracing Tests
476 *
477 * Trace packets are flushed all the way only when the next packet is traced.
478 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
479 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
480 * will have additional empty frames created for this reason.
481 */
482TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
483 auto tracingSession = getTracingSessionForTest();
484 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
485 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
486
487 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
488 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
489 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
490 sLayerNameOne, token1);
491
492 // Set up the display frame
493 mFrameTimeline->setSfWakeUp(token1, 20);
494 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame1), SurfaceFrame::PresentState::Dropped);
495 mFrameTimeline->setSfPresent(25, presentFence1);
496 presentFence1->signalForTest(30);
497
498 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
499 // next frame
500 mFrameTimeline->setSfWakeUp(token2, 50);
501 mFrameTimeline->setSfPresent(55, presentFence2);
502
503 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
504 EXPECT_EQ(packets.size(), 0);
505}
506
507TEST_F(FrameTimelineTest, tracing_sanityTest) {
508 auto tracingSession = getTracingSessionForTest();
509 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
510 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
511
512 tracingSession->StartBlocking();
513 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
514 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
515 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
516 sLayerNameOne, token1);
517
518 // Set up the display frame
519 mFrameTimeline->setSfWakeUp(token2, 20);
520 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame1),
521 SurfaceFrame::PresentState::Presented);
522 mFrameTimeline->setSfPresent(25, presentFence1);
523 presentFence1->signalForTest(30);
524
525 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
526 // next frame
527 mFrameTimeline->setSfWakeUp(token2, 50);
528 mFrameTimeline->setSfPresent(55, presentFence2);
529 presentFence2->signalForTest(55);
530
531 // The SurfaceFrame packet from the first frame is emitted, but not flushed yet. Emitting a new
532 // packet will flush it. To emit a new packet, we'll need to call flushPendingPresentFences()
533 // again, which is done by setSfPresent().
534 addEmptyDisplayFrame();
535 tracingSession->StopBlocking();
536
537 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
538 // Display Frame 1 has two packets - DisplayFrame and a SurfaceFrame.
539 // Display Frame 2 has one packet - DisplayFrame. However, this packet has been emitted but not
540 // flushed through traced, so this is not counted.
541 EXPECT_EQ(packets.size(), 2);
542}
543
544TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
545 auto tracingSession = getTracingSessionForTest();
546 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
547 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
548
549 tracingSession->StartBlocking();
550 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
551
552 // Set up the display frame
553 mFrameTimeline->setSfWakeUp(-1, 20);
554 mFrameTimeline->setSfPresent(25, presentFence1);
555 presentFence1->signalForTest(30);
556
557 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
558 // next frame
559 mFrameTimeline->setSfWakeUp(token1, 50);
560 mFrameTimeline->setSfPresent(55, presentFence2);
561 presentFence2->signalForTest(60);
562
563 addEmptyDisplayFrame();
564 tracingSession->StopBlocking();
565
566 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
567 // Display Frame 1 has no packets.
568 // Display Frame 2 has one packet - DisplayFrame. However, this packet has
569 // been emitted but not flushed through traced, so this is not counted.
570 EXPECT_EQ(packets.size(), 0);
571}
572
573TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
574 auto tracingSession = getTracingSessionForTest();
575 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
576 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
577
578 tracingSession->StartBlocking();
579 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
580 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
581 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
582 sLayerNameOne, std::nullopt);
583
584 // Set up the display frame
585 mFrameTimeline->setSfWakeUp(token1, 20);
586 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame1), SurfaceFrame::PresentState::Dropped);
587 mFrameTimeline->setSfPresent(25, presentFence1);
588 presentFence1->signalForTest(30);
589
590 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
591 // next frame
592 mFrameTimeline->setSfWakeUp(token2, 50);
593 mFrameTimeline->setSfPresent(55, presentFence2);
594 presentFence2->signalForTest(60);
595
596 addEmptyDisplayFrame();
597 tracingSession->StopBlocking();
598
599 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
600 // Display Frame 1 has one packet - DisplayFrame (SurfaceFrame shouldn't be traced since it has
601 // an invalid token).
602 // Display Frame 2 has one packet - DisplayFrame. However, this packet has
603 // been emitted but not flushed through traced, so this is not counted.
604 EXPECT_EQ(packets.size(), 1);
605}
606
607void validateDisplayFrameEvent(const ProtoDisplayFrame& received, const ProtoDisplayFrame& source) {
608 ASSERT_TRUE(received.has_token());
609 EXPECT_EQ(received.token(), source.token());
610
611 ASSERT_TRUE(received.has_present_type());
612 EXPECT_EQ(received.present_type(), source.present_type());
613 ASSERT_TRUE(received.has_on_time_finish());
614 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
615 ASSERT_TRUE(received.has_gpu_composition());
616 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
617 ASSERT_TRUE(received.has_jank_type());
618 EXPECT_EQ(received.jank_type(), source.jank_type());
619
620 ASSERT_TRUE(received.has_expected_start_ns());
621 EXPECT_EQ(received.expected_start_ns(), source.expected_start_ns());
622 ASSERT_TRUE(received.has_expected_end_ns());
623 EXPECT_EQ(received.expected_end_ns(), source.expected_end_ns());
624
625 ASSERT_TRUE(received.has_actual_start_ns());
626 EXPECT_EQ(received.actual_start_ns(), source.actual_start_ns());
627 ASSERT_TRUE(received.has_actual_end_ns());
628 EXPECT_EQ(received.actual_end_ns(), source.actual_end_ns());
629}
630
631void validateSurfaceFrameEvent(const ProtoSurfaceFrame& received, const ProtoSurfaceFrame& source) {
632 ASSERT_TRUE(received.has_token());
633 EXPECT_EQ(received.token(), source.token());
634
635 ASSERT_TRUE(received.has_display_frame_token());
636 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
637
638 ASSERT_TRUE(received.has_present_type());
639 EXPECT_EQ(received.present_type(), source.present_type());
640 ASSERT_TRUE(received.has_on_time_finish());
641 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
642 ASSERT_TRUE(received.has_gpu_composition());
643 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
644 ASSERT_TRUE(received.has_jank_type());
645 EXPECT_EQ(received.jank_type(), source.jank_type());
646
647 ASSERT_TRUE(received.has_expected_start_ns());
648 EXPECT_EQ(received.expected_start_ns(), source.expected_start_ns());
649 ASSERT_TRUE(received.has_expected_end_ns());
650 EXPECT_EQ(received.expected_end_ns(), source.expected_end_ns());
651
652 ASSERT_TRUE(received.has_actual_start_ns());
653 EXPECT_EQ(received.actual_start_ns(), source.actual_start_ns());
654 ASSERT_TRUE(received.has_actual_end_ns());
655 EXPECT_EQ(received.actual_end_ns(), source.actual_end_ns());
656
657 ASSERT_TRUE(received.has_layer_name());
658 EXPECT_EQ(received.layer_name(), source.layer_name());
659 ASSERT_TRUE(received.has_pid());
660 EXPECT_EQ(received.pid(), source.pid());
661}
662
663TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
664 auto tracingSession = getTracingSessionForTest();
665 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
666 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
667
668 tracingSession->StartBlocking();
669 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
670 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
671
672 // Set up the display frame
673 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20);
674 mFrameTimeline->setSfPresent(26, presentFence1);
675 presentFence1->signalForTest(31);
676
677 ProtoDisplayFrame protoDisplayFrame;
678 protoDisplayFrame.set_token(displayFrameToken1);
679 protoDisplayFrame.set_present_type(ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
680 protoDisplayFrame.set_on_time_finish(true);
681 protoDisplayFrame.set_gpu_composition(false);
682 protoDisplayFrame.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
683 protoDisplayFrame.set_expected_start_ns(10);
684 protoDisplayFrame.set_expected_end_ns(25);
685 protoDisplayFrame.set_actual_start_ns(20);
686 protoDisplayFrame.set_actual_end_ns(26);
687
688 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
689 // next frame
690 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50);
691 mFrameTimeline->setSfPresent(55, presentFence2);
692 presentFence2->signalForTest(55);
693
694 addEmptyDisplayFrame();
695 tracingSession->StopBlocking();
696
697 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
698 // Display Frame 1 has one packet - DisplayFrame.
699 // Display Frame 2 has one packet - DisplayFrame. However, this packet has been emitted but not
700 // flushed through traced, so this is not counted.
701 EXPECT_EQ(packets.size(), 1);
702
703 const auto& packet = packets[0];
704 ASSERT_TRUE(packet.has_timestamp());
705 ASSERT_TRUE(packet.has_frame_timeline_event());
706
707 const auto& event = packet.frame_timeline_event();
708 ASSERT_TRUE(event.has_display_frame());
709 ASSERT_FALSE(event.has_surface_frame());
710 const auto& displayFrameEvent = event.display_frame();
711 validateDisplayFrameEvent(displayFrameEvent, protoDisplayFrame);
712}
713
714TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
715 auto tracingSession = getTracingSessionForTest();
716 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
717 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
718
719 tracingSession->StartBlocking();
720 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
721 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
722 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
723
724 auto surfaceFrame1 =
725 mFrameTimeline->createSurfaceFrameForToken(sPidOne, sUidOne, sLayerNameOne,
726 sLayerNameOne, surfaceFrameToken);
727 surfaceFrame1->setActualStartTime(0);
728 surfaceFrame1->setActualQueueTime(15);
729 surfaceFrame1->setAcquireFenceTime(20);
730
731 ProtoSurfaceFrame protoSurfaceFrame;
732 protoSurfaceFrame.set_token(surfaceFrameToken);
733 protoSurfaceFrame.set_display_frame_token(displayFrameToken1);
734 protoSurfaceFrame.set_present_type(ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
735 protoSurfaceFrame.set_on_time_finish(true);
736 protoSurfaceFrame.set_gpu_composition(false);
737 protoSurfaceFrame.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
738 protoSurfaceFrame.set_expected_start_ns(10);
739 protoSurfaceFrame.set_expected_end_ns(25);
740 protoSurfaceFrame.set_actual_start_ns(0);
741 protoSurfaceFrame.set_actual_end_ns(20);
742 protoSurfaceFrame.set_layer_name(sLayerNameOne);
743 protoSurfaceFrame.set_pid(sPidOne);
744
745 // Set up the display frame
746 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20);
747 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame1),
748 SurfaceFrame::PresentState::Presented);
749 mFrameTimeline->setSfPresent(26, presentFence1);
750 presentFence1->signalForTest(31);
751
752 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
753 // next frame
754 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50);
755 mFrameTimeline->setSfPresent(55, presentFence2);
756 presentFence2->signalForTest(55);
757
758 addEmptyDisplayFrame();
759 tracingSession->StopBlocking();
760
761 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
762 // Display Frame 1 has one packet - DisplayFrame and a SurfaceFrame.
763 // Display Frame 2 has one packet - DisplayFrame. However, this packet has been emitted but not
764 // flushed through traced, so this is not counted.
765 EXPECT_EQ(packets.size(), 2);
766
767 const auto& packet = packets[1];
768 ASSERT_TRUE(packet.has_timestamp());
769 ASSERT_TRUE(packet.has_frame_timeline_event());
770
771 const auto& event = packet.frame_timeline_event();
772 ASSERT_TRUE(!event.has_display_frame());
773 ASSERT_TRUE(event.has_surface_frame());
774 const auto& surfaceFrameEvent = event.surface_frame();
775 validateSurfaceFrameEvent(surfaceFrameEvent, protoSurfaceFrame);
776}
777
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700778} // namespace android::frametimeline