blob: 263bf61c126dfc37d91b6ddb9b17594ede719006 [file] [log] [blame]
Yiwei Zhang2d4c1882019-02-24 22:28:08 -08001/*
2 * Copyright 2019 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#undef LOG_TAG
17#define LOG_TAG "GpuStats"
18#define ATRACE_TAG ATRACE_TAG_GRAPHICS
19
Yiwei Zhang29f85932020-02-04 17:14:54 -080020#include "gpustats/GpuStats.h"
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080021
Yiwei Zhang29f85932020-02-04 17:14:54 -080022#include <android/util/ProtoOutputStream.h>
Yiwei Zhang174a2a02019-05-06 19:08:31 -070023#include <cutils/properties.h>
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080024#include <log/log.h>
Yiwei Zhangb59a1272020-02-04 14:58:01 -080025#include <stats_event.h>
26#include <statslog.h>
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080027#include <utils/Trace.h>
28
Yiwei Zhang174a2a02019-05-06 19:08:31 -070029#include <unordered_set>
30
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080031namespace android {
32
Yiwei Zhangb59a1272020-02-04 14:58:01 -080033GpuStats::~GpuStats() {
Alec Mouri822b10a2020-03-17 17:51:27 -070034 if (mStatsdRegistered) {
35 AStatsManager_unregisterPullAtomCallback(android::util::GPU_STATS_GLOBAL_INFO);
36 AStatsManager_unregisterPullAtomCallback(android::util::GPU_STATS_APP_INFO);
37 }
Yiwei Zhangb59a1272020-02-04 14:58:01 -080038}
39
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070040static void addLoadingCount(GpuStatsInfo::Driver driver, bool isDriverLoaded,
Yiwei Zhangf40fb102019-02-27 21:05:06 -080041 GpuStatsGlobalInfo* const outGlobalInfo) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080042 switch (driver) {
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070043 case GpuStatsInfo::Driver::GL:
44 case GpuStatsInfo::Driver::GL_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080045 outGlobalInfo->glLoadingCount++;
46 if (!isDriverLoaded) outGlobalInfo->glLoadingFailureCount++;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080047 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070048 case GpuStatsInfo::Driver::VULKAN:
49 case GpuStatsInfo::Driver::VULKAN_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080050 outGlobalInfo->vkLoadingCount++;
51 if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080052 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070053 case GpuStatsInfo::Driver::ANGLE:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070054 outGlobalInfo->angleLoadingCount++;
55 if (!isDriverLoaded) outGlobalInfo->angleLoadingFailureCount++;
56 break;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080057 default:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070058 break;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080059 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080060}
61
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070062static void addLoadingTime(GpuStatsInfo::Driver driver, int64_t driverLoadingTime,
Yiwei Zhangf40fb102019-02-27 21:05:06 -080063 GpuStatsAppInfo* const outAppInfo) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080064 switch (driver) {
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070065 case GpuStatsInfo::Driver::GL:
66 case GpuStatsInfo::Driver::GL_UPDATED:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070067 if (outAppInfo->glDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
68 outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
69 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080070 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070071 case GpuStatsInfo::Driver::VULKAN:
72 case GpuStatsInfo::Driver::VULKAN_UPDATED:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070073 if (outAppInfo->vkDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
74 outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
75 }
76 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070077 case GpuStatsInfo::Driver::ANGLE:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070078 if (outAppInfo->angleDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
79 outAppInfo->angleDriverLoadingTime.emplace_back(driverLoadingTime);
80 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080081 break;
82 default:
83 break;
84 }
85}
86
Yiwei Zhangfdd7e782020-01-31 15:59:34 -080087void GpuStats::insertDriverStats(const std::string& driverPackageName,
88 const std::string& driverVersionName, uint64_t driverVersionCode,
89 int64_t driverBuildTime, const std::string& appPackageName,
90 const int32_t vulkanVersion, GpuStatsInfo::Driver driver,
91 bool isDriverLoaded, int64_t driverLoadingTime) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080092 ATRACE_CALL();
93
94 std::lock_guard<std::mutex> lock(mLock);
Alec Mouri822b10a2020-03-17 17:51:27 -070095 registerStatsdCallbacksIfNeeded();
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080096 ALOGV("Received:\n"
97 "\tdriverPackageName[%s]\n"
98 "\tdriverVersionName[%s]\n"
99 "\tdriverVersionCode[%" PRIu64 "]\n"
100 "\tdriverBuildTime[%" PRId64 "]\n"
101 "\tappPackageName[%s]\n"
Yiwei Zhang794d2952019-05-06 17:43:59 -0700102 "\tvulkanVersion[%d]\n"
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800103 "\tdriver[%d]\n"
104 "\tisDriverLoaded[%d]\n"
105 "\tdriverLoadingTime[%" PRId64 "]",
106 driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime,
Yiwei Zhang794d2952019-05-06 17:43:59 -0700107 appPackageName.c_str(), vulkanVersion, static_cast<int32_t>(driver), isDriverLoaded,
108 driverLoadingTime);
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800109
110 if (!mGlobalStats.count(driverVersionCode)) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800111 GpuStatsGlobalInfo globalInfo;
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -0700112 addLoadingCount(driver, isDriverLoaded, &globalInfo);
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800113 globalInfo.driverPackageName = driverPackageName;
114 globalInfo.driverVersionName = driverVersionName;
115 globalInfo.driverVersionCode = driverVersionCode;
116 globalInfo.driverBuildTime = driverBuildTime;
Yiwei Zhang794d2952019-05-06 17:43:59 -0700117 globalInfo.vulkanVersion = vulkanVersion;
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800118 mGlobalStats.insert({driverVersionCode, globalInfo});
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -0700119 } else {
120 addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode]);
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800121 }
122
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800123 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
124 if (!mAppStats.count(appStatsKey)) {
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700125 if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
126 ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats.");
127 return;
128 }
129
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800130 GpuStatsAppInfo appInfo;
131 addLoadingTime(driver, driverLoadingTime, &appInfo);
132 appInfo.appPackageName = appPackageName;
133 appInfo.driverVersionCode = driverVersionCode;
134 mAppStats.insert({appStatsKey, appInfo});
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800135 return;
136 }
137
138 addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
139}
140
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700141void GpuStats::insertTargetStats(const std::string& appPackageName,
142 const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
143 const uint64_t /*value*/) {
144 ATRACE_CALL();
145
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700146 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700147
148 std::lock_guard<std::mutex> lock(mLock);
Alec Mouri822b10a2020-03-17 17:51:27 -0700149 registerStatsdCallbacksIfNeeded();
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700150 if (!mAppStats.count(appStatsKey)) {
151 return;
152 }
153
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700154 switch (stats) {
155 case GpuStatsInfo::Stats::CPU_VULKAN_IN_USE:
156 mAppStats[appStatsKey].cpuVulkanInUse = true;
157 break;
Yiwei Zhang69395cd2019-07-03 16:55:39 -0700158 case GpuStatsInfo::Stats::FALSE_PREROTATION:
159 mAppStats[appStatsKey].falsePrerotation = true;
160 break;
Yiwei Zhang011538f2019-12-20 14:37:21 -0800161 case GpuStatsInfo::Stats::GLES_1_IN_USE:
162 mAppStats[appStatsKey].gles1InUse = true;
163 break;
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700164 default:
165 break;
166 }
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700167}
168
Yiwei Zhang174a2a02019-05-06 19:08:31 -0700169void GpuStats::interceptSystemDriverStatsLocked() {
170 // Append cpuVulkanVersion and glesVersion to system driver stats
171 if (!mGlobalStats.count(0) || mGlobalStats[0].glesVersion) {
172 return;
173 }
174
175 mGlobalStats[0].cpuVulkanVersion = property_get_int32("ro.cpuvulkan.version", 0);
176 mGlobalStats[0].glesVersion = property_get_int32("ro.opengles.version", 0);
177}
178
Alec Mouri822b10a2020-03-17 17:51:27 -0700179void GpuStats::registerStatsdCallbacksIfNeeded() {
180 if (!mStatsdRegistered) {
181 AStatsManager_registerPullAtomCallback(android::util::GPU_STATS_GLOBAL_INFO,
182 GpuStats::pullAtomCallback, nullptr, this);
183 AStatsManager_registerPullAtomCallback(android::util::GPU_STATS_APP_INFO,
184 GpuStats::pullAtomCallback, nullptr, this);
185 mStatsdRegistered = true;
186 }
187}
188
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800189void GpuStats::dump(const Vector<String16>& args, std::string* result) {
190 ATRACE_CALL();
191
192 if (!result) {
193 ALOGE("Dump result shouldn't be nullptr.");
194 return;
195 }
196
197 std::lock_guard<std::mutex> lock(mLock);
198 bool dumpAll = true;
199
200 std::unordered_set<std::string> argsSet;
201 for (size_t i = 0; i < args.size(); i++) {
202 argsSet.insert(String8(args[i]).c_str());
203 }
204
205 const bool dumpGlobal = argsSet.count("--global") != 0;
206 if (dumpGlobal) {
207 dumpGlobalLocked(result);
208 dumpAll = false;
209 }
210
211 const bool dumpApp = argsSet.count("--app") != 0;
212 if (dumpApp) {
213 dumpAppLocked(result);
214 dumpAll = false;
215 }
216
Yiwei Zhangfdd7e782020-01-31 15:59:34 -0800217 if (dumpAll) {
218 dumpGlobalLocked(result);
219 dumpAppLocked(result);
220 }
221
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800222 if (argsSet.count("--clear")) {
223 bool clearAll = true;
224
225 if (dumpGlobal) {
226 mGlobalStats.clear();
227 clearAll = false;
228 }
229
230 if (dumpApp) {
231 mAppStats.clear();
232 clearAll = false;
233 }
234
235 if (clearAll) {
236 mGlobalStats.clear();
237 mAppStats.clear();
238 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800239 }
240}
241
242void GpuStats::dumpGlobalLocked(std::string* result) {
Yiwei Zhang174a2a02019-05-06 19:08:31 -0700243 interceptSystemDriverStatsLocked();
244
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800245 for (const auto& ele : mGlobalStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800246 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800247 result->append("\n");
248 }
249}
250
251void GpuStats::dumpAppLocked(std::string* result) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800252 for (const auto& ele : mAppStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800253 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800254 result->append("\n");
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800255 }
256}
257
Yiwei Zhang29f85932020-02-04 17:14:54 -0800258static std::string protoOutputStreamToByteString(android::util::ProtoOutputStream& proto) {
259 if (!proto.size()) return "";
260
261 std::string byteString;
262 sp<android::util::ProtoReader> reader = proto.data();
263 while (reader->readBuffer() != nullptr) {
264 const size_t toRead = reader->currentToRead();
265 byteString.append((char*)reader->readBuffer(), toRead);
266 reader->move(toRead);
267 }
268
269 if (byteString.size() != proto.size()) return "";
270
271 return byteString;
272}
273
274static std::string int64VectorToProtoByteString(const std::vector<int64_t>& value) {
275 if (value.empty()) return "";
276
277 android::util::ProtoOutputStream proto;
278 for (const auto& ele : value) {
279 proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED |
280 1 /* field id */,
281 (long long)ele);
282 }
283
284 return protoOutputStreamToByteString(proto);
285}
286
287AStatsManager_PullAtomCallbackReturn GpuStats::pullAppInfoAtom(AStatsEventList* data) {
288 ATRACE_CALL();
289
290 std::lock_guard<std::mutex> lock(mLock);
291
292 if (data) {
293 for (const auto& ele : mAppStats) {
294 AStatsEvent* event = AStatsEventList_addStatsEvent(data);
295 AStatsEvent_setAtomId(event, android::util::GPU_STATS_APP_INFO);
296 AStatsEvent_writeString(event, ele.second.appPackageName.c_str());
297 AStatsEvent_writeInt64(event, ele.second.driverVersionCode);
298
299 std::string bytes = int64VectorToProtoByteString(ele.second.glDriverLoadingTime);
300 AStatsEvent_writeByteArray(event, (const uint8_t*)bytes.c_str(), bytes.length());
301
302 bytes = int64VectorToProtoByteString(ele.second.vkDriverLoadingTime);
303 AStatsEvent_writeByteArray(event, (const uint8_t*)bytes.c_str(), bytes.length());
304
305 bytes = int64VectorToProtoByteString(ele.second.angleDriverLoadingTime);
306 AStatsEvent_writeByteArray(event, (const uint8_t*)bytes.c_str(), bytes.length());
307
308 AStatsEvent_writeBool(event, ele.second.cpuVulkanInUse);
309 AStatsEvent_writeBool(event, ele.second.falsePrerotation);
310 AStatsEvent_writeBool(event, ele.second.gles1InUse);
311 AStatsEvent_build(event);
312 }
313 }
314
315 mAppStats.clear();
316
317 return AStatsManager_PULL_SUCCESS;
318}
319
Yiwei Zhangb59a1272020-02-04 14:58:01 -0800320AStatsManager_PullAtomCallbackReturn GpuStats::pullGlobalInfoAtom(AStatsEventList* data) {
321 ATRACE_CALL();
322
323 std::lock_guard<std::mutex> lock(mLock);
324 // flush cpuVulkanVersion and glesVersion to builtin driver stats
325 interceptSystemDriverStatsLocked();
326
327 if (data) {
328 for (const auto& ele : mGlobalStats) {
329 AStatsEvent* event = AStatsEventList_addStatsEvent(data);
330 AStatsEvent_setAtomId(event, android::util::GPU_STATS_GLOBAL_INFO);
331 AStatsEvent_writeString(event, ele.second.driverPackageName.c_str());
332 AStatsEvent_writeString(event, ele.second.driverVersionName.c_str());
333 AStatsEvent_writeInt64(event, ele.second.driverVersionCode);
334 AStatsEvent_writeInt64(event, ele.second.driverBuildTime);
335 AStatsEvent_writeInt64(event, ele.second.glLoadingCount);
336 AStatsEvent_writeInt64(event, ele.second.glLoadingFailureCount);
337 AStatsEvent_writeInt64(event, ele.second.vkLoadingCount);
338 AStatsEvent_writeInt64(event, ele.second.vkLoadingFailureCount);
339 AStatsEvent_writeInt32(event, ele.second.vulkanVersion);
340 AStatsEvent_writeInt32(event, ele.second.cpuVulkanVersion);
341 AStatsEvent_writeInt32(event, ele.second.glesVersion);
342 AStatsEvent_writeInt64(event, ele.second.angleLoadingCount);
343 AStatsEvent_writeInt64(event, ele.second.angleLoadingFailureCount);
344 AStatsEvent_build(event);
345 }
346 }
347
348 mGlobalStats.clear();
349
350 return AStatsManager_PULL_SUCCESS;
351}
352
353AStatsManager_PullAtomCallbackReturn GpuStats::pullAtomCallback(int32_t atomTag,
354 AStatsEventList* data,
355 void* cookie) {
356 ATRACE_CALL();
357
358 GpuStats* pGpuStats = reinterpret_cast<GpuStats*>(cookie);
359 if (atomTag == android::util::GPU_STATS_GLOBAL_INFO) {
360 return pGpuStats->pullGlobalInfoAtom(data);
Yiwei Zhang29f85932020-02-04 17:14:54 -0800361 } else if (atomTag == android::util::GPU_STATS_APP_INFO) {
362 return pGpuStats->pullAppInfoAtom(data);
Yiwei Zhangb59a1272020-02-04 14:58:01 -0800363 }
364
365 return AStatsManager_PULL_SKIP;
366}
367
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800368} // namespace android