blob: 96549056e212f30b5d7d561d8c9a9186338da396 [file] [log] [blame]
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010017
Alec Mouri9a29e672020-09-14 12:39:14 -070018#include "gmock/gmock-spec-builders.h"
19#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070020#undef LOG_TAG
21#define LOG_TAG "LibSurfaceFlingerUnittests"
22
23#include <FrameTimeline/FrameTimeline.h>
24#include <gtest/gtest.h>
25#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070026#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070027#include <cinttypes>
28
29using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080030using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080031using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070032using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070033using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000034using ProtoExpectedDisplayFrameStart =
35 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
36using ProtoExpectedSurfaceFrameStart =
37 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
38using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
39using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
40using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070041using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
42using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000043using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070044
Adithya Srinivasanf279e042020-08-17 14:56:27 -070045namespace android::frametimeline {
46
47class FrameTimelineTest : public testing::Test {
48public:
49 FrameTimelineTest() {
50 const ::testing::TestInfo* const test_info =
51 ::testing::UnitTest::GetInstance()->current_test_info();
52 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
53 }
54
55 ~FrameTimelineTest() {
56 const ::testing::TestInfo* const test_info =
57 ::testing::UnitTest::GetInstance()->current_test_info();
58 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
59 }
60
Adithya Srinivasan01189672020-10-20 14:23:05 -070061 static void SetUpTestSuite() {
62 // Need to initialize tracing in process for testing, and only once per test suite.
63 perfetto::TracingInitArgs args;
64 args.backends = perfetto::kInProcessBackend;
65 perfetto::Tracing::Initialize(args);
66 }
67
Adithya Srinivasanf279e042020-08-17 14:56:27 -070068 void SetUp() override {
Alec Mouri9a29e672020-09-14 12:39:14 -070069 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000070 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +000071 kTestThresholds, kHwcDuration);
Adithya Srinivasan01189672020-10-20 14:23:05 -070072 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070073 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000074 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070075 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070076 maxTokenRetentionTime = mTokenManager->kMaxRetentionTime;
77 }
78
Adithya Srinivasan01189672020-10-20 14:23:05 -070079 // Each tracing session can be used for a single block of Start -> Stop.
80 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
81 perfetto::TraceConfig cfg;
82 cfg.set_duration_ms(500);
83 cfg.add_buffers()->set_size_kb(1024);
84 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
85 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
86
87 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
88 tracingSession->Setup(cfg);
89 return tracingSession;
90 }
91
92 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
93 perfetto::TracingSession* tracingSession) {
94 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
95 perfetto::protos::Trace trace;
96 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
97
98 std::vector<perfetto::protos::TracePacket> packets;
99 for (const auto& packet : trace.packet()) {
100 if (!packet.has_frame_timeline_event()) {
101 continue;
102 }
103 packets.emplace_back(packet);
104 }
105 return packets;
106 }
107
108 void addEmptyDisplayFrame() {
109 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000110 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700111 mFrameTimeline->setSfPresent(2500, presentFence1);
112 }
113
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700114 void flushTokens(nsecs_t flushTime) {
115 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
116 mTokenManager->flushTokens(flushTime);
117 }
118
119 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
120 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800121 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
122 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700123 }
124
125 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
126 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
127 return mFrameTimeline->mDisplayFrames[idx];
128 }
129
130 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
131 return a.startTime == b.startTime && a.endTime == b.endTime &&
132 a.presentTime == b.presentTime;
133 }
134
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000135 const std::map<int64_t, TokenManagerPrediction>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700136 return mTokenManager->mPredictions;
137 }
138
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000139 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700140 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
141 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
142 }
143
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000144 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
145
146 void flushTrace() {
147 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
148 FrameTimelineDataSource::Trace(
149 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
150 }
151
Alec Mouri9a29e672020-09-14 12:39:14 -0700152 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700153 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
154 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000155 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700156 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700157 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700158 nsecs_t maxTokenRetentionTime;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000159 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000160 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
161 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(2ns).count();
162 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800163 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
164 kDeadlineThreshold,
165 kStartThreshold};
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000166 static constexpr nsecs_t kHwcDuration = std::chrono::nanoseconds(3ns).count();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700167};
168
Alec Mouri9a29e672020-09-14 12:39:14 -0700169static const std::string sLayerNameOne = "layer1";
170static const std::string sLayerNameTwo = "layer2";
171static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700172static constexpr pid_t sPidOne = 10;
173static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000174static constexpr int32_t sInputEventId = 5;
Alec Mouriadebf5c2021-01-05 12:57:36 -0800175static constexpr int32_t sLayerIdOne = 1;
176static constexpr int32_t sLayerIdTwo = 2;
Alec Mouri9a29e672020-09-14 12:39:14 -0700177
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700178TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
179 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000180 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700181 flushTokens(systemTime() + maxTokenRetentionTime);
182 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
183 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
184
185 // token1 should have expired
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000186 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700187 EXPECT_EQ(predictions.has_value(), false);
188
189 predictions = mTokenManager->getPredictionsForToken(token2);
190 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
191}
192
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700193TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800194 auto surfaceFrame1 =
195 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000196 sLayerNameOne, sLayerNameOne,
197 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800198 auto surfaceFrame2 =
199 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000200 sLayerNameOne, sLayerNameOne,
201 /*isBuffer*/ true);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700202 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
203 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
204}
205
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700206TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800207 auto surfaceFrame =
208 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000209 sLayerNameOne, sLayerNameOne,
210 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700211 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
212}
213
214TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
215 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
216 flushTokens(systemTime() + maxTokenRetentionTime);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000217 auto surfaceFrame =
218 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000219 sLayerIdOne, sLayerNameOne, sLayerNameOne,
220 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700221
222 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
223}
224
225TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
226 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000227 auto surfaceFrame =
228 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000229 sLayerIdOne, sLayerNameOne, sLayerNameOne,
230 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700231
232 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
233 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
234}
235
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000236TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
237 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
238 constexpr int32_t inputEventId = 1;
239 auto surfaceFrame =
240 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000241 sLayerIdOne, sLayerNameOne, sLayerNameOne,
242 /*isBuffer*/ true);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000243
244 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
245}
246
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700247TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
248 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700249 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000250 auto surfaceFrame1 =
251 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000252 sLayerIdOne, sLayerNameOne, sLayerNameOne,
253 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700254
255 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800256 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000257 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800258 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
259 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700260 mFrameTimeline->setSfPresent(25, presentFence1);
261 presentFence1->signalForTest(30);
262
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000263 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700264
265 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
266 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000267 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
268 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700269 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
270}
271
272TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800273 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800274 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700275 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
276 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700277 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700278 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000279 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800280 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000281 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri9a29e672020-09-14 12:39:14 -0700282 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000283 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800284 sUidOne, sLayerIdTwo, sLayerNameTwo,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000285 sLayerNameTwo, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800286 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800287 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
288 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
289 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
290 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700291 mFrameTimeline->setSfPresent(26, presentFence1);
292 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800293 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
294 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700295 presentFence1->signalForTest(42);
296
297 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800298 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700299 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
300 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
301
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000302 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700303
304 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800305 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700306 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
307 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100308 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
309 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700310}
311
312TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
313 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
314 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800315 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800316 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800317 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700318 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700319 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
320 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
321 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
322 int64_t sfToken = mTokenManager->generateTokenForPredictions(
323 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700324 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000325 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
Alec Mouriadebf5c2021-01-05 12:57:36 -0800326 sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000327 sLayerNameOne, sLayerNameOne,
328 /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800329 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800330 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
331 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700332 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
333 presentFence->signalForTest(32 + frameTimeFactor);
334 frameTimeFactor += 30;
335 }
336 auto displayFrame0 = getDisplayFrame(0);
337
338 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800339 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700340
341 // Add one more display frame
342 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
343 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
344 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
345 int64_t sfToken = mTokenManager->generateTokenForPredictions(
346 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700347 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000348 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800349 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000350 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800351 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800352 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
353 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700354 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
355 presentFence->signalForTest(32 + frameTimeFactor);
356 displayFrame0 = getDisplayFrame(0);
357
358 // The window should have slided by 1 now and the previous 0th display frame
359 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800360 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700361}
362
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700363TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000364 auto surfaceFrame =
365 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
366 "acquireFenceAfterQueue",
367 "acquireFenceAfterQueue", /*isBuffer*/ true);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700368 surfaceFrame->setActualQueueTime(123);
369 surfaceFrame->setAcquireFenceTime(456);
370 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
371}
372
373TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000374 auto surfaceFrame =
375 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
376 "acquireFenceAfterQueue",
377 "acquireFenceAfterQueue", /*isBuffer*/ true);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700378 surfaceFrame->setActualQueueTime(456);
379 surfaceFrame->setAcquireFenceTime(123);
380 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
381}
382
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700383TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
384 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
385 presentFence->signalForTest(2);
386
387 // Size shouldn't exceed maxDisplayFrames - 64
388 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700389 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800390 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000391 sLayerNameOne, sLayerNameOne,
392 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700393 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800394 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800395 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
396 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700397 mFrameTimeline->setSfPresent(27, presentFence);
398 }
399 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
400
401 // Increase the size to 256
402 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000403 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700404
405 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700406 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800407 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000408 sLayerNameOne, sLayerNameOne,
409 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700410 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800411 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800412 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
413 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700414 mFrameTimeline->setSfPresent(27, presentFence);
415 }
416 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
417
418 // Shrink the size to 128
419 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000420 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700421
422 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700423 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800424 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000425 sLayerNameOne, sLayerNameOne,
426 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700427 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800428 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800429 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
430 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700431 mFrameTimeline->setSfPresent(27, presentFence);
432 }
433 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
434}
Alec Mouri9a29e672020-09-14 12:39:14 -0700435
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000436TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
437 Fps refreshRate = Fps::fromPeriodNsecs(11);
438
439 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
440 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
441 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
442
443 auto surfaceFrame1 =
444 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
445 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000446 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000447 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
448 surfaceFrame1->setAcquireFenceTime(20);
449 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
450 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
451
452 mFrameTimeline->setSfPresent(59, presentFence1);
453 presentFence1->signalForTest(-1);
454 addEmptyDisplayFrame();
455
456 auto displayFrame0 = getDisplayFrame(0);
457 EXPECT_EQ(displayFrame0->getActuals().presentTime, -1);
458 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
459 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
460 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
461}
462
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800463// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000464TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
465 Fps refreshRate = Fps::fromPeriodNsecs(11);
466 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
467 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
468 int64_t surfaceFrameToken1 = -1;
469 int64_t sfToken1 = -1;
470
471 auto surfaceFrame1 =
472 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
473 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000474 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000475 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
476 surfaceFrame1->setAcquireFenceTime(20);
477 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
478 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
479 presentFence1->signalForTest(70);
480
481 mFrameTimeline->setSfPresent(59, presentFence1);
482}
483
Alec Mouri9a29e672020-09-14 12:39:14 -0700484TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000485 Fps refreshRate = Fps::fromPeriodNsecs(11);
486 // Deadline delta is 2ms because, sf's adjusted deadline is 60 - composerTime(3) = 57ms.
Alec Mouri9a29e672020-09-14 12:39:14 -0700487 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800488 incrementJankyFrames(
489 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
490 sLayerNameOne,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000491 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800492 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700493 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000494 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
495 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
496
Alec Mouri9a29e672020-09-14 12:39:14 -0700497 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000498 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800499 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000500 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000501 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
502 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800503 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
504 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000505 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700506
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000507 mFrameTimeline->setSfPresent(59, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700508}
509
510TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800511 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700512 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800513 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
514 sLayerNameOne, JankType::DisplayHAL,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000515 -1, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800516
Alec Mouri9a29e672020-09-14 12:39:14 -0700517 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000518 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
519 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
520
Alec Mouri9a29e672020-09-14 12:39:14 -0700521 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000522 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800523 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000524 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000525 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800526 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000527 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800528 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000529 presentFence1->signalForTest(90);
530 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800531 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700532}
533
534TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800535 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700536 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000537 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
538 sLayerNameOne,
539 JankType::AppDeadlineMissed, -1, 0,
540 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700541 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000542 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
543 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
544
Alec Mouri9a29e672020-09-14 12:39:14 -0700545 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000546 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800547 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000548 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000549 surfaceFrame1->setAcquireFenceTime(45);
550 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700551
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800552 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
553 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000554 presentFence1->signalForTest(90);
555 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100556
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800557 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700558}
559
Adithya Srinivasanead17162021-02-18 02:17:37 +0000560TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000561 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000562 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000563 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
564 sLayerNameOne,
565 JankType::SurfaceFlingerScheduling,
566 -1, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000567 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000568 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
569 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
570
Adithya Srinivasanead17162021-02-18 02:17:37 +0000571 auto surfaceFrame1 =
572 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800573 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000574 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000575 surfaceFrame1->setAcquireFenceTime(50);
576 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000577
578 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
579 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000580 presentFence1->signalForTest(60);
581 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000582
583 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
584}
585
586TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000587 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000588 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000589 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
590 sLayerNameOne,
591 JankType::PredictionError, -1, 5,
592 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000593 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000594 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
595 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
596
Adithya Srinivasanead17162021-02-18 02:17:37 +0000597 auto surfaceFrame1 =
598 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800599 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000600 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000601 surfaceFrame1->setAcquireFenceTime(40);
602 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000603
604 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
605 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000606 presentFence1->signalForTest(65);
607 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000608
609 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
610}
611
612TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000613 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000614 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000615 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
616 sLayerNameOne,
617 JankType::BufferStuffing, -1, 0,
618 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000619 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000620 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
621 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
622
Adithya Srinivasanead17162021-02-18 02:17:37 +0000623 auto surfaceFrame1 =
624 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800625 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000626 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000627 surfaceFrame1->setAcquireFenceTime(40);
628 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000629
630 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000631 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000632 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000633 presentFence1->signalForTest(90);
634 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000635
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000636 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000637}
638
Alec Mouri363faf02021-01-29 16:34:55 -0800639TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000640 Fps refreshRate = Fps::fromPeriodNsecs(11);
641 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800642 EXPECT_CALL(*mTimeStats,
643 incrementJankyFrames(
644 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000645 JankType::AppDeadlineMissed, -1, 0, 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800646 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000647 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
648 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
649
Alec Mouri363faf02021-01-29 16:34:55 -0800650 auto surfaceFrame1 =
651 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800652 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000653 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000654 surfaceFrame1->setAcquireFenceTime(45);
655 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800656
657 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
658 surfaceFrame1->setRenderRate(renderRate);
659 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000660 presentFence1->signalForTest(90);
661 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800662
663 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
664}
665
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000666TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
667 Fps refreshRate = Fps::fromPeriodNsecs(11);
668 Fps renderRate = Fps::fromPeriodNsecs(30);
669
670 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000671 incrementJankyFrames(
672 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
673 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000674 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000675 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
676 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
677 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
678
679 auto surfaceFrame1 =
680 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
681 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000682 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000683 surfaceFrame1->setAcquireFenceTime(45);
684 // Trigger a prediction expiry
685 flushTokens(systemTime() + maxTokenRetentionTime);
686 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
687
688 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
689 surfaceFrame1->setRenderRate(renderRate);
690 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
691 presentFence1->signalForTest(90);
692 mFrameTimeline->setSfPresent(86, presentFence1);
693
694 auto displayFrame = getDisplayFrame(0);
695 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
696 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
697 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
698 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
699
700 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000701 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000702}
703
Adithya Srinivasan01189672020-10-20 14:23:05 -0700704/*
705 * Tracing Tests
706 *
707 * Trace packets are flushed all the way only when the next packet is traced.
708 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
709 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
710 * will have additional empty frames created for this reason.
711 */
712TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
713 auto tracingSession = getTracingSessionForTest();
714 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700715 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000716 auto surfaceFrame1 =
717 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000718 sLayerIdOne, sLayerNameOne, sLayerNameOne,
719 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700720
721 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800722 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800723 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
724 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700725 mFrameTimeline->setSfPresent(25, presentFence1);
726 presentFence1->signalForTest(30);
727
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000728 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700729
730 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000731 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700732}
733
734TEST_F(FrameTimelineTest, tracing_sanityTest) {
735 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800736 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800737 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700738 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700739
740 tracingSession->StartBlocking();
741 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
742 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000743 auto surfaceFrame1 =
744 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000745 sLayerIdOne, sLayerNameOne, sLayerNameOne,
746 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700747
748 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800749 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800750 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
751 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700752 mFrameTimeline->setSfPresent(25, presentFence1);
753 presentFence1->signalForTest(30);
754
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000755 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000756 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700757 tracingSession->StopBlocking();
758
759 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000760 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000761 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700762}
763
764TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
765 auto tracingSession = getTracingSessionForTest();
766 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700767
768 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700769
770 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800771 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700772 mFrameTimeline->setSfPresent(25, presentFence1);
773 presentFence1->signalForTest(30);
774
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000775 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000776 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700777 tracingSession->StopBlocking();
778
779 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000780 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700781}
782
783TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
784 auto tracingSession = getTracingSessionForTest();
785 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700786
787 tracingSession->StartBlocking();
788 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800789 auto surfaceFrame1 =
790 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000791 sLayerNameOne, sLayerNameOne,
792 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700793
794 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800795 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800796 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
797 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700798 mFrameTimeline->setSfPresent(25, presentFence1);
799 presentFence1->signalForTest(30);
800
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000801 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000802 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700803 tracingSession->StopBlocking();
804
805 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000806 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
807 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000808 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700809}
810
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000811ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
812 pid_t pid) {
813 ProtoExpectedDisplayFrameStart proto;
814 proto.set_cookie(cookie);
815 proto.set_token(token);
816 proto.set_pid(pid);
817 return proto;
818}
819
820ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
821 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000822 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000823 ProtoActualDisplayFrameStart proto;
824 proto.set_cookie(cookie);
825 proto.set_token(token);
826 proto.set_pid(pid);
827 proto.set_present_type(presentType);
828 proto.set_on_time_finish(onTimeFinish);
829 proto.set_gpu_composition(gpuComposition);
830 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000831 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000832 return proto;
833}
834
835ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
836 int64_t displayFrameToken,
837 pid_t pid,
838 std::string layerName) {
839 ProtoExpectedSurfaceFrameStart proto;
840 proto.set_cookie(cookie);
841 proto.set_token(token);
842 proto.set_display_frame_token(displayFrameToken);
843 proto.set_pid(pid);
844 proto.set_layer_name(layerName);
845 return proto;
846}
847
848ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
849 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
850 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000851 ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000852 ProtoActualSurfaceFrameStart proto;
853 proto.set_cookie(cookie);
854 proto.set_token(token);
855 proto.set_display_frame_token(displayFrameToken);
856 proto.set_pid(pid);
857 proto.set_layer_name(layerName);
858 proto.set_present_type(presentType);
859 proto.set_on_time_finish(onTimeFinish);
860 proto.set_gpu_composition(gpuComposition);
861 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000862 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000863 return proto;
864}
865
866ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
867 ProtoFrameEnd proto;
868 proto.set_cookie(cookie);
869 return proto;
870}
871
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000872void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
873 const ProtoExpectedDisplayFrameStart& source) {
874 ASSERT_TRUE(received.has_cookie());
875 EXPECT_EQ(received.cookie(), source.cookie());
876
Adithya Srinivasan01189672020-10-20 14:23:05 -0700877 ASSERT_TRUE(received.has_token());
878 EXPECT_EQ(received.token(), source.token());
879
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000880 ASSERT_TRUE(received.has_pid());
881 EXPECT_EQ(received.pid(), source.pid());
882}
883
884void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
885 const ProtoActualDisplayFrameStart& source) {
886 ASSERT_TRUE(received.has_cookie());
887 EXPECT_EQ(received.cookie(), source.cookie());
888
889 ASSERT_TRUE(received.has_token());
890 EXPECT_EQ(received.token(), source.token());
891
892 ASSERT_TRUE(received.has_pid());
893 EXPECT_EQ(received.pid(), source.pid());
894
Adithya Srinivasan01189672020-10-20 14:23:05 -0700895 ASSERT_TRUE(received.has_present_type());
896 EXPECT_EQ(received.present_type(), source.present_type());
897 ASSERT_TRUE(received.has_on_time_finish());
898 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
899 ASSERT_TRUE(received.has_gpu_composition());
900 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
901 ASSERT_TRUE(received.has_jank_type());
902 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000903 ASSERT_TRUE(received.has_prediction_type());
904 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700905}
906
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000907void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
908 const ProtoExpectedSurfaceFrameStart& source) {
909 ASSERT_TRUE(received.has_cookie());
910 EXPECT_EQ(received.cookie(), source.cookie());
911
Adithya Srinivasan01189672020-10-20 14:23:05 -0700912 ASSERT_TRUE(received.has_token());
913 EXPECT_EQ(received.token(), source.token());
914
915 ASSERT_TRUE(received.has_display_frame_token());
916 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
917
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000918 ASSERT_TRUE(received.has_pid());
919 EXPECT_EQ(received.pid(), source.pid());
920
921 ASSERT_TRUE(received.has_layer_name());
922 EXPECT_EQ(received.layer_name(), source.layer_name());
923}
924
925void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
926 const ProtoActualSurfaceFrameStart& source) {
927 ASSERT_TRUE(received.has_cookie());
928 EXPECT_EQ(received.cookie(), source.cookie());
929
930 ASSERT_TRUE(received.has_token());
931 EXPECT_EQ(received.token(), source.token());
932
933 ASSERT_TRUE(received.has_display_frame_token());
934 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
935
936 ASSERT_TRUE(received.has_pid());
937 EXPECT_EQ(received.pid(), source.pid());
938
939 ASSERT_TRUE(received.has_layer_name());
940 EXPECT_EQ(received.layer_name(), source.layer_name());
941
Adithya Srinivasan01189672020-10-20 14:23:05 -0700942 ASSERT_TRUE(received.has_present_type());
943 EXPECT_EQ(received.present_type(), source.present_type());
944 ASSERT_TRUE(received.has_on_time_finish());
945 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
946 ASSERT_TRUE(received.has_gpu_composition());
947 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
948 ASSERT_TRUE(received.has_jank_type());
949 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000950 ASSERT_TRUE(received.has_prediction_type());
951 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000952}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700953
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000954void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
955 ASSERT_TRUE(received.has_cookie());
956 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700957}
958
959TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
960 auto tracingSession = getTracingSessionForTest();
961 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700962
963 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000964 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700965
966 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800967 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700968 mFrameTimeline->setSfPresent(26, presentFence1);
969 presentFence1->signalForTest(31);
970
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000971 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000972 auto protoExpectedDisplayFrameStart =
973 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
974 kSurfaceFlingerPid);
975 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
976 auto protoActualDisplayFrameStart =
977 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
978 kSurfaceFlingerPid,
979 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000980 FrameTimelineEvent::JANK_NONE,
981 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000982 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000983
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000984 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000985 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700986 tracingSession->StopBlocking();
987
988 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000989 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700990
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000991 // Packet - 0 : ExpectedDisplayFrameStart
992 const auto& packet0 = packets[0];
993 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000994 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000995 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700996
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000997 const auto& event0 = packet0.frame_timeline_event();
998 ASSERT_TRUE(event0.has_expected_display_frame_start());
999 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1000 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1001
1002 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1003 const auto& packet1 = packets[1];
1004 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001005 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001006 ASSERT_TRUE(packet1.has_frame_timeline_event());
1007
1008 const auto& event1 = packet1.frame_timeline_event();
1009 ASSERT_TRUE(event1.has_frame_end());
1010 const auto& expectedDisplayFrameEnd = event1.frame_end();
1011 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1012
1013 // Packet - 2 : ActualDisplayFrameStart
1014 const auto& packet2 = packets[2];
1015 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001016 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001017 ASSERT_TRUE(packet2.has_frame_timeline_event());
1018
1019 const auto& event2 = packet2.frame_timeline_event();
1020 ASSERT_TRUE(event2.has_actual_display_frame_start());
1021 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1022 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1023
1024 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1025 const auto& packet3 = packets[3];
1026 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001027 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001028 ASSERT_TRUE(packet3.has_frame_timeline_event());
1029
1030 const auto& event3 = packet3.frame_timeline_event();
1031 ASSERT_TRUE(event3.has_frame_end());
1032 const auto& actualDisplayFrameEnd = event3.frame_end();
1033 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001034}
1035
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001036TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1037 auto tracingSession = getTracingSessionForTest();
1038 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1039
1040 tracingSession->StartBlocking();
1041 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1042 // Flush the token so that it would expire
1043 flushTokens(systemTime() + maxTokenRetentionTime);
1044
1045 // Set up the display frame
1046 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1047 mFrameTimeline->setSfPresent(26, presentFence1);
1048 presentFence1->signalForTest(31);
1049
1050 int64_t traceCookie = snoopCurrentTraceCookie();
1051
1052 auto protoActualDisplayFrameStart =
1053 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1054 kSurfaceFlingerPid,
1055 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001056 false, FrameTimelineEvent::JANK_UNKNOWN,
1057 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001058 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1059
1060 addEmptyDisplayFrame();
1061 flushTrace();
1062 tracingSession->StopBlocking();
1063
1064 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1065 // Only actual timeline packets should be in the trace
1066 EXPECT_EQ(packets.size(), 2u);
1067
1068 // Packet - 0 : ActualDisplayFrameStart
1069 const auto& packet0 = packets[0];
1070 ASSERT_TRUE(packet0.has_timestamp());
1071 EXPECT_EQ(packet0.timestamp(), 20u);
1072 ASSERT_TRUE(packet0.has_frame_timeline_event());
1073
1074 const auto& event0 = packet0.frame_timeline_event();
1075 ASSERT_TRUE(event0.has_actual_display_frame_start());
1076 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1077 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1078
1079 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1080 const auto& packet1 = packets[1];
1081 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001082 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001083 ASSERT_TRUE(packet1.has_frame_timeline_event());
1084
1085 const auto& event1 = packet1.frame_timeline_event();
1086 ASSERT_TRUE(event1.has_frame_end());
1087 const auto& actualDisplayFrameEnd = event1.frame_end();
1088 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1089}
1090
Adithya Srinivasan01189672020-10-20 14:23:05 -07001091TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1092 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001093 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001094 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001095 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1096 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1097
1098 tracingSession->StartBlocking();
1099 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1100 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001101
1102 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001103 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001104 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001105 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001106 auto surfaceFrame2 =
1107 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001108 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001109 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001110 surfaceFrame1->setActualQueueTime(10);
1111 surfaceFrame1->setDropTime(15);
1112
1113 surfaceFrame2->setActualQueueTime(15);
1114 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001115
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001116 // First 2 cookies will be used by the DisplayFrame
1117 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1118
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001119 auto protoDroppedSurfaceFrameExpectedStart =
1120 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1121 displayFrameToken1, sPidOne, sLayerNameOne);
1122 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1123 auto protoDroppedSurfaceFrameActualStart =
1124 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1125 displayFrameToken1, sPidOne, sLayerNameOne,
1126 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001127 FrameTimelineEvent::JANK_NONE,
1128 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001129 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001130
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001131 auto protoPresentedSurfaceFrameExpectedStart =
1132 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1133 displayFrameToken1, sPidOne, sLayerNameOne);
1134 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1135 auto protoPresentedSurfaceFrameActualStart =
1136 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1137 displayFrameToken1, sPidOne, sLayerNameOne,
1138 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001139 FrameTimelineEvent::JANK_NONE,
1140 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001141 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001142
1143 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001144 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001145 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1146 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001147 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001148 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001149 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001150 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001151
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001152 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001153 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001154 tracingSession->StopBlocking();
1155
1156 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001157 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1158 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001159
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001160 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001161 const auto& packet4 = packets[4];
1162 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001163 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001164 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001165
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001166 const auto& event4 = packet4.frame_timeline_event();
1167 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001168 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1169 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001170
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001171 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001172 const auto& packet5 = packets[5];
1173 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001174 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001175 ASSERT_TRUE(packet5.has_frame_timeline_event());
1176
1177 const auto& event5 = packet5.frame_timeline_event();
1178 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001179 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1180 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001181
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001182 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001183 const auto& packet6 = packets[6];
1184 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001185 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001186 ASSERT_TRUE(packet6.has_frame_timeline_event());
1187
1188 const auto& event6 = packet6.frame_timeline_event();
1189 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001190 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1191 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001192
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001193 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001194 const auto& packet7 = packets[7];
1195 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001196 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001197 ASSERT_TRUE(packet7.has_frame_timeline_event());
1198
1199 const auto& event7 = packet7.frame_timeline_event();
1200 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001201 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1202 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1203
1204 // Packet - 8 : ExpectedSurfaceFrameStart2
1205 const auto& packet8 = packets[8];
1206 ASSERT_TRUE(packet8.has_timestamp());
1207 EXPECT_EQ(packet8.timestamp(), 10u);
1208 ASSERT_TRUE(packet8.has_frame_timeline_event());
1209
1210 const auto& event8 = packet8.frame_timeline_event();
1211 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1212 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1213 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1214
1215 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1216 const auto& packet9 = packets[9];
1217 ASSERT_TRUE(packet9.has_timestamp());
1218 EXPECT_EQ(packet9.timestamp(), 25u);
1219 ASSERT_TRUE(packet9.has_frame_timeline_event());
1220
1221 const auto& event9 = packet9.frame_timeline_event();
1222 ASSERT_TRUE(event9.has_frame_end());
1223 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1224 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1225
1226 // Packet - 10 : ActualSurfaceFrameStart2
1227 const auto& packet10 = packets[10];
1228 ASSERT_TRUE(packet10.has_timestamp());
1229 EXPECT_EQ(packet10.timestamp(), 10u);
1230 ASSERT_TRUE(packet10.has_frame_timeline_event());
1231
1232 const auto& event10 = packet10.frame_timeline_event();
1233 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1234 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1235 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1236
1237 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1238 const auto& packet11 = packets[11];
1239 ASSERT_TRUE(packet11.has_timestamp());
1240 EXPECT_EQ(packet11.timestamp(), 20u);
1241 ASSERT_TRUE(packet11.has_frame_timeline_event());
1242
1243 const auto& event11 = packet11.frame_timeline_event();
1244 ASSERT_TRUE(event11.has_frame_end());
1245 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1246 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1247}
1248
1249TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1250 auto tracingSession = getTracingSessionForTest();
1251 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1252
1253 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001254 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1255 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1256 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001257 int64_t surfaceFrameToken =
1258 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1259
1260 // Flush the token so that it would expire
1261 flushTokens(systemTime() + maxTokenRetentionTime);
1262 auto surfaceFrame1 =
1263 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001264 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001265 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001266 surfaceFrame1->setActualQueueTime(appEndTime);
1267 surfaceFrame1->setAcquireFenceTime(appEndTime);
1268
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001269 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1270 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1271 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001272 int64_t displayFrameToken =
1273 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1274
1275 // First 2 cookies will be used by the DisplayFrame
1276 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1277
1278 auto protoActualSurfaceFrameStart =
1279 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1280 displayFrameToken, sPidOne, sLayerNameOne,
1281 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001282 false, FrameTimelineEvent::JANK_UNKNOWN,
1283 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001284 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1285
1286 // Set up the display frame
1287 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1288 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1289 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1290 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1291 presentFence1->signalForTest(sfPresentTime);
1292
1293 addEmptyDisplayFrame();
1294 flushTrace();
1295 tracingSession->StopBlocking();
1296
1297 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1298 // Display Frame 4 packets + SurfaceFrame 2 packets
1299 ASSERT_EQ(packets.size(), 6u);
1300
1301 // Packet - 4 : ActualSurfaceFrameStart
1302 const auto& packet4 = packets[4];
1303 ASSERT_TRUE(packet4.has_timestamp());
1304 EXPECT_EQ(packet4.timestamp(),
1305 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1306 ASSERT_TRUE(packet4.has_frame_timeline_event());
1307
1308 const auto& event4 = packet4.frame_timeline_event();
1309 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1310 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1311 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1312
1313 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1314 const auto& packet5 = packets[5];
1315 ASSERT_TRUE(packet5.has_timestamp());
1316 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1317 ASSERT_TRUE(packet5.has_frame_timeline_event());
1318
1319 const auto& event5 = packet5.frame_timeline_event();
1320 ASSERT_TRUE(event5.has_frame_end());
1321 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001322 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001323}
1324
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001325// Tests for Jank classification
1326TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001327 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001328 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001329 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1330 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001331 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001332 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001333 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001334 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001335 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001336 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001337 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1338 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1339 mFrameTimeline->setSfPresent(26, presentFence1);
1340 auto displayFrame = getDisplayFrame(0);
1341 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1342 presentFence1->signalForTest(29);
1343
1344 // Fences haven't been flushed yet, so it should be 0
1345 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1346 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1347
1348 addEmptyDisplayFrame();
1349 displayFrame = getDisplayFrame(0);
1350
1351 // Fences have flushed, so the present timestamps should be updated
1352 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1353 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1354 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1355 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1356 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1357}
1358
1359TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001360 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001361 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001362 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1363 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001364 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001365 mFrameTimeline->setSfPresent(26, presentFence1);
1366 auto displayFrame = getDisplayFrame(0);
1367 presentFence1->signalForTest(30);
1368
1369 // Fences for the first frame haven't been flushed yet, so it should be 0
1370 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1371
1372 // Trigger a flush by finalizing the next DisplayFrame
1373 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001374 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001375 mFrameTimeline->setSfPresent(56, presentFence2);
1376 displayFrame = getDisplayFrame(0);
1377
1378 // Fences for the first frame have flushed, so the present timestamps should be updated
1379 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1380 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1381 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1382 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1383
1384 // Fences for the second frame haven't been flushed yet, so it should be 0
1385 auto displayFrame2 = getDisplayFrame(1);
1386 presentFence2->signalForTest(65);
1387 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001388 addEmptyDisplayFrame();
1389 displayFrame2 = getDisplayFrame(1);
1390
1391 // Fences for the second frame have flushed, so the present timestamps should be updated
1392 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1393 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1394 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1395 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1396}
1397
1398TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001399 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001400 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001401 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1402 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001403 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001404 mFrameTimeline->setSfPresent(26, presentFence1);
1405 auto displayFrame = getDisplayFrame(0);
1406 presentFence1->signalForTest(50);
1407
1408 // Fences for the first frame haven't been flushed yet, so it should be 0
1409 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1410
1411 // Trigger a flush by finalizing the next DisplayFrame
1412 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001413 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001414 mFrameTimeline->setSfPresent(56, presentFence2);
1415 displayFrame = getDisplayFrame(0);
1416
1417 // Fences for the first frame have flushed, so the present timestamps should be updated
1418 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1419 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1420 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1421 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1422
1423 // Fences for the second frame haven't been flushed yet, so it should be 0
1424 auto displayFrame2 = getDisplayFrame(1);
1425 presentFence2->signalForTest(75);
1426 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1427
1428 addEmptyDisplayFrame();
1429 displayFrame2 = getDisplayFrame(1);
1430
1431 // Fences for the second frame have flushed, so the present timestamps should be updated
1432 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1433 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1434 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1435 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1436}
1437
1438TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001439 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1440 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001441 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001442
1443 mFrameTimeline->setSfPresent(22, presentFence1);
1444 auto displayFrame = getDisplayFrame(0);
1445 presentFence1->signalForTest(28);
1446
1447 // Fences haven't been flushed yet, so it should be 0
1448 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1449
1450 addEmptyDisplayFrame();
1451 displayFrame = getDisplayFrame(0);
1452
1453 // Fences have flushed, so the present timestamps should be updated
1454 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1455 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1456 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1457 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1458}
1459
1460TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001461 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1462 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001463 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001464 mFrameTimeline->setSfPresent(36, presentFence1);
1465 auto displayFrame = getDisplayFrame(0);
1466 presentFence1->signalForTest(52);
1467
1468 // Fences haven't been flushed yet, so it should be 0
1469 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1470
1471 addEmptyDisplayFrame();
1472 displayFrame = getDisplayFrame(0);
1473
1474 // Fences have flushed, so the present timestamps should be updated
1475 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1476 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1477 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1478 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1479}
1480
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001481TEST_F(FrameTimelineTest, jankClassification_displayFrameLateStartLateFinishLatePresent) {
1482 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1483 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1484 mFrameTimeline->setSfWakeUp(sfToken1, 26, Fps::fromPeriodNsecs(11));
1485 mFrameTimeline->setSfPresent(36, presentFence1);
1486 auto displayFrame = getDisplayFrame(0);
1487 presentFence1->signalForTest(52);
1488
1489 // Fences haven't been flushed yet, so it should be 0
1490 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1491
1492 addEmptyDisplayFrame();
1493 displayFrame = getDisplayFrame(0);
1494
1495 // Fences have flushed, so the present timestamps should be updated
1496 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1497 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::LateStart);
1498 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1499 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1500 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1501}
1502
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001503TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001504 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001505 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001506 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1507 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001508 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1509 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1510 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001511 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001512 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001513 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001514 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001515 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001516 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1517 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001518 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001519 auto displayFrame1 = getDisplayFrame(0);
1520 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1521 presentFence1->signalForTest(30);
1522
1523 // Fences for the first frame haven't been flushed yet, so it should be 0
1524 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1525 auto actuals1 = presentedSurfaceFrame1.getActuals();
1526 EXPECT_EQ(actuals1.presentTime, 0);
1527
1528 // Trigger a flush by finalizing the next DisplayFrame
1529 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1530 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001531 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001532 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001533 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001534 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001535 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001536 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1537 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001538 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001539 auto displayFrame2 = getDisplayFrame(1);
1540 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1541
1542 // Fences for the first frame have flushed, so the present timestamps should be updated
1543 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1544 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1545 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1546 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1547
1548 actuals1 = presentedSurfaceFrame1.getActuals();
1549 EXPECT_EQ(actuals1.presentTime, 30);
1550 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1551 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1552 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1553
1554 // Fences for the second frame haven't been flushed yet, so it should be 0
1555 presentFence2->signalForTest(65);
1556 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1557 auto actuals2 = presentedSurfaceFrame2.getActuals();
1558 EXPECT_EQ(actuals2.presentTime, 0);
1559
Alec Mouri363faf02021-01-29 16:34:55 -08001560 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1561
1562 EXPECT_CALL(*mTimeStats,
1563 incrementJankyFrames(
1564 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1565 sLayerNameOne, JankType::PredictionError, 0, 5,
1566 0}));
1567
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001568 addEmptyDisplayFrame();
1569
1570 // Fences for the second frame have flushed, so the present timestamps should be updated
1571 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1572 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1573 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1574 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1575
1576 actuals2 = presentedSurfaceFrame2.getActuals();
1577 EXPECT_EQ(actuals2.presentTime, 65);
1578 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1579 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1580 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1581}
1582
1583TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001584 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001585 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001586 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1587 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001588 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1589 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1590 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001591 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001592 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001593 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001594 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001595 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001596 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1597 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1598 mFrameTimeline->setSfPresent(26, presentFence1);
1599 auto displayFrame1 = getDisplayFrame(0);
1600 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1601 presentFence1->signalForTest(50);
1602
1603 // Fences for the first frame haven't been flushed yet, so it should be 0
1604 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1605 auto actuals1 = presentedSurfaceFrame1.getActuals();
1606 EXPECT_EQ(actuals1.presentTime, 0);
1607
1608 // Trigger a flush by finalizing the next DisplayFrame
1609 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1610 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001611 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001612 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001613 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001614 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001615 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001616 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1617 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001618 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001619 auto displayFrame2 = getDisplayFrame(1);
1620 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1621
1622 // Fences for the first frame have flushed, so the present timestamps should be updated
1623 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1624 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1625 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1626 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1627
1628 actuals1 = presentedSurfaceFrame1.getActuals();
1629 EXPECT_EQ(actuals1.presentTime, 50);
1630 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1631 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1632 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1633
1634 // Fences for the second frame haven't been flushed yet, so it should be 0
1635 presentFence2->signalForTest(86);
1636 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1637 auto actuals2 = presentedSurfaceFrame2.getActuals();
1638 EXPECT_EQ(actuals2.presentTime, 0);
1639
Alec Mouri363faf02021-01-29 16:34:55 -08001640 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1641
1642 EXPECT_CALL(*mTimeStats,
1643 incrementJankyFrames(
1644 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1645 sLayerNameOne, JankType::PredictionError, 0, 5,
1646 0}));
1647
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001648 addEmptyDisplayFrame();
1649
1650 // Fences for the second frame have flushed, so the present timestamps should be updated
1651 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1652 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1653 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1654 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1655
1656 actuals2 = presentedSurfaceFrame2.getActuals();
1657 EXPECT_EQ(actuals2.presentTime, 86);
1658 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1659 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1660 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1661}
1662
1663TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001664 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001665
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001666 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001667 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001668 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1669 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001670 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001671 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001672 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001673 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001674 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001675 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1676 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1677 mFrameTimeline->setSfPresent(46, presentFence1);
1678 auto displayFrame1 = getDisplayFrame(0);
1679 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1680 presentFence1->signalForTest(50);
1681
1682 // Fences for the first frame haven't been flushed yet, so it should be 0
1683 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1684 auto actuals1 = presentedSurfaceFrame1.getActuals();
1685 EXPECT_EQ(actuals1.presentTime, 0);
1686
1687 addEmptyDisplayFrame();
1688
1689 // Fences for the first frame have flushed, so the present timestamps should be updated
1690 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1691 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1692 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1693 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1694
1695 actuals1 = presentedSurfaceFrame1.getActuals();
1696 EXPECT_EQ(actuals1.presentTime, 50);
1697 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1698 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1699 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1700}
1701
1702TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001703 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001704 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001705 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001706
Alec Mouri363faf02021-01-29 16:34:55 -08001707 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001708 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001709 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1710 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001711 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1712 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1713 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001714 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001715 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001716 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001717 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001718 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001719 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1720 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1721 mFrameTimeline->setSfPresent(36, presentFence1);
1722 auto displayFrame1 = getDisplayFrame(0);
1723 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1724 presentFence1->signalForTest(40);
1725
1726 // Fences for the first frame haven't been flushed yet, so it should be 0
1727 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1728 auto actuals1 = presentedSurfaceFrame1.getActuals();
1729 EXPECT_EQ(actuals1.presentTime, 0);
1730
1731 // Trigger a flush by finalizing the next DisplayFrame
1732 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1733 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001734 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001735 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001736 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001737 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001738 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001739 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1740 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1741 mFrameTimeline->setSfPresent(56, presentFence2);
1742 auto displayFrame2 = getDisplayFrame(1);
1743 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1744
1745 // Fences for the first frame have flushed, so the present timestamps should be updated
1746 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1747 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1748 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1749 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1750
1751 actuals1 = presentedSurfaceFrame1.getActuals();
1752 EXPECT_EQ(actuals1.presentTime, 40);
1753 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1754 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1755 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1756
1757 // Fences for the second frame haven't been flushed yet, so it should be 0
1758 presentFence2->signalForTest(60);
1759 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1760 auto actuals2 = presentedSurfaceFrame2.getActuals();
1761 EXPECT_EQ(actuals2.presentTime, 0);
1762
1763 addEmptyDisplayFrame();
1764
1765 // Fences for the second frame have flushed, so the present timestamps should be updated
1766 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1767 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1768 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1769 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1770
1771 actuals2 = presentedSurfaceFrame2.getActuals();
1772 EXPECT_EQ(actuals2.presentTime, 60);
1773 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1774 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001775 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1776 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001777}
1778
1779TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001780 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001781 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001782 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1783 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1784 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1785
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001786 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1787 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001788 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001789 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001790 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001791 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001792 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001793 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001794 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1795 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1796 mFrameTimeline->setSfPresent(56, presentFence1);
1797 auto displayFrame1 = getDisplayFrame(0);
1798 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1799 presentFence1->signalForTest(60);
1800
1801 // Fences for the first frame haven't been flushed yet, so it should be 0
1802 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1803 auto actuals1 = presentedSurfaceFrame1.getActuals();
1804 EXPECT_EQ(actuals1.presentTime, 0);
1805
1806 // Trigger a flush by finalizing the next DisplayFrame
1807 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1808 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001809 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001810 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001811 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001812 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001813 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001814 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1815 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1816 mFrameTimeline->setSfPresent(116, presentFence2);
1817 auto displayFrame2 = getDisplayFrame(1);
1818 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1819 presentFence2->signalForTest(120);
1820
1821 // Fences for the first frame have flushed, so the present timestamps should be updated
1822 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1823 actuals1 = presentedSurfaceFrame1.getActuals();
1824 EXPECT_EQ(actuals1.endTime, 50);
1825 EXPECT_EQ(actuals1.presentTime, 60);
1826
1827 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1828 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1829 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1830
1831 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1832 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1833 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1834
1835 // Fences for the second frame haven't been flushed yet, so it should be 0
1836 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1837 auto actuals2 = presentedSurfaceFrame2.getActuals();
1838 EXPECT_EQ(actuals2.presentTime, 0);
1839
1840 addEmptyDisplayFrame();
1841
1842 // Fences for the second frame have flushed, so the present timestamps should be updated
1843 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1844 actuals2 = presentedSurfaceFrame2.getActuals();
1845 EXPECT_EQ(actuals2.presentTime, 120);
1846
1847 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1848 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1849 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1850
1851 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1852 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1853 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1854 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1855}
Alec Mouriadebf5c2021-01-05 12:57:36 -08001856
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001857TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
1858 // Layer specific increment
1859 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
1860 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1861 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1862 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1863
1864 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1865 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1866 auto surfaceFrame1 =
1867 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1868 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001869 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001870 surfaceFrame1->setAcquireFenceTime(50);
1871 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
1872 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1873 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1874 mFrameTimeline->setSfPresent(56, presentFence1);
1875 auto displayFrame1 = getDisplayFrame(0);
1876 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1877 presentFence1->signalForTest(60);
1878
1879 // Fences for the first frame haven't been flushed yet, so it should be 0
1880 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1881 auto actuals1 = presentedSurfaceFrame1.getActuals();
1882 EXPECT_EQ(actuals1.presentTime, 0);
1883
1884 // Trigger a flush by finalizing the next DisplayFrame
1885 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1886 auto surfaceFrame2 =
1887 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1888 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001889 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001890 surfaceFrame2->setAcquireFenceTime(80);
1891 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
1892 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
1893 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1894 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1895 mFrameTimeline->setSfPresent(86, presentFence2);
1896 auto displayFrame2 = getDisplayFrame(1);
1897 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1898 presentFence2->signalForTest(90);
1899
1900 // Fences for the first frame have flushed, so the present timestamps should be updated
1901 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1902 actuals1 = presentedSurfaceFrame1.getActuals();
1903 EXPECT_EQ(actuals1.endTime, 50);
1904 EXPECT_EQ(actuals1.presentTime, 60);
1905
1906 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1907 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1908 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1909
1910 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1911 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1912 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1913
1914 // Fences for the second frame haven't been flushed yet, so it should be 0
1915 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1916 auto actuals2 = presentedSurfaceFrame2.getActuals();
1917 EXPECT_EQ(actuals2.presentTime, 0);
1918
1919 addEmptyDisplayFrame();
1920
1921 // Fences for the second frame have flushed, so the present timestamps should be updated
1922 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
1923 actuals2 = presentedSurfaceFrame2.getActuals();
1924 EXPECT_EQ(actuals2.presentTime, 90);
1925
1926 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1927 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1928 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1929
1930 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1931 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1932 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
1933}
1934
Alec Mouriadebf5c2021-01-05 12:57:36 -08001935TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
1936 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
1937}
1938
1939TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001940 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001941
1942 auto surfaceFrame1 =
1943 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001944 sLayerIdOne, sLayerNameOne, sLayerNameOne,
1945 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08001946 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1947 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1948 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1949 presentFence1->signalForTest(oneHundredMs);
1950 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1951
1952 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
1953}
1954
1955TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001956 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1957 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001958 auto surfaceFrame1 =
1959 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001960 sLayerIdOne, sLayerNameOne, sLayerNameOne,
1961 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08001962 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1963 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1964 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1965 presentFence1->signalForTest(oneHundredMs);
1966 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1967
1968 auto surfaceFrame2 =
1969 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001970 sLayerIdOne, sLayerNameOne, sLayerNameOne,
1971 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08001972 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1973 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1974 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1975 presentFence2->signalForTest(twoHundredMs);
1976 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1977
1978 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
1979}
1980
1981TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001982 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1983 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001984 auto surfaceFrame1 =
1985 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001986 sLayerIdOne, sLayerNameOne, sLayerNameOne,
1987 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08001988 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1989 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1990 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1991 presentFence1->signalForTest(oneHundredMs);
1992 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1993
1994 auto surfaceFrame2 =
1995 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001996 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
1997 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08001998 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1999 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2000 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2001 presentFence2->signalForTest(twoHundredMs);
2002 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2003
2004 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2005}
2006
2007TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002008 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2009 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002010 auto surfaceFrame1 =
2011 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002012 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2013 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002014 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2015 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2016 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2017 presentFence1->signalForTest(oneHundredMs);
2018 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2019
2020 auto surfaceFrame2 =
2021 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002022 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2023 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002024 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2025 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2026 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2027 presentFence2->signalForTest(twoHundredMs);
2028 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2029
2030 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2031}
2032
2033TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002034 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2035 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2036 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2037 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2038 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002039 auto surfaceFrame1 =
2040 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002041 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2042 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002043 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2044 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2045 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2046 presentFence1->signalForTest(oneHundredMs);
2047 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2048
2049 auto surfaceFrame2 =
2050 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002051 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2052 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002053 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2054 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2055 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2056 presentFence2->signalForTest(twoHundredMs);
2057 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2058
2059 auto surfaceFrame3 =
2060 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002061 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2062 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002063 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2064 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2065 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2066 presentFence3->signalForTest(threeHundredMs);
2067 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2068
2069 auto surfaceFrame4 =
2070 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002071 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2072 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002073 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2074 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2075 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2076 presentFence4->signalForTest(fiveHundredMs);
2077 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2078
2079 auto surfaceFrame5 =
2080 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002081 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2082 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002083 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2084 // Dropped frames will be excluded from fps computation
2085 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2086 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2087 presentFence5->signalForTest(sixHundredMs);
2088 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2089
2090 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2091}
2092
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002093} // namespace android::frametimeline