blob: 5de6bace220a38a64e14438417d3dd03302911d2 [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
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080054// clang-format off
55#define FMT_PROTO true
56#define FMT_STRING false
57#define LAYER_ID_0 0
58#define LAYER_ID_1 1
59#define LAYER_ID_INVALID -1
60#define NUM_LAYERS 1
61#define NUM_LAYERS_INVALID "INVALID"
62
63enum InputCommand : int32_t {
64 ENABLE = 0,
65 DISABLE = 1,
66 CLEAR = 2,
67 DUMP_ALL = 3,
68 DUMP_MAXLAYERS_1 = 4,
69 DUMP_MAXLAYERS_INVALID = 5,
70 INPUT_COMMAND_BEGIN = ENABLE,
71 INPUT_COMMAND_END = DUMP_MAXLAYERS_INVALID,
72 INPUT_COMMAND_RANGE = INPUT_COMMAND_END - INPUT_COMMAND_BEGIN + 1,
73};
74
75enum TimeStamp : int32_t {
76 POST = 0,
77 ACQUIRE = 1,
78 ACQUIRE_FENCE = 2,
79 LATCH = 3,
80 DESIRED = 4,
81 PRESENT = 5,
82 PRESENT_FENCE = 6,
83 TIME_STAMP_BEGIN = POST,
84 TIME_STAMP_END = PRESENT,
85 TIME_STAMP_RANGE = TIME_STAMP_END - TIME_STAMP_BEGIN + 1,
86};
87
88static const TimeStamp NORMAL_SEQUENCE[] = {
89 TimeStamp::POST,
90 TimeStamp::ACQUIRE,
91 TimeStamp::LATCH,
92 TimeStamp::DESIRED,
93 TimeStamp::PRESENT,
94};
95
96static const TimeStamp NORMAL_SEQUENCE_2[] = {
97 TimeStamp::POST,
98 TimeStamp::ACQUIRE_FENCE,
99 TimeStamp::LATCH,
100 TimeStamp::DESIRED,
101 TimeStamp::PRESENT_FENCE,
102};
103
104static const TimeStamp UNORDERED_SEQUENCE[] = {
105 TimeStamp::ACQUIRE,
106 TimeStamp::LATCH,
107 TimeStamp::POST,
108 TimeStamp::DESIRED,
109 TimeStamp::PRESENT,
110};
111
112static const TimeStamp INCOMPLETE_SEQUENCE[] = {
113 TimeStamp::POST,
114};
115// clang-format on
116
117class TimeStatsTest : public testing::Test {
118public:
119 TimeStatsTest() {
120 const ::testing::TestInfo* const test_info =
121 ::testing::UnitTest::GetInstance()->current_test_info();
122 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
123 }
124
125 ~TimeStatsTest() {
126 const ::testing::TestInfo* const test_info =
127 ::testing::UnitTest::GetInstance()->current_test_info();
128 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
129 }
130
131 std::string inputCommand(InputCommand cmd, bool useProto);
132
133 void setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts);
134
135 int32_t genRandomInt32(int32_t begin, int32_t end);
136
137 template <size_t N>
138 void insertTimeRecord(const TimeStamp (&sequence)[N], int32_t id, uint64_t frameNumber,
139 nsecs_t ts) {
140 for (size_t i = 0; i < N; i++, ts += 1000000) {
141 setTimeStamp(sequence[i], id, frameNumber, ts);
142 }
143 }
144
145 std::mt19937 mRandomEngine = std::mt19937(std::random_device()());
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000146
147 class FakeStatsEventDelegate : public impl::TimeStats::StatsEventDelegate {
148 public:
149 FakeStatsEventDelegate() = default;
150 ~FakeStatsEventDelegate() override = default;
151
Tej Singh2a457b62020-01-31 16:16:10 -0800152 struct AStatsEvent* addStatsEventToPullData(AStatsEventList*) override {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000153 return mEvent;
154 }
Tej Singh38a4b212020-03-13 19:04:51 -0700155 void setStatsPullAtomCallback(int32_t atom_tag, AStatsManager_PullAtomMetadata*,
156 AStatsManager_PullAtomCallback callback,
157 void* cookie) override {
Alec Mouri37384342020-01-02 17:23:37 -0800158 mAtomTags.push_back(atom_tag);
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000159 mCallback = callback;
160 mCookie = cookie;
161 }
162
Tej Singh2a457b62020-01-31 16:16:10 -0800163 AStatsManager_PullAtomCallbackReturn makePullAtomCallback(int32_t atom_tag, void* cookie) {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000164 return (*mCallback)(atom_tag, nullptr, cookie);
165 }
166
Tej Singh38a4b212020-03-13 19:04:51 -0700167 MOCK_METHOD1(clearStatsPullAtomCallback, void(int32_t));
Tej Singh2a457b62020-01-31 16:16:10 -0800168 MOCK_METHOD2(statsEventSetAtomId, void(AStatsEvent*, uint32_t));
Alec Mouri717bcb62020-02-10 17:07:19 -0800169 MOCK_METHOD2(statsEventWriteInt32, void(AStatsEvent*, int32_t));
Tej Singh2a457b62020-01-31 16:16:10 -0800170 MOCK_METHOD2(statsEventWriteInt64, void(AStatsEvent*, int64_t));
171 MOCK_METHOD2(statsEventWriteString8, void(AStatsEvent*, const char*));
172 MOCK_METHOD3(statsEventWriteByteArray, void(AStatsEvent*, const uint8_t*, size_t));
173 MOCK_METHOD1(statsEventBuild, void(AStatsEvent*));
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000174
Tej Singh2a457b62020-01-31 16:16:10 -0800175 AStatsEvent* mEvent = AStatsEvent_obtain();
Alec Mouri37384342020-01-02 17:23:37 -0800176 std::vector<int32_t> mAtomTags;
Tej Singh2a457b62020-01-31 16:16:10 -0800177 AStatsManager_PullAtomCallback mCallback = nullptr;
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000178 void* mCookie = nullptr;
179 };
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000180 FakeStatsEventDelegate* mDelegate = new FakeStatsEventDelegate;
181 std::unique_ptr<TimeStats> mTimeStats =
Alec Mouri37384342020-01-02 17:23:37 -0800182 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate),
183 std::nullopt, std::nullopt);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800184};
185
186std::string TimeStatsTest::inputCommand(InputCommand cmd, bool useProto) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800187 std::string result;
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800188 Vector<String16> args;
189
190 switch (cmd) {
191 case InputCommand::ENABLE:
192 args.push_back(String16("-enable"));
193 break;
194 case InputCommand::DISABLE:
195 args.push_back(String16("-disable"));
196 break;
197 case InputCommand::CLEAR:
198 args.push_back(String16("-clear"));
199 break;
200 case InputCommand::DUMP_ALL:
201 args.push_back(String16("-dump"));
202 break;
203 case InputCommand::DUMP_MAXLAYERS_1:
204 args.push_back(String16("-dump"));
205 args.push_back(String16("-maxlayers"));
206 args.push_back(String16(std::to_string(NUM_LAYERS).c_str()));
207 break;
208 case InputCommand::DUMP_MAXLAYERS_INVALID:
209 args.push_back(String16("-dump"));
210 args.push_back(String16("-maxlayers"));
211 args.push_back(String16(NUM_LAYERS_INVALID));
212 break;
213 default:
214 ALOGD("Invalid control command");
215 }
216
Dominik Laskowskic2867142019-01-21 11:33:38 -0800217 EXPECT_NO_FATAL_FAILURE(mTimeStats->parseArgs(useProto, args, result));
Yiwei Zhang5434a782018-12-05 18:06:32 -0800218 return result;
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800219}
220
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800221static std::string genLayerName(int32_t layerId) {
222 return (layerId < 0 ? "PopupWindow:b54fcd1#0" : "com.dummy#") + std::to_string(layerId);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800223}
224
225void TimeStatsTest::setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts) {
226 switch (type) {
227 case TimeStamp::POST:
228 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPostTime(id, frameNumber, genLayerName(id), ts));
229 break;
230 case TimeStamp::ACQUIRE:
231 ASSERT_NO_FATAL_FAILURE(mTimeStats->setAcquireTime(id, frameNumber, ts));
232 break;
233 case TimeStamp::ACQUIRE_FENCE:
234 ASSERT_NO_FATAL_FAILURE(
235 mTimeStats->setAcquireFence(id, frameNumber, std::make_shared<FenceTime>(ts)));
236 break;
237 case TimeStamp::LATCH:
238 ASSERT_NO_FATAL_FAILURE(mTimeStats->setLatchTime(id, frameNumber, ts));
239 break;
240 case TimeStamp::DESIRED:
241 ASSERT_NO_FATAL_FAILURE(mTimeStats->setDesiredTime(id, frameNumber, ts));
242 break;
243 case TimeStamp::PRESENT:
244 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPresentTime(id, frameNumber, ts));
245 break;
246 case TimeStamp::PRESENT_FENCE:
247 ASSERT_NO_FATAL_FAILURE(
248 mTimeStats->setPresentFence(id, frameNumber, std::make_shared<FenceTime>(ts)));
249 break;
250 default:
251 ALOGD("Invalid timestamp type");
252 }
253}
254
255int32_t TimeStatsTest::genRandomInt32(int32_t begin, int32_t end) {
256 std::uniform_int_distribution<int32_t> distr(begin, end);
257 return distr(mRandomEngine);
258}
259
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000260TEST_F(TimeStatsTest, disabledByDefault) {
261 ASSERT_FALSE(mTimeStats->isEnabled());
262}
263
Tej Singh38a4b212020-03-13 19:04:51 -0700264TEST_F(TimeStatsTest, setsCallbacksAfterBoot) {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000265 mTimeStats->onBootFinished();
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800266 EXPECT_THAT(mDelegate->mAtomTags,
267 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
268 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
269}
270
Tej Singh38a4b212020-03-13 19:04:51 -0700271TEST_F(TimeStatsTest, clearsCallbacksOnDestruction) {
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800272 EXPECT_CALL(*mDelegate,
Tej Singh38a4b212020-03-13 19:04:51 -0700273 clearStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO));
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800274 EXPECT_CALL(*mDelegate,
Tej Singh38a4b212020-03-13 19:04:51 -0700275 clearStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO));
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800276 mTimeStats.reset();
Alec Mourib3885ad2019-09-06 17:08:55 -0700277}
278
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800279TEST_F(TimeStatsTest, canEnableAndDisableTimeStats) {
280 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
281 ASSERT_TRUE(mTimeStats->isEnabled());
282
283 EXPECT_TRUE(inputCommand(InputCommand::DISABLE, FMT_STRING).empty());
284 ASSERT_FALSE(mTimeStats->isEnabled());
285}
286
287TEST_F(TimeStatsTest, canIncreaseGlobalStats) {
288 constexpr size_t TOTAL_FRAMES = 5;
289 constexpr size_t MISSED_FRAMES = 4;
290 constexpr size_t CLIENT_COMPOSITION_FRAMES = 3;
291
292 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
293
294 for (size_t i = 0; i < TOTAL_FRAMES; i++) {
295 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementTotalFrames());
296 }
297 for (size_t i = 0; i < MISSED_FRAMES; i++) {
298 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementMissedFrames());
299 }
300 for (size_t i = 0; i < CLIENT_COMPOSITION_FRAMES; i++) {
301 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionFrames());
302 }
303
304 SFTimeStatsGlobalProto globalProto;
305 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
306
307 ASSERT_TRUE(globalProto.has_total_frames());
308 EXPECT_EQ(TOTAL_FRAMES, globalProto.total_frames());
309 ASSERT_TRUE(globalProto.has_missed_frames());
310 EXPECT_EQ(MISSED_FRAMES, globalProto.missed_frames());
311 ASSERT_TRUE(globalProto.has_client_composition_frames());
312 EXPECT_EQ(CLIENT_COMPOSITION_FRAMES, globalProto.client_composition_frames());
313}
314
Alec Mouri91f6df32020-01-30 08:48:58 -0800315TEST_F(TimeStatsTest, canIncreaseLateAcquireFrames) {
316 // this stat is not in the proto so verify by checking the string dump
317 constexpr size_t LATE_ACQUIRE_FRAMES = 2;
318
319 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
320
321 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
322 for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) {
323 mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire);
324 }
325 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
326
327 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
328 const std::string expectedResult = "lateAcquireFrames = " + std::to_string(LATE_ACQUIRE_FRAMES);
329 EXPECT_THAT(result, HasSubstr(expectedResult));
330}
331
332TEST_F(TimeStatsTest, canIncreaseBadDesiredPresent) {
333 // this stat is not in the proto so verify by checking the string dump
334 constexpr size_t BAD_DESIRED_PRESENT_FRAMES = 2;
335
336 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
337
338 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
339 for (size_t i = 0; i < BAD_DESIRED_PRESENT_FRAMES; i++) {
340 mTimeStats->incrementBadDesiredPresent(LAYER_ID_0);
341 }
342 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
343
344 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
345 const std::string expectedResult =
346 "badDesiredPresentFrames = " + std::to_string(BAD_DESIRED_PRESENT_FRAMES);
347 EXPECT_THAT(result, HasSubstr(expectedResult));
348}
349
Vishnu Nair9b079a22020-01-21 14:36:08 -0800350TEST_F(TimeStatsTest, canIncreaseClientCompositionReusedFrames) {
351 // this stat is not in the proto so verify by checking the string dump
352 constexpr size_t CLIENT_COMPOSITION_REUSED_FRAMES = 2;
353
354 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
355 for (size_t i = 0; i < CLIENT_COMPOSITION_REUSED_FRAMES; i++) {
356 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionReusedFrames());
357 }
358
359 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
360 const std::string expectedResult =
361 "clientCompositionReusedFrames = " + std::to_string(CLIENT_COMPOSITION_REUSED_FRAMES);
362 EXPECT_THAT(result, HasSubstr(expectedResult));
363}
364
Alec Mouri8de697e2020-03-19 10:52:01 -0700365TEST_F(TimeStatsTest, canIncreaseRefreshRateSwitches) {
366 // this stat is not in the proto so verify by checking the string dump
367 constexpr size_t REFRESH_RATE_SWITCHES = 2;
368
369 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
370 for (size_t i = 0; i < REFRESH_RATE_SWITCHES; i++) {
371 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
372 }
373
374 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
375 const std::string expectedResult =
376 "refreshRateSwitches = " + std::to_string(REFRESH_RATE_SWITCHES);
377 EXPECT_THAT(result, HasSubstr(expectedResult));
378}
379
Alec Mouri8f7a0102020-04-15 12:11:10 -0700380TEST_F(TimeStatsTest, canIncreaseCompositionStrategyChanges) {
381 // this stat is not in the proto so verify by checking the string dump
382 constexpr size_t COMPOSITION_STRATEGY_CHANGES = 2;
383
384 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
385 for (size_t i = 0; i < COMPOSITION_STRATEGY_CHANGES; i++) {
386 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementCompositionStrategyChanges());
387 }
388
389 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
390 const std::string expectedResult =
391 "compositionStrategyChanges = " + std::to_string(COMPOSITION_STRATEGY_CHANGES);
392 EXPECT_THAT(result, HasSubstr(expectedResult));
393}
394
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800395TEST_F(TimeStatsTest, canAverageFrameDuration) {
396 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
397 mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
398 mTimeStats
399 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
400 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
401 .count());
402 mTimeStats
403 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
404 std::chrono::duration_cast<std::chrono::nanoseconds>(16ms)
405 .count());
406
407 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
408 EXPECT_THAT(result, HasSubstr("averageFrameDuration = 10.000 ms"));
409}
410
411TEST_F(TimeStatsTest, canAverageRenderEngineTimings) {
412 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
413 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms)
414 .count(),
415 std::make_shared<FenceTime>(
416 std::chrono::duration_cast<
417 std::chrono::nanoseconds>(3ms)
418 .count()));
419
420 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(4ms)
421 .count(),
422 std::chrono::duration_cast<std::chrono::nanoseconds>(8ms)
423 .count());
424
425 // Push a dummy present fence to trigger flushing the RenderEngine timings.
426 mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
427 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(
428 std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count()));
429
430 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
431 EXPECT_THAT(result, HasSubstr("averageRenderEngineTiming = 3.000 ms"));
432}
433
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800434TEST_F(TimeStatsTest, canInsertGlobalPresentToPresent) {
435 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
436
437 ASSERT_NO_FATAL_FAILURE(
438 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(1000000)));
439 ASSERT_NO_FATAL_FAILURE(
440 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(2000000)));
441
442 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL));
443 ASSERT_NO_FATAL_FAILURE(
444 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000)));
445 ASSERT_NO_FATAL_FAILURE(
446 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000)));
447
448 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(HWC_POWER_MODE_OFF));
449 ASSERT_NO_FATAL_FAILURE(
450 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(6000000)));
451 ASSERT_NO_FATAL_FAILURE(
452 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(8000000)));
453
454 SFTimeStatsGlobalProto globalProto;
455 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
456
457 ASSERT_EQ(1, globalProto.present_to_present_size());
458 const SFTimeStatsHistogramBucketProto& histogramProto = globalProto.present_to_present().Get(0);
459 EXPECT_EQ(1, histogramProto.frame_count());
460 EXPECT_EQ(2, histogramProto.time_millis());
461}
462
Alec Mouri9519bf12019-11-15 16:54:44 -0800463TEST_F(TimeStatsTest, canInsertGlobalFrameDuration) {
464 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
465
Alec Mouri9519bf12019-11-15 16:54:44 -0800466 mTimeStats->setPowerMode(HWC_POWER_MODE_OFF);
467 mTimeStats
468 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
469 std::chrono::duration_cast<std::chrono::nanoseconds>(5ms)
470 .count());
471 mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
472 mTimeStats
473 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(3ms).count(),
474 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
475 .count());
476
477 SFTimeStatsGlobalProto globalProto;
478 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
479
480 ASSERT_EQ(1, globalProto.frame_duration_size());
481 const SFTimeStatsHistogramBucketProto& histogramProto = globalProto.frame_duration().Get(0);
482 EXPECT_EQ(1, histogramProto.frame_count());
483 EXPECT_EQ(3, histogramProto.time_millis());
484}
485
Alec Mourie4034bb2019-11-19 12:45:54 -0800486TEST_F(TimeStatsTest, canInsertGlobalRenderEngineTiming) {
487 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
488
Alec Mourie4034bb2019-11-19 12:45:54 -0800489 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms)
490 .count(),
491 std::make_shared<FenceTime>(
492 std::chrono::duration_cast<
493 std::chrono::nanoseconds>(3ms)
494 .count()));
495
496 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(4ms)
497 .count(),
498 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
499 .count());
500
501 // First verify that flushing RenderEngine durations did not occur yet.
502 SFTimeStatsGlobalProto preFlushProto;
503 ASSERT_TRUE(preFlushProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
504 ASSERT_EQ(0, preFlushProto.render_engine_timing_size());
505
506 // Push a dummy present fence to trigger flushing the RenderEngine timings.
507 mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
508 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(
509 std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count()));
510
511 // Now we can verify that RenderEngine durations were flushed now.
512 SFTimeStatsGlobalProto postFlushProto;
513 ASSERT_TRUE(postFlushProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
514
515 ASSERT_EQ(1, postFlushProto.render_engine_timing_size());
516 const SFTimeStatsHistogramBucketProto& histogramProto =
517 postFlushProto.render_engine_timing().Get(0);
518 EXPECT_EQ(2, histogramProto.frame_count());
519 EXPECT_EQ(2, histogramProto.time_millis());
520}
521
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800522TEST_F(TimeStatsTest, canInsertOneLayerTimeStats) {
523 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
524
525 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
526 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
527
528 SFTimeStatsGlobalProto globalProto;
529 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
530
531 ASSERT_EQ(1, globalProto.stats_size());
532 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
533 ASSERT_TRUE(layerProto.has_layer_name());
534 EXPECT_EQ(genLayerName(LAYER_ID_0), layerProto.layer_name());
535 ASSERT_TRUE(layerProto.has_total_frames());
536 EXPECT_EQ(1, layerProto.total_frames());
537 ASSERT_EQ(6, layerProto.deltas_size());
538 for (const SFTimeStatsDeltaProto& deltaProto : layerProto.deltas()) {
539 ASSERT_EQ(1, deltaProto.histograms_size());
540 const SFTimeStatsHistogramBucketProto& histogramProto = deltaProto.histograms().Get(0);
541 EXPECT_EQ(1, histogramProto.frame_count());
542 if ("post2acquire" == deltaProto.delta_name()) {
543 EXPECT_EQ(1, histogramProto.time_millis());
544 } else if ("post2present" == deltaProto.delta_name()) {
545 EXPECT_EQ(4, histogramProto.time_millis());
546 } else if ("acquire2present" == deltaProto.delta_name()) {
547 EXPECT_EQ(3, histogramProto.time_millis());
548 } else if ("latch2present" == deltaProto.delta_name()) {
549 EXPECT_EQ(2, histogramProto.time_millis());
550 } else if ("desired2present" == deltaProto.delta_name()) {
551 EXPECT_EQ(1, histogramProto.time_millis());
552 } else if ("present2present" == deltaProto.delta_name()) {
553 EXPECT_EQ(1, histogramProto.time_millis());
554 } else {
555 FAIL() << "Unknown delta_name: " << deltaProto.delta_name();
556 }
557 }
558}
559
560TEST_F(TimeStatsTest, canNotInsertInvalidLayerNameTimeStats) {
561 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
562
563 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_INVALID, 1, 1000000);
564 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_INVALID, 2, 2000000);
565
566 SFTimeStatsGlobalProto globalProto;
567 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
568
569 ASSERT_EQ(0, globalProto.stats_size());
570}
571
572TEST_F(TimeStatsTest, canInsertMultipleLayersTimeStats) {
573 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
574
575 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
576 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 1000000);
577 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
578 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 2000000);
579
580 SFTimeStatsGlobalProto globalProto;
581 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
582
583 EXPECT_EQ(2, globalProto.stats_size());
584}
585
586TEST_F(TimeStatsTest, canInsertUnorderedLayerTimeStats) {
587 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
588
589 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
590 insertTimeRecord(UNORDERED_SEQUENCE, LAYER_ID_0, 2, 2000000);
591
592 SFTimeStatsGlobalProto globalProto;
593 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
594
595 ASSERT_EQ(1, globalProto.stats_size());
596 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
597 ASSERT_TRUE(layerProto.has_layer_name());
598 EXPECT_EQ(genLayerName(LAYER_ID_0), layerProto.layer_name());
599 ASSERT_TRUE(layerProto.has_total_frames());
600 EXPECT_EQ(1, layerProto.total_frames());
601 ASSERT_EQ(6, layerProto.deltas_size());
602 for (const SFTimeStatsDeltaProto& deltaProto : layerProto.deltas()) {
603 ASSERT_EQ(1, deltaProto.histograms_size());
604 const SFTimeStatsHistogramBucketProto& histogramProto = deltaProto.histograms().Get(0);
605 EXPECT_EQ(1, histogramProto.frame_count());
606 if ("post2acquire" == deltaProto.delta_name()) {
607 EXPECT_EQ(0, histogramProto.time_millis());
608 } else if ("post2present" == deltaProto.delta_name()) {
609 EXPECT_EQ(2, histogramProto.time_millis());
610 } else if ("acquire2present" == deltaProto.delta_name()) {
611 EXPECT_EQ(2, histogramProto.time_millis());
612 } else if ("latch2present" == deltaProto.delta_name()) {
613 EXPECT_EQ(2, histogramProto.time_millis());
614 } else if ("desired2present" == deltaProto.delta_name()) {
615 EXPECT_EQ(1, histogramProto.time_millis());
616 } else if ("present2present" == deltaProto.delta_name()) {
617 EXPECT_EQ(1, histogramProto.time_millis());
618 } else {
619 FAIL() << "Unknown delta_name: " << deltaProto.delta_name();
620 }
621 }
622}
623
Alec Mourifb571ea2019-01-24 18:42:10 -0800624TEST_F(TimeStatsTest, recordRefreshRateNewConfigs) {
625 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
626
627 uint32_t fpsOne = 30;
628 uint32_t fpsTwo = 90;
629 uint64_t millisOne = 5000;
630 uint64_t millisTwo = 7000;
631
632 mTimeStats->recordRefreshRate(fpsOne, ms2ns(millisOne));
633 mTimeStats->recordRefreshRate(fpsTwo, ms2ns(millisTwo));
634
635 SFTimeStatsGlobalProto globalProto;
636 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
637
638 SFTimeStatsDisplayConfigBucketProto expectedBucketOne;
639 SFTimeStatsDisplayConfigProto* expectedConfigOne = expectedBucketOne.mutable_config();
640 expectedConfigOne->set_fps(fpsOne);
641 expectedBucketOne.set_duration_millis(millisOne);
642
643 SFTimeStatsDisplayConfigBucketProto expectedBucketTwo;
644 SFTimeStatsDisplayConfigProto* expectedConfigTwo = expectedBucketTwo.mutable_config();
645 expectedConfigTwo->set_fps(fpsTwo);
646 expectedBucketTwo.set_duration_millis(millisTwo);
647
648 EXPECT_THAT(globalProto.display_config_stats(), SizeIs(2));
649
650 std::unordered_set<uint32_t> seen_fps;
651 for (const auto& bucket : globalProto.display_config_stats()) {
652 seen_fps.emplace(bucket.config().fps());
653 if (fpsOne == bucket.config().fps()) {
654 EXPECT_EQ(millisOne, bucket.duration_millis());
655 } else if (fpsTwo == bucket.config().fps()) {
656 EXPECT_EQ(millisTwo, bucket.duration_millis());
657 } else {
658 FAIL() << "Unknown fps: " << bucket.config().fps();
659 }
660 }
661 EXPECT_THAT(seen_fps, UnorderedElementsAre(fpsOne, fpsTwo));
662}
663
664TEST_F(TimeStatsTest, recordRefreshRateUpdatesConfig) {
665 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
666
667 uint32_t fps = 30;
668 uint64_t millisOne = 5000;
669 uint64_t millisTwo = 7000;
670
671 mTimeStats->recordRefreshRate(fps, ms2ns(millisOne));
672 mTimeStats->recordRefreshRate(fps, ms2ns(millisTwo));
673
674 SFTimeStatsGlobalProto globalProto;
675 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
676 EXPECT_THAT(globalProto.display_config_stats(), SizeIs(1));
677 EXPECT_EQ(fps, globalProto.display_config_stats().Get(0).config().fps());
678 EXPECT_EQ(millisOne + millisTwo, globalProto.display_config_stats().Get(0).duration_millis());
679}
680
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800681TEST_F(TimeStatsTest, canRemoveTimeRecord) {
682 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
683
684 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
685 insertTimeRecord(INCOMPLETE_SEQUENCE, LAYER_ID_0, 2, 2000000);
686 ASSERT_NO_FATAL_FAILURE(mTimeStats->removeTimeRecord(0, 2));
687 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000);
688
689 SFTimeStatsGlobalProto globalProto;
690 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
691
692 ASSERT_EQ(1, globalProto.stats_size());
693 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
694 ASSERT_TRUE(layerProto.has_total_frames());
695 EXPECT_EQ(1, layerProto.total_frames());
696}
697
698TEST_F(TimeStatsTest, canRecoverFromIncompleteTimeRecordError) {
699 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
700
701 uint64_t frameNumber = 1;
702 nsecs_t ts = 1000000;
703 insertTimeRecord(INCOMPLETE_SEQUENCE, LAYER_ID_0, 1, 1000000);
Alec Mourifb571ea2019-01-24 18:42:10 -0800704 for (size_t i = 0; i < impl::TimeStats::MAX_NUM_TIME_RECORDS + 2; i++) {
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800705 frameNumber++;
706 ts += 1000000;
707 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, frameNumber, ts);
708 }
709
710 SFTimeStatsGlobalProto globalProto;
711 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
712
713 ASSERT_EQ(1, globalProto.stats_size());
714 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
715 ASSERT_TRUE(layerProto.has_total_frames());
716 EXPECT_EQ(1, layerProto.total_frames());
717}
718
719TEST_F(TimeStatsTest, layerTimeStatsOnDestroy) {
720 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
721
722 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
723 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
724 ASSERT_NO_FATAL_FAILURE(mTimeStats->onDestroy(0));
725 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000);
726
727 SFTimeStatsGlobalProto globalProto;
728 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
729
730 ASSERT_EQ(1, globalProto.stats_size());
731 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
732 ASSERT_TRUE(layerProto.has_total_frames());
733 EXPECT_EQ(1, layerProto.total_frames());
734}
735
736TEST_F(TimeStatsTest, canClearTimeStats) {
737 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
738
739 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementTotalFrames());
740 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementMissedFrames());
741 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionFrames());
742 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL));
Alec Mouri31ac64a2020-01-09 09:26:22 -0800743
Alec Mouri31ac64a2020-01-09 09:26:22 -0800744 mTimeStats
745 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(3ms).count(),
746 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
747 .count());
748 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(4ms)
749 .count(),
750 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
751 .count());
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800752 ASSERT_NO_FATAL_FAILURE(
753 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(1000000)));
754 ASSERT_NO_FATAL_FAILURE(
755 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(2000000)));
756 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
757 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
758
759 EXPECT_TRUE(inputCommand(InputCommand::CLEAR, FMT_STRING).empty());
760
761 SFTimeStatsGlobalProto globalProto;
762 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
763
764 EXPECT_EQ(0, globalProto.total_frames());
765 EXPECT_EQ(0, globalProto.missed_frames());
766 EXPECT_EQ(0, globalProto.client_composition_frames());
767 EXPECT_EQ(0, globalProto.present_to_present_size());
Alec Mouri31ac64a2020-01-09 09:26:22 -0800768 EXPECT_EQ(0, globalProto.frame_duration_size());
769 EXPECT_EQ(0, globalProto.render_engine_timing_size());
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800770 EXPECT_EQ(0, globalProto.stats_size());
771}
772
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800773TEST_F(TimeStatsTest, canClearDumpOnlyTimeStats) {
774 // These stats are not in the proto so verify by checking the string dump.
Vishnu Nair9b079a22020-01-21 14:36:08 -0800775 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
776 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionReusedFrames());
Alec Mouri8de697e2020-03-19 10:52:01 -0700777 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
Alec Mouri8f7a0102020-04-15 12:11:10 -0700778 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementCompositionStrategyChanges());
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800779 mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
780 mTimeStats
781 ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
782 std::chrono::duration_cast<std::chrono::nanoseconds>(5ms)
783 .count());
784 mTimeStats->recordRenderEngineDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(4ms)
785 .count(),
786 std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
787 .count());
788 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(
789 std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count()));
Vishnu Nair9b079a22020-01-21 14:36:08 -0800790 EXPECT_TRUE(inputCommand(InputCommand::CLEAR, FMT_STRING).empty());
791
792 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
793 EXPECT_THAT(result, HasSubstr("clientCompositionReusedFrames = 0"));
Alec Mouri8de697e2020-03-19 10:52:01 -0700794 EXPECT_THAT(result, HasSubstr("refreshRateSwitches = 0"));
Alec Mouri8f7a0102020-04-15 12:11:10 -0700795 EXPECT_THAT(result, HasSubstr("compositionStrategyChanges = 0"));
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800796 EXPECT_THAT(result, HasSubstr("averageFrameDuration = 0.000 ms"));
797 EXPECT_THAT(result, HasSubstr("averageRenderEngineTiming = 0.000 ms"));
Vishnu Nair9b079a22020-01-21 14:36:08 -0800798}
799
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800800TEST_F(TimeStatsTest, canDumpWithMaxLayers) {
801 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
802
803 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
804 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 1000000);
805 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
806 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 2000000);
807 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 3, 2000000);
808
809 SFTimeStatsGlobalProto globalProto;
810 ASSERT_TRUE(
811 globalProto.ParseFromString(inputCommand(InputCommand::DUMP_MAXLAYERS_1, FMT_PROTO)));
812
813 ASSERT_EQ(1, globalProto.stats_size());
814 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
815 ASSERT_TRUE(layerProto.has_layer_name());
816 EXPECT_EQ(genLayerName(LAYER_ID_1), layerProto.layer_name());
817 ASSERT_TRUE(layerProto.has_total_frames());
818 EXPECT_EQ(2, layerProto.total_frames());
819}
820
821TEST_F(TimeStatsTest, canDumpWithInvalidMaxLayers) {
822 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
823
824 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
825 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
826
827 SFTimeStatsGlobalProto globalProto;
828 ASSERT_TRUE(globalProto.ParseFromString(
829 inputCommand(InputCommand::DUMP_MAXLAYERS_INVALID, FMT_PROTO)));
830
831 ASSERT_EQ(0, globalProto.stats_size());
832}
833
Alec Mouri37384342020-01-02 17:23:37 -0800834namespace {
835std::string buildExpectedHistogramBytestring(const std::vector<int32_t>& times,
836 const std::vector<int32_t>& frameCounts) {
837 util::ProtoOutputStream proto;
838 for (int i = 0; i < times.size(); i++) {
839 ALOGE("Writing time: %d", times[i]);
840 proto.write(util::FIELD_TYPE_INT32 | util::FIELD_COUNT_REPEATED | 1 /* field id */,
841 (int32_t)times[i]);
842 ALOGE("Writing count: %d", frameCounts[i]);
843 proto.write(util::FIELD_TYPE_INT64 | util::FIELD_COUNT_REPEATED | 2 /* field id */,
844 (int64_t)frameCounts[i]);
845 }
846 std::string byteString;
847 proto.serializeToString(&byteString);
848 return byteString;
849}
850
851std::string dumpByteStringHex(const std::string& str) {
852 std::stringstream ss;
853 ss << std::hex;
854 for (const char& c : str) {
855 ss << (int)c << " ";
856 }
857
858 return ss.str();
859}
860
861} // namespace
862
863MATCHER_P2(BytesEq, bytes, size, "") {
864 std::string expected;
865 expected.append((const char*)bytes, size);
866 std::string actual;
867 actual.append((const char*)arg, size);
868
869 *result_listener << "Bytes are not equal! \n";
870 *result_listener << "size: " << size << "\n";
871 *result_listener << "expected: " << dumpByteStringHex(expected).c_str() << "\n";
872 *result_listener << "actual: " << dumpByteStringHex(actual).c_str() << "\n";
873
874 return expected == actual;
875}
876
Alec Mouridfad9002020-02-12 17:49:09 -0800877TEST_F(TimeStatsTest, globalStatsCallback) {
878 constexpr size_t TOTAL_FRAMES = 5;
879 constexpr size_t MISSED_FRAMES = 4;
880 constexpr size_t CLIENT_COMPOSITION_FRAMES = 3;
881 constexpr size_t DISPLAY_EVENT_CONNECTIONS = 14;
882
883 mTimeStats->onBootFinished();
884 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
885
886 for (size_t i = 0; i < TOTAL_FRAMES; i++) {
887 mTimeStats->incrementTotalFrames();
888 }
889 for (size_t i = 0; i < MISSED_FRAMES; i++) {
890 mTimeStats->incrementMissedFrames();
891 }
892 for (size_t i = 0; i < CLIENT_COMPOSITION_FRAMES; i++) {
893 mTimeStats->incrementClientCompositionFrames();
894 }
895
896 mTimeStats->recordDisplayEventConnectionCount(DISPLAY_EVENT_CONNECTIONS);
897 mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
898 mTimeStats->recordFrameDuration(1000000, 3000000);
899 mTimeStats->recordRenderEngineDuration(2000000, 4000000);
900 mTimeStats->recordRenderEngineDuration(2000000, std::make_shared<FenceTime>(3000000));
901
902 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000));
903 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
904
905 EXPECT_THAT(mDelegate->mAtomTags,
906 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
907 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
908 EXPECT_NE(nullptr, mDelegate->mCallback);
909 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
910
911 std::string expectedFrameDuration = buildExpectedHistogramBytestring({2}, {1});
912 std::string expectedRenderEngineTiming = buildExpectedHistogramBytestring({1, 2}, {1, 1});
913
914 {
915 InSequence seq;
916 EXPECT_CALL(*mDelegate,
917 statsEventSetAtomId(mDelegate->mEvent,
918 android::util::SURFACEFLINGER_STATS_GLOBAL_INFO));
919 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, TOTAL_FRAMES));
920 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, MISSED_FRAMES));
921 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, CLIENT_COMPOSITION_FRAMES));
922 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, _));
923 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 2));
924 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, DISPLAY_EVENT_CONNECTIONS));
925 EXPECT_CALL(*mDelegate,
926 statsEventWriteByteArray(mDelegate->mEvent,
927 BytesEq((const uint8_t*)expectedFrameDuration.c_str(),
928 expectedFrameDuration.size()),
929 expectedFrameDuration.size()));
930 EXPECT_CALL(*mDelegate,
931 statsEventWriteByteArray(mDelegate->mEvent,
932 BytesEq((const uint8_t*)
933 expectedRenderEngineTiming.c_str(),
934 expectedRenderEngineTiming.size()),
935 expectedRenderEngineTiming.size()));
936 EXPECT_CALL(*mDelegate, statsEventBuild(mDelegate->mEvent));
937 }
938 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
939 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
940 mDelegate->mCookie));
941
942 SFTimeStatsGlobalProto globalProto;
943 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
944
945 EXPECT_EQ(0, globalProto.total_frames());
946 EXPECT_EQ(0, globalProto.missed_frames());
947 EXPECT_EQ(0, globalProto.client_composition_frames());
948 EXPECT_EQ(0, globalProto.present_to_present_size());
949}
950
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -0800951TEST_F(TimeStatsTest, layerStatsCallback_pullsAllAndClears) {
952 constexpr size_t LATE_ACQUIRE_FRAMES = 2;
953 constexpr size_t BAD_DESIRED_PRESENT_FRAMES = 3;
Alec Mouri37384342020-01-02 17:23:37 -0800954 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
955
956 mTimeStats->onBootFinished();
957
958 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -0800959 for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) {
960 mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire);
961 }
962 for (size_t i = 0; i < BAD_DESIRED_PRESENT_FRAMES; i++) {
963 mTimeStats->incrementBadDesiredPresent(LAYER_ID_0);
964 }
Alec Mouri37384342020-01-02 17:23:37 -0800965 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
966
967 EXPECT_THAT(mDelegate->mAtomTags,
968 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
969 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
970 EXPECT_NE(nullptr, mDelegate->mCallback);
971 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
972
973 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1}, {1});
974 std::string expectedPostToPresent = buildExpectedHistogramBytestring({4}, {1});
975 std::string expectedAcquireToPresent = buildExpectedHistogramBytestring({3}, {1});
976 std::string expectedLatchToPresent = buildExpectedHistogramBytestring({2}, {1});
977 std::string expectedDesiredToPresent = buildExpectedHistogramBytestring({1}, {1});
978 std::string expectedPostToAcquire = buildExpectedHistogramBytestring({1}, {1});
979 {
980 InSequence seq;
981 EXPECT_CALL(*mDelegate,
982 statsEventSetAtomId(mDelegate->mEvent,
983 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
984 EXPECT_CALL(*mDelegate,
985 statsEventWriteString8(mDelegate->mEvent,
986 StrEq(genLayerName(LAYER_ID_0).c_str())));
987 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 1));
988 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 0));
989 EXPECT_CALL(*mDelegate,
990 statsEventWriteByteArray(mDelegate->mEvent,
991 BytesEq((const uint8_t*)
992 expectedPresentToPresent.c_str(),
993 expectedPresentToPresent.size()),
994 expectedPresentToPresent.size()));
995 EXPECT_CALL(*mDelegate,
996 statsEventWriteByteArray(mDelegate->mEvent,
997 BytesEq((const uint8_t*)expectedPostToPresent.c_str(),
998 expectedPostToPresent.size()),
999 expectedPostToPresent.size()));
1000 EXPECT_CALL(*mDelegate,
1001 statsEventWriteByteArray(mDelegate->mEvent,
1002 BytesEq((const uint8_t*)
1003 expectedAcquireToPresent.c_str(),
1004 expectedAcquireToPresent.size()),
1005 expectedAcquireToPresent.size()));
1006 EXPECT_CALL(*mDelegate,
1007 statsEventWriteByteArray(mDelegate->mEvent,
1008 BytesEq((const uint8_t*)expectedLatchToPresent.c_str(),
1009 expectedLatchToPresent.size()),
1010 expectedLatchToPresent.size()));
1011 EXPECT_CALL(*mDelegate,
1012 statsEventWriteByteArray(mDelegate->mEvent,
1013 BytesEq((const uint8_t*)
1014 expectedDesiredToPresent.c_str(),
1015 expectedDesiredToPresent.size()),
1016 expectedDesiredToPresent.size()));
1017 EXPECT_CALL(*mDelegate,
1018 statsEventWriteByteArray(mDelegate->mEvent,
1019 BytesEq((const uint8_t*)expectedPostToAcquire.c_str(),
1020 expectedPostToAcquire.size()),
1021 expectedPostToAcquire.size()));
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -08001022 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, LATE_ACQUIRE_FRAMES));
1023 EXPECT_CALL(*mDelegate,
1024 statsEventWriteInt64(mDelegate->mEvent, BAD_DESIRED_PRESENT_FRAMES));
Alec Mouri37384342020-01-02 17:23:37 -08001025 EXPECT_CALL(*mDelegate, statsEventBuild(mDelegate->mEvent));
1026 }
Tej Singh2a457b62020-01-31 16:16:10 -08001027 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001028 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1029 mDelegate->mCookie));
1030
1031 SFTimeStatsGlobalProto globalProto;
1032 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
1033
1034 EXPECT_EQ(0, globalProto.stats_size());
1035}
1036
1037TEST_F(TimeStatsTest, layerStatsCallback_pullsMultipleLayers) {
1038 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1039
1040 mTimeStats->onBootFinished();
1041
1042 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1043 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1044 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 2000000);
1045 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 3000000);
1046
1047 EXPECT_THAT(mDelegate->mAtomTags,
1048 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1049 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1050 EXPECT_NE(nullptr, mDelegate->mCallback);
1051 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1052
1053 EXPECT_CALL(*mDelegate,
1054 statsEventSetAtomId(mDelegate->mEvent,
1055 android::util::SURFACEFLINGER_STATS_LAYER_INFO))
1056 .Times(2);
1057 EXPECT_CALL(*mDelegate,
1058 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_0).c_str())));
1059 EXPECT_CALL(*mDelegate,
1060 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_1).c_str())));
Tej Singh2a457b62020-01-31 16:16:10 -08001061 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001062 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1063 mDelegate->mCookie));
1064}
1065
1066TEST_F(TimeStatsTest, layerStatsCallback_pullsMultipleBuckets) {
1067 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1068
1069 mTimeStats->onBootFinished();
1070
1071 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1072 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1073 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 4000000);
1074 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 5000000);
1075
Tej Singh38a4b212020-03-13 19:04:51 -07001076 // Now make sure that TimeStats flushes global stats to set the callback.
Alec Mouri37384342020-01-02 17:23:37 -08001077 mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
1078 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000));
1079 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
1080 EXPECT_THAT(mDelegate->mAtomTags,
1081 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1082 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1083 EXPECT_NE(nullptr, mDelegate->mCallback);
1084 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1085
1086 EXPECT_THAT(mDelegate->mAtomTags,
1087 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1088 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1089 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1, 2}, {2, 1});
1090 {
1091 InSequence seq;
1092 EXPECT_CALL(*mDelegate,
1093 statsEventWriteByteArray(mDelegate->mEvent,
1094 BytesEq((const uint8_t*)
1095 expectedPresentToPresent.c_str(),
1096 expectedPresentToPresent.size()),
1097 expectedPresentToPresent.size()));
1098 EXPECT_CALL(*mDelegate, statsEventWriteByteArray(mDelegate->mEvent, _, _))
1099 .Times(AnyNumber());
1100 }
Tej Singh2a457b62020-01-31 16:16:10 -08001101 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001102 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1103 mDelegate->mCookie));
1104}
1105
1106TEST_F(TimeStatsTest, layerStatsCallback_limitsHistogramBuckets) {
1107 mDelegate = new FakeStatsEventDelegate;
1108 mTimeStats =
1109 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate),
1110 std::nullopt, 1);
1111 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1112
1113 mTimeStats->onBootFinished();
1114
1115 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1116 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1117 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 4000000);
1118 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 5000000);
1119
1120 EXPECT_THAT(mDelegate->mAtomTags,
1121 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1122 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1123 EXPECT_NE(nullptr, mDelegate->mCallback);
1124 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1125
1126 EXPECT_THAT(mDelegate->mAtomTags,
1127 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1128 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1129 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1}, {2});
1130 {
1131 InSequence seq;
1132 EXPECT_CALL(*mDelegate,
1133 statsEventWriteByteArray(mDelegate->mEvent,
1134 BytesEq((const uint8_t*)
1135 expectedPresentToPresent.c_str(),
1136 expectedPresentToPresent.size()),
1137 expectedPresentToPresent.size()));
1138 EXPECT_CALL(*mDelegate, statsEventWriteByteArray(mDelegate->mEvent, _, _))
1139 .Times(AnyNumber());
1140 }
Tej Singh2a457b62020-01-31 16:16:10 -08001141 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001142 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1143 mDelegate->mCookie));
1144}
1145
1146TEST_F(TimeStatsTest, layerStatsCallback_limitsLayers) {
1147 mDelegate = new FakeStatsEventDelegate;
1148 mTimeStats =
1149 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate), 1,
1150 std::nullopt);
1151 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1152
1153 mTimeStats->onBootFinished();
1154
1155 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1156 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1157 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 2000000);
1158 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 3000000);
1159 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 4, 5000000);
1160
1161 EXPECT_THAT(mDelegate->mAtomTags,
1162 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1163 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1164 EXPECT_NE(nullptr, mDelegate->mCallback);
1165 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1166
1167 EXPECT_CALL(*mDelegate,
1168 statsEventSetAtomId(mDelegate->mEvent,
1169 android::util::SURFACEFLINGER_STATS_LAYER_INFO))
1170 .Times(1);
1171 EXPECT_CALL(*mDelegate,
1172 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_1).c_str())));
Tej Singh2a457b62020-01-31 16:16:10 -08001173 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001174 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1175 mDelegate->mCookie));
1176}
1177
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001178TEST_F(TimeStatsTest, canSurviveMonkey) {
Lloyd Pique067fe1e2018-12-06 19:44:13 -08001179 if (g_noSlowTests) {
1180 GTEST_SKIP();
1181 }
1182
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001183 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1184
1185 for (size_t i = 0; i < 10000000; ++i) {
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001186 const int32_t layerId = genRandomInt32(-1, 10);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001187 const int32_t frameNumber = genRandomInt32(1, 10);
1188 switch (genRandomInt32(0, 100)) {
1189 case 0:
1190 ALOGV("removeTimeRecord");
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001191 ASSERT_NO_FATAL_FAILURE(mTimeStats->removeTimeRecord(layerId, frameNumber));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001192 continue;
1193 case 1:
1194 ALOGV("onDestroy");
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001195 ASSERT_NO_FATAL_FAILURE(mTimeStats->onDestroy(layerId));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001196 continue;
1197 }
1198 TimeStamp type = static_cast<TimeStamp>(genRandomInt32(TIME_STAMP_BEGIN, TIME_STAMP_END));
1199 const int32_t ts = genRandomInt32(1, 1000000000);
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001200 ALOGV("type[%d], layerId[%d], frameNumber[%d], ts[%d]", type, layerId, frameNumber, ts);
1201 setTimeStamp(type, layerId, frameNumber, ts);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001202 }
1203}
1204
1205} // namespace
1206} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001207
1208// TODO(b/129481165): remove the #pragma below and fix conversion issues
1209#pragma clang diagnostic pop // ignored "-Wconversion"