blob: 7a1c7c6e0ed39151a732f8da33c7dedeecc3e070 [file] [log] [blame]
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001/*
2 * Copyright 2018 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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080021#undef LOG_TAG
22#define LOG_TAG "LibSurfaceFlingerUnittests"
23
Mikael Pessa2e1608f2019-07-19 11:25:35 -070024#include <TimeStats/TimeStats.h>
Alec Mouri37384342020-01-02 17:23:37 -080025#include <android/util/ProtoOutputStream.h>
Alec Mourifb571ea2019-01-24 18:42:10 -080026#include <gmock/gmock.h>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080027#include <gtest/gtest.h>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080028#include <log/log.h>
29#include <utils/String16.h>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080030#include <utils/Vector.h>
31
Alec Mouri9519bf12019-11-15 16:54:44 -080032#include <chrono>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080033#include <random>
Alec Mourifb571ea2019-01-24 18:42:10 -080034#include <unordered_set>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080035
Lloyd Pique067fe1e2018-12-06 19:44:13 -080036#include "libsurfaceflinger_unittest_main.h"
37
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080038using namespace android::surfaceflinger;
39using namespace google::protobuf;
Vishnu Nairabf97fd2020-02-03 13:51:16 -080040using namespace std::chrono_literals;
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080041
42namespace android {
43namespace {
44
Alec Mouri8e2f31b2020-01-16 22:04:35 +000045using testing::_;
Alec Mouri37384342020-01-02 17:23:37 -080046using testing::AnyNumber;
Alec Mourifb571ea2019-01-24 18:42:10 -080047using testing::Contains;
Vishnu Nair9b079a22020-01-21 14:36:08 -080048using testing::HasSubstr;
Alec Mouri8e2f31b2020-01-16 22:04:35 +000049using testing::InSequence;
Alec Mourifb571ea2019-01-24 18:42:10 -080050using testing::SizeIs;
Alec Mouri37384342020-01-02 17:23:37 -080051using testing::StrEq;
Alec Mourifb571ea2019-01-24 18:42:10 -080052using testing::UnorderedElementsAre;
53
Peiyong Lin65248e02020-04-18 21:15:07 -070054using PowerMode = hardware::graphics::composer::V2_4::IComposerClient::PowerMode;
55
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080056// clang-format off
57#define FMT_PROTO true
58#define FMT_STRING false
59#define LAYER_ID_0 0
60#define LAYER_ID_1 1
61#define LAYER_ID_INVALID -1
62#define NUM_LAYERS 1
63#define NUM_LAYERS_INVALID "INVALID"
64
65enum InputCommand : int32_t {
66 ENABLE = 0,
67 DISABLE = 1,
68 CLEAR = 2,
69 DUMP_ALL = 3,
70 DUMP_MAXLAYERS_1 = 4,
71 DUMP_MAXLAYERS_INVALID = 5,
72 INPUT_COMMAND_BEGIN = ENABLE,
73 INPUT_COMMAND_END = DUMP_MAXLAYERS_INVALID,
74 INPUT_COMMAND_RANGE = INPUT_COMMAND_END - INPUT_COMMAND_BEGIN + 1,
75};
76
77enum TimeStamp : int32_t {
78 POST = 0,
79 ACQUIRE = 1,
80 ACQUIRE_FENCE = 2,
81 LATCH = 3,
82 DESIRED = 4,
83 PRESENT = 5,
84 PRESENT_FENCE = 6,
85 TIME_STAMP_BEGIN = POST,
86 TIME_STAMP_END = PRESENT,
87 TIME_STAMP_RANGE = TIME_STAMP_END - TIME_STAMP_BEGIN + 1,
88};
89
90static const TimeStamp NORMAL_SEQUENCE[] = {
91 TimeStamp::POST,
92 TimeStamp::ACQUIRE,
93 TimeStamp::LATCH,
94 TimeStamp::DESIRED,
95 TimeStamp::PRESENT,
96};
97
98static const TimeStamp NORMAL_SEQUENCE_2[] = {
99 TimeStamp::POST,
100 TimeStamp::ACQUIRE_FENCE,
101 TimeStamp::LATCH,
102 TimeStamp::DESIRED,
103 TimeStamp::PRESENT_FENCE,
104};
105
106static const TimeStamp UNORDERED_SEQUENCE[] = {
107 TimeStamp::ACQUIRE,
108 TimeStamp::LATCH,
109 TimeStamp::POST,
110 TimeStamp::DESIRED,
111 TimeStamp::PRESENT,
112};
113
114static const TimeStamp INCOMPLETE_SEQUENCE[] = {
115 TimeStamp::POST,
116};
117// clang-format on
118
119class TimeStatsTest : public testing::Test {
120public:
121 TimeStatsTest() {
122 const ::testing::TestInfo* const test_info =
123 ::testing::UnitTest::GetInstance()->current_test_info();
124 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
125 }
126
127 ~TimeStatsTest() {
128 const ::testing::TestInfo* const test_info =
129 ::testing::UnitTest::GetInstance()->current_test_info();
130 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
131 }
132
133 std::string inputCommand(InputCommand cmd, bool useProto);
134
135 void setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts);
136
137 int32_t genRandomInt32(int32_t begin, int32_t end);
138
139 template <size_t N>
140 void insertTimeRecord(const TimeStamp (&sequence)[N], int32_t id, uint64_t frameNumber,
141 nsecs_t ts) {
142 for (size_t i = 0; i < N; i++, ts += 1000000) {
143 setTimeStamp(sequence[i], id, frameNumber, ts);
144 }
145 }
146
147 std::mt19937 mRandomEngine = std::mt19937(std::random_device()());
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000148
149 class FakeStatsEventDelegate : public impl::TimeStats::StatsEventDelegate {
150 public:
151 FakeStatsEventDelegate() = default;
152 ~FakeStatsEventDelegate() override = default;
153
Tej Singh2a457b62020-01-31 16:16:10 -0800154 struct AStatsEvent* addStatsEventToPullData(AStatsEventList*) override {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000155 return mEvent;
156 }
Tej Singh38a4b212020-03-13 19:04:51 -0700157 void setStatsPullAtomCallback(int32_t atom_tag, AStatsManager_PullAtomMetadata*,
158 AStatsManager_PullAtomCallback callback,
159 void* cookie) override {
Alec Mouri37384342020-01-02 17:23:37 -0800160 mAtomTags.push_back(atom_tag);
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000161 mCallback = callback;
162 mCookie = cookie;
163 }
164
Tej Singh2a457b62020-01-31 16:16:10 -0800165 AStatsManager_PullAtomCallbackReturn makePullAtomCallback(int32_t atom_tag, void* cookie) {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000166 return (*mCallback)(atom_tag, nullptr, cookie);
167 }
168
Tej Singh38a4b212020-03-13 19:04:51 -0700169 MOCK_METHOD1(clearStatsPullAtomCallback, void(int32_t));
Tej Singh2a457b62020-01-31 16:16:10 -0800170 MOCK_METHOD2(statsEventSetAtomId, void(AStatsEvent*, uint32_t));
Alec Mouri717bcb62020-02-10 17:07:19 -0800171 MOCK_METHOD2(statsEventWriteInt32, void(AStatsEvent*, int32_t));
Tej Singh2a457b62020-01-31 16:16:10 -0800172 MOCK_METHOD2(statsEventWriteInt64, void(AStatsEvent*, int64_t));
173 MOCK_METHOD2(statsEventWriteString8, void(AStatsEvent*, const char*));
174 MOCK_METHOD3(statsEventWriteByteArray, void(AStatsEvent*, const uint8_t*, size_t));
175 MOCK_METHOD1(statsEventBuild, void(AStatsEvent*));
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000176
Tej Singh2a457b62020-01-31 16:16:10 -0800177 AStatsEvent* mEvent = AStatsEvent_obtain();
Alec Mouri37384342020-01-02 17:23:37 -0800178 std::vector<int32_t> mAtomTags;
Tej Singh2a457b62020-01-31 16:16:10 -0800179 AStatsManager_PullAtomCallback mCallback = nullptr;
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000180 void* mCookie = nullptr;
181 };
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000182 FakeStatsEventDelegate* mDelegate = new FakeStatsEventDelegate;
183 std::unique_ptr<TimeStats> mTimeStats =
Alec Mouri37384342020-01-02 17:23:37 -0800184 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate),
185 std::nullopt, std::nullopt);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800186};
187
188std::string TimeStatsTest::inputCommand(InputCommand cmd, bool useProto) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800189 std::string result;
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800190 Vector<String16> args;
191
192 switch (cmd) {
193 case InputCommand::ENABLE:
194 args.push_back(String16("-enable"));
195 break;
196 case InputCommand::DISABLE:
197 args.push_back(String16("-disable"));
198 break;
199 case InputCommand::CLEAR:
200 args.push_back(String16("-clear"));
201 break;
202 case InputCommand::DUMP_ALL:
203 args.push_back(String16("-dump"));
204 break;
205 case InputCommand::DUMP_MAXLAYERS_1:
206 args.push_back(String16("-dump"));
207 args.push_back(String16("-maxlayers"));
208 args.push_back(String16(std::to_string(NUM_LAYERS).c_str()));
209 break;
210 case InputCommand::DUMP_MAXLAYERS_INVALID:
211 args.push_back(String16("-dump"));
212 args.push_back(String16("-maxlayers"));
213 args.push_back(String16(NUM_LAYERS_INVALID));
214 break;
215 default:
216 ALOGD("Invalid control command");
217 }
218
Dominik Laskowskic2867142019-01-21 11:33:38 -0800219 EXPECT_NO_FATAL_FAILURE(mTimeStats->parseArgs(useProto, args, result));
Yiwei Zhang5434a782018-12-05 18:06:32 -0800220 return result;
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800221}
222
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800223static std::string genLayerName(int32_t layerId) {
224 return (layerId < 0 ? "PopupWindow:b54fcd1#0" : "com.dummy#") + std::to_string(layerId);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800225}
226
227void TimeStatsTest::setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts) {
228 switch (type) {
229 case TimeStamp::POST:
230 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPostTime(id, frameNumber, genLayerName(id), ts));
231 break;
232 case TimeStamp::ACQUIRE:
233 ASSERT_NO_FATAL_FAILURE(mTimeStats->setAcquireTime(id, frameNumber, ts));
234 break;
235 case TimeStamp::ACQUIRE_FENCE:
236 ASSERT_NO_FATAL_FAILURE(
237 mTimeStats->setAcquireFence(id, frameNumber, std::make_shared<FenceTime>(ts)));
238 break;
239 case TimeStamp::LATCH:
240 ASSERT_NO_FATAL_FAILURE(mTimeStats->setLatchTime(id, frameNumber, ts));
241 break;
242 case TimeStamp::DESIRED:
243 ASSERT_NO_FATAL_FAILURE(mTimeStats->setDesiredTime(id, frameNumber, ts));
244 break;
245 case TimeStamp::PRESENT:
246 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPresentTime(id, frameNumber, ts));
247 break;
248 case TimeStamp::PRESENT_FENCE:
249 ASSERT_NO_FATAL_FAILURE(
250 mTimeStats->setPresentFence(id, frameNumber, std::make_shared<FenceTime>(ts)));
251 break;
252 default:
253 ALOGD("Invalid timestamp type");
254 }
255}
256
257int32_t TimeStatsTest::genRandomInt32(int32_t begin, int32_t end) {
258 std::uniform_int_distribution<int32_t> distr(begin, end);
259 return distr(mRandomEngine);
260}
261
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000262TEST_F(TimeStatsTest, disabledByDefault) {
263 ASSERT_FALSE(mTimeStats->isEnabled());
264}
265
Tej Singh38a4b212020-03-13 19:04:51 -0700266TEST_F(TimeStatsTest, setsCallbacksAfterBoot) {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000267 mTimeStats->onBootFinished();
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800268 EXPECT_THAT(mDelegate->mAtomTags,
269 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
270 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
271}
272
Tej Singh38a4b212020-03-13 19:04:51 -0700273TEST_F(TimeStatsTest, clearsCallbacksOnDestruction) {
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800274 EXPECT_CALL(*mDelegate,
Tej Singh38a4b212020-03-13 19:04:51 -0700275 clearStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO));
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800276 EXPECT_CALL(*mDelegate,
Tej Singh38a4b212020-03-13 19:04:51 -0700277 clearStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO));
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800278 mTimeStats.reset();
Alec Mourib3885ad2019-09-06 17:08:55 -0700279}
280
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800281TEST_F(TimeStatsTest, canEnableAndDisableTimeStats) {
282 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
283 ASSERT_TRUE(mTimeStats->isEnabled());
284
285 EXPECT_TRUE(inputCommand(InputCommand::DISABLE, FMT_STRING).empty());
286 ASSERT_FALSE(mTimeStats->isEnabled());
287}
288
289TEST_F(TimeStatsTest, canIncreaseGlobalStats) {
290 constexpr size_t TOTAL_FRAMES = 5;
291 constexpr size_t MISSED_FRAMES = 4;
292 constexpr size_t CLIENT_COMPOSITION_FRAMES = 3;
293
294 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
295
296 for (size_t i = 0; i < TOTAL_FRAMES; i++) {
297 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementTotalFrames());
298 }
299 for (size_t i = 0; i < MISSED_FRAMES; i++) {
300 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementMissedFrames());
301 }
302 for (size_t i = 0; i < CLIENT_COMPOSITION_FRAMES; i++) {
303 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionFrames());
304 }
305
306 SFTimeStatsGlobalProto globalProto;
307 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
308
309 ASSERT_TRUE(globalProto.has_total_frames());
310 EXPECT_EQ(TOTAL_FRAMES, globalProto.total_frames());
311 ASSERT_TRUE(globalProto.has_missed_frames());
312 EXPECT_EQ(MISSED_FRAMES, globalProto.missed_frames());
313 ASSERT_TRUE(globalProto.has_client_composition_frames());
314 EXPECT_EQ(CLIENT_COMPOSITION_FRAMES, globalProto.client_composition_frames());
315}
316
Alec Mouri91f6df32020-01-30 08:48:58 -0800317TEST_F(TimeStatsTest, canIncreaseLateAcquireFrames) {
318 // this stat is not in the proto so verify by checking the string dump
319 constexpr size_t LATE_ACQUIRE_FRAMES = 2;
320
321 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
322
323 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
324 for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) {
325 mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire);
326 }
327 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
328
329 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
330 const std::string expectedResult = "lateAcquireFrames = " + std::to_string(LATE_ACQUIRE_FRAMES);
331 EXPECT_THAT(result, HasSubstr(expectedResult));
332}
333
334TEST_F(TimeStatsTest, canIncreaseBadDesiredPresent) {
335 // this stat is not in the proto so verify by checking the string dump
336 constexpr size_t BAD_DESIRED_PRESENT_FRAMES = 2;
337
338 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
339
340 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
341 for (size_t i = 0; i < BAD_DESIRED_PRESENT_FRAMES; i++) {
342 mTimeStats->incrementBadDesiredPresent(LAYER_ID_0);
343 }
344 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
345
346 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
347 const std::string expectedResult =
348 "badDesiredPresentFrames = " + std::to_string(BAD_DESIRED_PRESENT_FRAMES);
349 EXPECT_THAT(result, HasSubstr(expectedResult));
350}
351
Vishnu Nair9b079a22020-01-21 14:36:08 -0800352TEST_F(TimeStatsTest, canIncreaseClientCompositionReusedFrames) {
353 // this stat is not in the proto so verify by checking the string dump
354 constexpr size_t CLIENT_COMPOSITION_REUSED_FRAMES = 2;
355
356 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
357 for (size_t i = 0; i < CLIENT_COMPOSITION_REUSED_FRAMES; i++) {
358 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionReusedFrames());
359 }
360
361 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
362 const std::string expectedResult =
363 "clientCompositionReusedFrames = " + std::to_string(CLIENT_COMPOSITION_REUSED_FRAMES);
364 EXPECT_THAT(result, HasSubstr(expectedResult));
365}
366
Alec Mouri8de697e2020-03-19 10:52:01 -0700367TEST_F(TimeStatsTest, canIncreaseRefreshRateSwitches) {
368 // this stat is not in the proto so verify by checking the string dump
369 constexpr size_t REFRESH_RATE_SWITCHES = 2;
370
371 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
372 for (size_t i = 0; i < REFRESH_RATE_SWITCHES; i++) {
373 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
374 }
375
376 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
377 const std::string expectedResult =
378 "refreshRateSwitches = " + std::to_string(REFRESH_RATE_SWITCHES);
379 EXPECT_THAT(result, HasSubstr(expectedResult));
380}
381
Alec Mouri8f7a0102020-04-15 12:11:10 -0700382TEST_F(TimeStatsTest, canIncreaseCompositionStrategyChanges) {
383 // this stat is not in the proto so verify by checking the string dump
384 constexpr size_t COMPOSITION_STRATEGY_CHANGES = 2;
385
386 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
387 for (size_t i = 0; i < COMPOSITION_STRATEGY_CHANGES; i++) {
388 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementCompositionStrategyChanges());
389 }
390
391 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
392 const std::string expectedResult =
393 "compositionStrategyChanges = " + std::to_string(COMPOSITION_STRATEGY_CHANGES);
394 EXPECT_THAT(result, HasSubstr(expectedResult));
395}
396
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800397TEST_F(TimeStatsTest, canAverageFrameDuration) {
398 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
Peiyong Lin65248e02020-04-18 21:15:07 -0700399 mTimeStats->setPowerMode(PowerMode::ON);
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800400 mTimeStats
401 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
402 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
403 .count());
404 mTimeStats
405 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
406 std::chrono::duration_cast<std::chrono::nanoseconds>(16ms)
407 .count());
408
409 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
410 EXPECT_THAT(result, HasSubstr("averageFrameDuration = 10.000 ms"));
411}
412
413TEST_F(TimeStatsTest, canAverageRenderEngineTimings) {
414 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
415 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms)
416 .count(),
417 std::make_shared<FenceTime>(
418 std::chrono::duration_cast<
419 std::chrono::nanoseconds>(3ms)
420 .count()));
421
422 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(4ms)
423 .count(),
424 std::chrono::duration_cast<std::chrono::nanoseconds>(8ms)
425 .count());
426
427 // Push a dummy present fence to trigger flushing the RenderEngine timings.
Peiyong Lin65248e02020-04-18 21:15:07 -0700428 mTimeStats->setPowerMode(PowerMode::ON);
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800429 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(
430 std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count()));
431
432 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
433 EXPECT_THAT(result, HasSubstr("averageRenderEngineTiming = 3.000 ms"));
434}
435
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800436TEST_F(TimeStatsTest, canInsertGlobalPresentToPresent) {
437 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
438
439 ASSERT_NO_FATAL_FAILURE(
440 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(1000000)));
441 ASSERT_NO_FATAL_FAILURE(
442 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(2000000)));
443
Peiyong Lin65248e02020-04-18 21:15:07 -0700444 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::ON));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800445 ASSERT_NO_FATAL_FAILURE(
446 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000)));
447 ASSERT_NO_FATAL_FAILURE(
448 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000)));
449
Peiyong Lin65248e02020-04-18 21:15:07 -0700450 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::OFF));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800451 ASSERT_NO_FATAL_FAILURE(
452 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(6000000)));
453 ASSERT_NO_FATAL_FAILURE(
454 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(8000000)));
455
456 SFTimeStatsGlobalProto globalProto;
457 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
458
459 ASSERT_EQ(1, globalProto.present_to_present_size());
460 const SFTimeStatsHistogramBucketProto& histogramProto = globalProto.present_to_present().Get(0);
461 EXPECT_EQ(1, histogramProto.frame_count());
462 EXPECT_EQ(2, histogramProto.time_millis());
463}
464
Alec Mouri9519bf12019-11-15 16:54:44 -0800465TEST_F(TimeStatsTest, canInsertGlobalFrameDuration) {
466 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
467
Peiyong Lin65248e02020-04-18 21:15:07 -0700468 mTimeStats->setPowerMode(PowerMode::OFF);
Alec Mouri9519bf12019-11-15 16:54:44 -0800469 mTimeStats
470 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
471 std::chrono::duration_cast<std::chrono::nanoseconds>(5ms)
472 .count());
Peiyong Lin65248e02020-04-18 21:15:07 -0700473 mTimeStats->setPowerMode(PowerMode::ON);
Alec Mouri9519bf12019-11-15 16:54:44 -0800474 mTimeStats
475 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(3ms).count(),
476 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
477 .count());
478
479 SFTimeStatsGlobalProto globalProto;
480 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
481
482 ASSERT_EQ(1, globalProto.frame_duration_size());
483 const SFTimeStatsHistogramBucketProto& histogramProto = globalProto.frame_duration().Get(0);
484 EXPECT_EQ(1, histogramProto.frame_count());
485 EXPECT_EQ(3, histogramProto.time_millis());
486}
487
Alec Mourie4034bb2019-11-19 12:45:54 -0800488TEST_F(TimeStatsTest, canInsertGlobalRenderEngineTiming) {
489 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
490
Alec Mourie4034bb2019-11-19 12:45:54 -0800491 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms)
492 .count(),
493 std::make_shared<FenceTime>(
494 std::chrono::duration_cast<
495 std::chrono::nanoseconds>(3ms)
496 .count()));
497
498 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(4ms)
499 .count(),
500 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
501 .count());
502
503 // First verify that flushing RenderEngine durations did not occur yet.
504 SFTimeStatsGlobalProto preFlushProto;
505 ASSERT_TRUE(preFlushProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
506 ASSERT_EQ(0, preFlushProto.render_engine_timing_size());
507
508 // Push a dummy present fence to trigger flushing the RenderEngine timings.
Peiyong Lin65248e02020-04-18 21:15:07 -0700509 mTimeStats->setPowerMode(PowerMode::ON);
Alec Mourie4034bb2019-11-19 12:45:54 -0800510 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(
511 std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count()));
512
513 // Now we can verify that RenderEngine durations were flushed now.
514 SFTimeStatsGlobalProto postFlushProto;
515 ASSERT_TRUE(postFlushProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
516
517 ASSERT_EQ(1, postFlushProto.render_engine_timing_size());
518 const SFTimeStatsHistogramBucketProto& histogramProto =
519 postFlushProto.render_engine_timing().Get(0);
520 EXPECT_EQ(2, histogramProto.frame_count());
521 EXPECT_EQ(2, histogramProto.time_millis());
522}
523
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800524TEST_F(TimeStatsTest, canInsertOneLayerTimeStats) {
525 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
526
527 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
528 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
529
530 SFTimeStatsGlobalProto globalProto;
531 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
532
533 ASSERT_EQ(1, globalProto.stats_size());
534 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
535 ASSERT_TRUE(layerProto.has_layer_name());
536 EXPECT_EQ(genLayerName(LAYER_ID_0), layerProto.layer_name());
537 ASSERT_TRUE(layerProto.has_total_frames());
538 EXPECT_EQ(1, layerProto.total_frames());
539 ASSERT_EQ(6, layerProto.deltas_size());
540 for (const SFTimeStatsDeltaProto& deltaProto : layerProto.deltas()) {
541 ASSERT_EQ(1, deltaProto.histograms_size());
542 const SFTimeStatsHistogramBucketProto& histogramProto = deltaProto.histograms().Get(0);
543 EXPECT_EQ(1, histogramProto.frame_count());
544 if ("post2acquire" == deltaProto.delta_name()) {
545 EXPECT_EQ(1, histogramProto.time_millis());
546 } else if ("post2present" == deltaProto.delta_name()) {
547 EXPECT_EQ(4, histogramProto.time_millis());
548 } else if ("acquire2present" == deltaProto.delta_name()) {
549 EXPECT_EQ(3, histogramProto.time_millis());
550 } else if ("latch2present" == deltaProto.delta_name()) {
551 EXPECT_EQ(2, histogramProto.time_millis());
552 } else if ("desired2present" == deltaProto.delta_name()) {
553 EXPECT_EQ(1, histogramProto.time_millis());
554 } else if ("present2present" == deltaProto.delta_name()) {
555 EXPECT_EQ(1, histogramProto.time_millis());
556 } else {
557 FAIL() << "Unknown delta_name: " << deltaProto.delta_name();
558 }
559 }
560}
561
562TEST_F(TimeStatsTest, canNotInsertInvalidLayerNameTimeStats) {
563 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
564
565 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_INVALID, 1, 1000000);
566 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_INVALID, 2, 2000000);
567
568 SFTimeStatsGlobalProto globalProto;
569 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
570
571 ASSERT_EQ(0, globalProto.stats_size());
572}
573
574TEST_F(TimeStatsTest, canInsertMultipleLayersTimeStats) {
575 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
576
577 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
578 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 1000000);
579 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
580 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 2000000);
581
582 SFTimeStatsGlobalProto globalProto;
583 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
584
585 EXPECT_EQ(2, globalProto.stats_size());
586}
587
588TEST_F(TimeStatsTest, canInsertUnorderedLayerTimeStats) {
589 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
590
591 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
592 insertTimeRecord(UNORDERED_SEQUENCE, LAYER_ID_0, 2, 2000000);
593
594 SFTimeStatsGlobalProto globalProto;
595 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
596
597 ASSERT_EQ(1, globalProto.stats_size());
598 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
599 ASSERT_TRUE(layerProto.has_layer_name());
600 EXPECT_EQ(genLayerName(LAYER_ID_0), layerProto.layer_name());
601 ASSERT_TRUE(layerProto.has_total_frames());
602 EXPECT_EQ(1, layerProto.total_frames());
603 ASSERT_EQ(6, layerProto.deltas_size());
604 for (const SFTimeStatsDeltaProto& deltaProto : layerProto.deltas()) {
605 ASSERT_EQ(1, deltaProto.histograms_size());
606 const SFTimeStatsHistogramBucketProto& histogramProto = deltaProto.histograms().Get(0);
607 EXPECT_EQ(1, histogramProto.frame_count());
608 if ("post2acquire" == deltaProto.delta_name()) {
609 EXPECT_EQ(0, histogramProto.time_millis());
610 } else if ("post2present" == deltaProto.delta_name()) {
611 EXPECT_EQ(2, histogramProto.time_millis());
612 } else if ("acquire2present" == deltaProto.delta_name()) {
613 EXPECT_EQ(2, histogramProto.time_millis());
614 } else if ("latch2present" == deltaProto.delta_name()) {
615 EXPECT_EQ(2, histogramProto.time_millis());
616 } else if ("desired2present" == deltaProto.delta_name()) {
617 EXPECT_EQ(1, histogramProto.time_millis());
618 } else if ("present2present" == deltaProto.delta_name()) {
619 EXPECT_EQ(1, histogramProto.time_millis());
620 } else {
621 FAIL() << "Unknown delta_name: " << deltaProto.delta_name();
622 }
623 }
624}
625
Alec Mourifb571ea2019-01-24 18:42:10 -0800626TEST_F(TimeStatsTest, recordRefreshRateNewConfigs) {
627 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
628
629 uint32_t fpsOne = 30;
630 uint32_t fpsTwo = 90;
631 uint64_t millisOne = 5000;
632 uint64_t millisTwo = 7000;
633
634 mTimeStats->recordRefreshRate(fpsOne, ms2ns(millisOne));
635 mTimeStats->recordRefreshRate(fpsTwo, ms2ns(millisTwo));
636
637 SFTimeStatsGlobalProto globalProto;
638 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
639
640 SFTimeStatsDisplayConfigBucketProto expectedBucketOne;
641 SFTimeStatsDisplayConfigProto* expectedConfigOne = expectedBucketOne.mutable_config();
642 expectedConfigOne->set_fps(fpsOne);
643 expectedBucketOne.set_duration_millis(millisOne);
644
645 SFTimeStatsDisplayConfigBucketProto expectedBucketTwo;
646 SFTimeStatsDisplayConfigProto* expectedConfigTwo = expectedBucketTwo.mutable_config();
647 expectedConfigTwo->set_fps(fpsTwo);
648 expectedBucketTwo.set_duration_millis(millisTwo);
649
650 EXPECT_THAT(globalProto.display_config_stats(), SizeIs(2));
651
652 std::unordered_set<uint32_t> seen_fps;
653 for (const auto& bucket : globalProto.display_config_stats()) {
654 seen_fps.emplace(bucket.config().fps());
655 if (fpsOne == bucket.config().fps()) {
656 EXPECT_EQ(millisOne, bucket.duration_millis());
657 } else if (fpsTwo == bucket.config().fps()) {
658 EXPECT_EQ(millisTwo, bucket.duration_millis());
659 } else {
660 FAIL() << "Unknown fps: " << bucket.config().fps();
661 }
662 }
663 EXPECT_THAT(seen_fps, UnorderedElementsAre(fpsOne, fpsTwo));
664}
665
666TEST_F(TimeStatsTest, recordRefreshRateUpdatesConfig) {
667 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
668
669 uint32_t fps = 30;
670 uint64_t millisOne = 5000;
671 uint64_t millisTwo = 7000;
672
673 mTimeStats->recordRefreshRate(fps, ms2ns(millisOne));
674 mTimeStats->recordRefreshRate(fps, ms2ns(millisTwo));
675
676 SFTimeStatsGlobalProto globalProto;
677 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
678 EXPECT_THAT(globalProto.display_config_stats(), SizeIs(1));
679 EXPECT_EQ(fps, globalProto.display_config_stats().Get(0).config().fps());
680 EXPECT_EQ(millisOne + millisTwo, globalProto.display_config_stats().Get(0).duration_millis());
681}
682
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800683TEST_F(TimeStatsTest, canRemoveTimeRecord) {
684 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
685
686 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
687 insertTimeRecord(INCOMPLETE_SEQUENCE, LAYER_ID_0, 2, 2000000);
688 ASSERT_NO_FATAL_FAILURE(mTimeStats->removeTimeRecord(0, 2));
689 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000);
690
691 SFTimeStatsGlobalProto globalProto;
692 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
693
694 ASSERT_EQ(1, globalProto.stats_size());
695 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
696 ASSERT_TRUE(layerProto.has_total_frames());
697 EXPECT_EQ(1, layerProto.total_frames());
698}
699
700TEST_F(TimeStatsTest, canRecoverFromIncompleteTimeRecordError) {
701 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
702
703 uint64_t frameNumber = 1;
704 nsecs_t ts = 1000000;
705 insertTimeRecord(INCOMPLETE_SEQUENCE, LAYER_ID_0, 1, 1000000);
Alec Mourifb571ea2019-01-24 18:42:10 -0800706 for (size_t i = 0; i < impl::TimeStats::MAX_NUM_TIME_RECORDS + 2; i++) {
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800707 frameNumber++;
708 ts += 1000000;
709 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, frameNumber, ts);
710 }
711
712 SFTimeStatsGlobalProto globalProto;
713 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
714
715 ASSERT_EQ(1, globalProto.stats_size());
716 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
717 ASSERT_TRUE(layerProto.has_total_frames());
718 EXPECT_EQ(1, layerProto.total_frames());
719}
720
721TEST_F(TimeStatsTest, layerTimeStatsOnDestroy) {
722 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
723
724 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
725 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
726 ASSERT_NO_FATAL_FAILURE(mTimeStats->onDestroy(0));
727 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000);
728
729 SFTimeStatsGlobalProto globalProto;
730 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
731
732 ASSERT_EQ(1, globalProto.stats_size());
733 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
734 ASSERT_TRUE(layerProto.has_total_frames());
735 EXPECT_EQ(1, layerProto.total_frames());
736}
737
738TEST_F(TimeStatsTest, canClearTimeStats) {
739 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
740
741 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementTotalFrames());
742 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementMissedFrames());
743 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionFrames());
Peiyong Lin65248e02020-04-18 21:15:07 -0700744 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::ON));
Alec Mouri31ac64a2020-01-09 09:26:22 -0800745
Alec Mouri31ac64a2020-01-09 09:26:22 -0800746 mTimeStats
747 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(3ms).count(),
748 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
749 .count());
750 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(4ms)
751 .count(),
752 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
753 .count());
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800754 ASSERT_NO_FATAL_FAILURE(
755 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(1000000)));
756 ASSERT_NO_FATAL_FAILURE(
757 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(2000000)));
758 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
759 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
760
761 EXPECT_TRUE(inputCommand(InputCommand::CLEAR, FMT_STRING).empty());
762
763 SFTimeStatsGlobalProto globalProto;
764 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
765
766 EXPECT_EQ(0, globalProto.total_frames());
767 EXPECT_EQ(0, globalProto.missed_frames());
768 EXPECT_EQ(0, globalProto.client_composition_frames());
769 EXPECT_EQ(0, globalProto.present_to_present_size());
Alec Mouri31ac64a2020-01-09 09:26:22 -0800770 EXPECT_EQ(0, globalProto.frame_duration_size());
771 EXPECT_EQ(0, globalProto.render_engine_timing_size());
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800772 EXPECT_EQ(0, globalProto.stats_size());
773}
774
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800775TEST_F(TimeStatsTest, canClearDumpOnlyTimeStats) {
776 // These stats are not in the proto so verify by checking the string dump.
Vishnu Nair9b079a22020-01-21 14:36:08 -0800777 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
778 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionReusedFrames());
Alec Mouri8de697e2020-03-19 10:52:01 -0700779 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
Alec Mouri8f7a0102020-04-15 12:11:10 -0700780 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementCompositionStrategyChanges());
Peiyong Lin65248e02020-04-18 21:15:07 -0700781 mTimeStats->setPowerMode(PowerMode::ON);
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800782 mTimeStats
783 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
784 std::chrono::duration_cast<std::chrono::nanoseconds>(5ms)
785 .count());
786 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(4ms)
787 .count(),
788 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
789 .count());
790 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(
791 std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count()));
Vishnu Nair9b079a22020-01-21 14:36:08 -0800792 EXPECT_TRUE(inputCommand(InputCommand::CLEAR, FMT_STRING).empty());
793
794 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
795 EXPECT_THAT(result, HasSubstr("clientCompositionReusedFrames = 0"));
Alec Mouri8de697e2020-03-19 10:52:01 -0700796 EXPECT_THAT(result, HasSubstr("refreshRateSwitches = 0"));
Alec Mouri8f7a0102020-04-15 12:11:10 -0700797 EXPECT_THAT(result, HasSubstr("compositionStrategyChanges = 0"));
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800798 EXPECT_THAT(result, HasSubstr("averageFrameDuration = 0.000 ms"));
799 EXPECT_THAT(result, HasSubstr("averageRenderEngineTiming = 0.000 ms"));
Vishnu Nair9b079a22020-01-21 14:36:08 -0800800}
801
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800802TEST_F(TimeStatsTest, canDumpWithMaxLayers) {
803 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
804
805 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
806 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 1000000);
807 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
808 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 2000000);
809 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 3, 2000000);
810
811 SFTimeStatsGlobalProto globalProto;
812 ASSERT_TRUE(
813 globalProto.ParseFromString(inputCommand(InputCommand::DUMP_MAXLAYERS_1, FMT_PROTO)));
814
815 ASSERT_EQ(1, globalProto.stats_size());
816 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
817 ASSERT_TRUE(layerProto.has_layer_name());
818 EXPECT_EQ(genLayerName(LAYER_ID_1), layerProto.layer_name());
819 ASSERT_TRUE(layerProto.has_total_frames());
820 EXPECT_EQ(2, layerProto.total_frames());
821}
822
823TEST_F(TimeStatsTest, canDumpWithInvalidMaxLayers) {
824 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
825
826 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
827 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
828
829 SFTimeStatsGlobalProto globalProto;
830 ASSERT_TRUE(globalProto.ParseFromString(
831 inputCommand(InputCommand::DUMP_MAXLAYERS_INVALID, FMT_PROTO)));
832
833 ASSERT_EQ(0, globalProto.stats_size());
834}
835
Alec Mouri37384342020-01-02 17:23:37 -0800836namespace {
837std::string buildExpectedHistogramBytestring(const std::vector<int32_t>& times,
838 const std::vector<int32_t>& frameCounts) {
839 util::ProtoOutputStream proto;
840 for (int i = 0; i < times.size(); i++) {
841 ALOGE("Writing time: %d", times[i]);
842 proto.write(util::FIELD_TYPE_INT32 | util::FIELD_COUNT_REPEATED | 1 /* field id */,
843 (int32_t)times[i]);
844 ALOGE("Writing count: %d", frameCounts[i]);
845 proto.write(util::FIELD_TYPE_INT64 | util::FIELD_COUNT_REPEATED | 2 /* field id */,
846 (int64_t)frameCounts[i]);
847 }
848 std::string byteString;
849 proto.serializeToString(&byteString);
850 return byteString;
851}
852
853std::string dumpByteStringHex(const std::string& str) {
854 std::stringstream ss;
855 ss << std::hex;
856 for (const char& c : str) {
857 ss << (int)c << " ";
858 }
859
860 return ss.str();
861}
862
863} // namespace
864
865MATCHER_P2(BytesEq, bytes, size, "") {
866 std::string expected;
867 expected.append((const char*)bytes, size);
868 std::string actual;
869 actual.append((const char*)arg, size);
870
871 *result_listener << "Bytes are not equal! \n";
872 *result_listener << "size: " << size << "\n";
873 *result_listener << "expected: " << dumpByteStringHex(expected).c_str() << "\n";
874 *result_listener << "actual: " << dumpByteStringHex(actual).c_str() << "\n";
875
876 return expected == actual;
877}
878
Alec Mouridfad9002020-02-12 17:49:09 -0800879TEST_F(TimeStatsTest, globalStatsCallback) {
880 constexpr size_t TOTAL_FRAMES = 5;
881 constexpr size_t MISSED_FRAMES = 4;
882 constexpr size_t CLIENT_COMPOSITION_FRAMES = 3;
883 constexpr size_t DISPLAY_EVENT_CONNECTIONS = 14;
884
885 mTimeStats->onBootFinished();
886 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
887
888 for (size_t i = 0; i < TOTAL_FRAMES; i++) {
889 mTimeStats->incrementTotalFrames();
890 }
891 for (size_t i = 0; i < MISSED_FRAMES; i++) {
892 mTimeStats->incrementMissedFrames();
893 }
894 for (size_t i = 0; i < CLIENT_COMPOSITION_FRAMES; i++) {
895 mTimeStats->incrementClientCompositionFrames();
896 }
897
898 mTimeStats->recordDisplayEventConnectionCount(DISPLAY_EVENT_CONNECTIONS);
Peiyong Lin65248e02020-04-18 21:15:07 -0700899 mTimeStats->setPowerMode(PowerMode::ON);
Alec Mouridfad9002020-02-12 17:49:09 -0800900 mTimeStats->recordFrameDuration(1000000, 3000000);
901 mTimeStats->recordRenderEngineDuration(2000000, 4000000);
902 mTimeStats->recordRenderEngineDuration(2000000, std::make_shared<FenceTime>(3000000));
903
904 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000));
905 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
906
907 EXPECT_THAT(mDelegate->mAtomTags,
908 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
909 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
910 EXPECT_NE(nullptr, mDelegate->mCallback);
911 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
912
913 std::string expectedFrameDuration = buildExpectedHistogramBytestring({2}, {1});
914 std::string expectedRenderEngineTiming = buildExpectedHistogramBytestring({1, 2}, {1, 1});
915
916 {
917 InSequence seq;
918 EXPECT_CALL(*mDelegate,
919 statsEventSetAtomId(mDelegate->mEvent,
920 android::util::SURFACEFLINGER_STATS_GLOBAL_INFO));
921 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, TOTAL_FRAMES));
922 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, MISSED_FRAMES));
923 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, CLIENT_COMPOSITION_FRAMES));
924 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, _));
925 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 2));
926 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, DISPLAY_EVENT_CONNECTIONS));
927 EXPECT_CALL(*mDelegate,
928 statsEventWriteByteArray(mDelegate->mEvent,
929 BytesEq((const uint8_t*)expectedFrameDuration.c_str(),
930 expectedFrameDuration.size()),
931 expectedFrameDuration.size()));
932 EXPECT_CALL(*mDelegate,
933 statsEventWriteByteArray(mDelegate->mEvent,
934 BytesEq((const uint8_t*)
935 expectedRenderEngineTiming.c_str(),
936 expectedRenderEngineTiming.size()),
937 expectedRenderEngineTiming.size()));
938 EXPECT_CALL(*mDelegate, statsEventBuild(mDelegate->mEvent));
939 }
940 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
941 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
942 mDelegate->mCookie));
943
944 SFTimeStatsGlobalProto globalProto;
945 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
946
947 EXPECT_EQ(0, globalProto.total_frames());
948 EXPECT_EQ(0, globalProto.missed_frames());
949 EXPECT_EQ(0, globalProto.client_composition_frames());
950 EXPECT_EQ(0, globalProto.present_to_present_size());
951}
952
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -0800953TEST_F(TimeStatsTest, layerStatsCallback_pullsAllAndClears) {
954 constexpr size_t LATE_ACQUIRE_FRAMES = 2;
955 constexpr size_t BAD_DESIRED_PRESENT_FRAMES = 3;
Alec Mouri37384342020-01-02 17:23:37 -0800956 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
957
958 mTimeStats->onBootFinished();
959
960 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -0800961 for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) {
962 mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire);
963 }
964 for (size_t i = 0; i < BAD_DESIRED_PRESENT_FRAMES; i++) {
965 mTimeStats->incrementBadDesiredPresent(LAYER_ID_0);
966 }
Alec Mouri37384342020-01-02 17:23:37 -0800967 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
968
969 EXPECT_THAT(mDelegate->mAtomTags,
970 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
971 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
972 EXPECT_NE(nullptr, mDelegate->mCallback);
973 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
974
975 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1}, {1});
976 std::string expectedPostToPresent = buildExpectedHistogramBytestring({4}, {1});
977 std::string expectedAcquireToPresent = buildExpectedHistogramBytestring({3}, {1});
978 std::string expectedLatchToPresent = buildExpectedHistogramBytestring({2}, {1});
979 std::string expectedDesiredToPresent = buildExpectedHistogramBytestring({1}, {1});
980 std::string expectedPostToAcquire = buildExpectedHistogramBytestring({1}, {1});
981 {
982 InSequence seq;
983 EXPECT_CALL(*mDelegate,
984 statsEventSetAtomId(mDelegate->mEvent,
985 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
986 EXPECT_CALL(*mDelegate,
987 statsEventWriteString8(mDelegate->mEvent,
988 StrEq(genLayerName(LAYER_ID_0).c_str())));
989 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 1));
990 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 0));
991 EXPECT_CALL(*mDelegate,
992 statsEventWriteByteArray(mDelegate->mEvent,
993 BytesEq((const uint8_t*)
994 expectedPresentToPresent.c_str(),
995 expectedPresentToPresent.size()),
996 expectedPresentToPresent.size()));
997 EXPECT_CALL(*mDelegate,
998 statsEventWriteByteArray(mDelegate->mEvent,
999 BytesEq((const uint8_t*)expectedPostToPresent.c_str(),
1000 expectedPostToPresent.size()),
1001 expectedPostToPresent.size()));
1002 EXPECT_CALL(*mDelegate,
1003 statsEventWriteByteArray(mDelegate->mEvent,
1004 BytesEq((const uint8_t*)
1005 expectedAcquireToPresent.c_str(),
1006 expectedAcquireToPresent.size()),
1007 expectedAcquireToPresent.size()));
1008 EXPECT_CALL(*mDelegate,
1009 statsEventWriteByteArray(mDelegate->mEvent,
1010 BytesEq((const uint8_t*)expectedLatchToPresent.c_str(),
1011 expectedLatchToPresent.size()),
1012 expectedLatchToPresent.size()));
1013 EXPECT_CALL(*mDelegate,
1014 statsEventWriteByteArray(mDelegate->mEvent,
1015 BytesEq((const uint8_t*)
1016 expectedDesiredToPresent.c_str(),
1017 expectedDesiredToPresent.size()),
1018 expectedDesiredToPresent.size()));
1019 EXPECT_CALL(*mDelegate,
1020 statsEventWriteByteArray(mDelegate->mEvent,
1021 BytesEq((const uint8_t*)expectedPostToAcquire.c_str(),
1022 expectedPostToAcquire.size()),
1023 expectedPostToAcquire.size()));
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -08001024 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, LATE_ACQUIRE_FRAMES));
1025 EXPECT_CALL(*mDelegate,
1026 statsEventWriteInt64(mDelegate->mEvent, BAD_DESIRED_PRESENT_FRAMES));
Alec Mouri37384342020-01-02 17:23:37 -08001027 EXPECT_CALL(*mDelegate, statsEventBuild(mDelegate->mEvent));
1028 }
Tej Singh2a457b62020-01-31 16:16:10 -08001029 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001030 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1031 mDelegate->mCookie));
1032
1033 SFTimeStatsGlobalProto globalProto;
1034 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
1035
1036 EXPECT_EQ(0, globalProto.stats_size());
1037}
1038
1039TEST_F(TimeStatsTest, layerStatsCallback_pullsMultipleLayers) {
1040 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1041
1042 mTimeStats->onBootFinished();
1043
1044 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1045 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1046 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 2000000);
1047 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 3000000);
1048
1049 EXPECT_THAT(mDelegate->mAtomTags,
1050 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1051 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1052 EXPECT_NE(nullptr, mDelegate->mCallback);
1053 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1054
1055 EXPECT_CALL(*mDelegate,
1056 statsEventSetAtomId(mDelegate->mEvent,
1057 android::util::SURFACEFLINGER_STATS_LAYER_INFO))
1058 .Times(2);
1059 EXPECT_CALL(*mDelegate,
1060 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_0).c_str())));
1061 EXPECT_CALL(*mDelegate,
1062 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_1).c_str())));
Tej Singh2a457b62020-01-31 16:16:10 -08001063 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001064 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1065 mDelegate->mCookie));
1066}
1067
1068TEST_F(TimeStatsTest, layerStatsCallback_pullsMultipleBuckets) {
1069 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1070
1071 mTimeStats->onBootFinished();
1072
1073 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1074 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1075 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 4000000);
1076 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 5000000);
1077
Tej Singh38a4b212020-03-13 19:04:51 -07001078 // Now make sure that TimeStats flushes global stats to set the callback.
Peiyong Lin65248e02020-04-18 21:15:07 -07001079 mTimeStats->setPowerMode(PowerMode::ON);
Alec Mouri37384342020-01-02 17:23:37 -08001080 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000));
1081 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
1082 EXPECT_THAT(mDelegate->mAtomTags,
1083 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1084 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1085 EXPECT_NE(nullptr, mDelegate->mCallback);
1086 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1087
1088 EXPECT_THAT(mDelegate->mAtomTags,
1089 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1090 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1091 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1, 2}, {2, 1});
1092 {
1093 InSequence seq;
1094 EXPECT_CALL(*mDelegate,
1095 statsEventWriteByteArray(mDelegate->mEvent,
1096 BytesEq((const uint8_t*)
1097 expectedPresentToPresent.c_str(),
1098 expectedPresentToPresent.size()),
1099 expectedPresentToPresent.size()));
1100 EXPECT_CALL(*mDelegate, statsEventWriteByteArray(mDelegate->mEvent, _, _))
1101 .Times(AnyNumber());
1102 }
Tej Singh2a457b62020-01-31 16:16:10 -08001103 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001104 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1105 mDelegate->mCookie));
1106}
1107
1108TEST_F(TimeStatsTest, layerStatsCallback_limitsHistogramBuckets) {
1109 mDelegate = new FakeStatsEventDelegate;
1110 mTimeStats =
1111 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate),
1112 std::nullopt, 1);
1113 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1114
1115 mTimeStats->onBootFinished();
1116
1117 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1118 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1119 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 4000000);
1120 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 5000000);
1121
1122 EXPECT_THAT(mDelegate->mAtomTags,
1123 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1124 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1125 EXPECT_NE(nullptr, mDelegate->mCallback);
1126 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1127
1128 EXPECT_THAT(mDelegate->mAtomTags,
1129 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1130 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1131 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1}, {2});
1132 {
1133 InSequence seq;
1134 EXPECT_CALL(*mDelegate,
1135 statsEventWriteByteArray(mDelegate->mEvent,
1136 BytesEq((const uint8_t*)
1137 expectedPresentToPresent.c_str(),
1138 expectedPresentToPresent.size()),
1139 expectedPresentToPresent.size()));
1140 EXPECT_CALL(*mDelegate, statsEventWriteByteArray(mDelegate->mEvent, _, _))
1141 .Times(AnyNumber());
1142 }
Tej Singh2a457b62020-01-31 16:16:10 -08001143 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001144 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1145 mDelegate->mCookie));
1146}
1147
1148TEST_F(TimeStatsTest, layerStatsCallback_limitsLayers) {
1149 mDelegate = new FakeStatsEventDelegate;
1150 mTimeStats =
1151 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate), 1,
1152 std::nullopt);
1153 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1154
1155 mTimeStats->onBootFinished();
1156
1157 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1158 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1159 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 2000000);
1160 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 3000000);
1161 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 4, 5000000);
1162
1163 EXPECT_THAT(mDelegate->mAtomTags,
1164 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1165 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1166 EXPECT_NE(nullptr, mDelegate->mCallback);
1167 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1168
1169 EXPECT_CALL(*mDelegate,
1170 statsEventSetAtomId(mDelegate->mEvent,
1171 android::util::SURFACEFLINGER_STATS_LAYER_INFO))
1172 .Times(1);
1173 EXPECT_CALL(*mDelegate,
1174 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_1).c_str())));
Tej Singh2a457b62020-01-31 16:16:10 -08001175 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001176 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1177 mDelegate->mCookie));
1178}
1179
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001180TEST_F(TimeStatsTest, canSurviveMonkey) {
Lloyd Pique067fe1e2018-12-06 19:44:13 -08001181 if (g_noSlowTests) {
1182 GTEST_SKIP();
1183 }
1184
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001185 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1186
1187 for (size_t i = 0; i < 10000000; ++i) {
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001188 const int32_t layerId = genRandomInt32(-1, 10);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001189 const int32_t frameNumber = genRandomInt32(1, 10);
1190 switch (genRandomInt32(0, 100)) {
1191 case 0:
1192 ALOGV("removeTimeRecord");
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001193 ASSERT_NO_FATAL_FAILURE(mTimeStats->removeTimeRecord(layerId, frameNumber));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001194 continue;
1195 case 1:
1196 ALOGV("onDestroy");
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001197 ASSERT_NO_FATAL_FAILURE(mTimeStats->onDestroy(layerId));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001198 continue;
1199 }
1200 TimeStamp type = static_cast<TimeStamp>(genRandomInt32(TIME_STAMP_BEGIN, TIME_STAMP_END));
1201 const int32_t ts = genRandomInt32(1, 1000000000);
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001202 ALOGV("type[%d], layerId[%d], frameNumber[%d], ts[%d]", type, layerId, frameNumber, ts);
1203 setTimeStamp(type, layerId, frameNumber, ts);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001204 }
1205}
1206
1207} // namespace
1208} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001209
1210// TODO(b/129481165): remove the #pragma below and fix conversion issues
1211#pragma clang diagnostic pop // ignored "-Wconversion"