blob: d0945326b306e1512a60589a1a0668728fdadc01 [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() {
34 AStatsManager_registerPullAtomCallback(android::util::GPU_STATS_GLOBAL_INFO,
35 GpuStats::pullAtomCallback, nullptr, this);
Yiwei Zhang29f85932020-02-04 17:14:54 -080036 AStatsManager_registerPullAtomCallback(android::util::GPU_STATS_APP_INFO,
37 GpuStats::pullAtomCallback, nullptr, this);
Yiwei Zhangb59a1272020-02-04 14:58:01 -080038}
39
40GpuStats::~GpuStats() {
41 AStatsManager_unregisterPullAtomCallback(android::util::GPU_STATS_GLOBAL_INFO);
Yiwei Zhang29f85932020-02-04 17:14:54 -080042 AStatsManager_unregisterPullAtomCallback(android::util::GPU_STATS_APP_INFO);
Yiwei Zhangb59a1272020-02-04 14:58:01 -080043}
44
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070045static void addLoadingCount(GpuStatsInfo::Driver driver, bool isDriverLoaded,
Yiwei Zhangf40fb102019-02-27 21:05:06 -080046 GpuStatsGlobalInfo* const outGlobalInfo) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080047 switch (driver) {
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070048 case GpuStatsInfo::Driver::GL:
49 case GpuStatsInfo::Driver::GL_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080050 outGlobalInfo->glLoadingCount++;
51 if (!isDriverLoaded) outGlobalInfo->glLoadingFailureCount++;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080052 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070053 case GpuStatsInfo::Driver::VULKAN:
54 case GpuStatsInfo::Driver::VULKAN_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080055 outGlobalInfo->vkLoadingCount++;
56 if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080057 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070058 case GpuStatsInfo::Driver::ANGLE:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070059 outGlobalInfo->angleLoadingCount++;
60 if (!isDriverLoaded) outGlobalInfo->angleLoadingFailureCount++;
61 break;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080062 default:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070063 break;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080064 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080065}
66
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070067static void addLoadingTime(GpuStatsInfo::Driver driver, int64_t driverLoadingTime,
Yiwei Zhangf40fb102019-02-27 21:05:06 -080068 GpuStatsAppInfo* const outAppInfo) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080069 switch (driver) {
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070070 case GpuStatsInfo::Driver::GL:
71 case GpuStatsInfo::Driver::GL_UPDATED:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070072 if (outAppInfo->glDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
73 outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
74 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080075 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070076 case GpuStatsInfo::Driver::VULKAN:
77 case GpuStatsInfo::Driver::VULKAN_UPDATED:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070078 if (outAppInfo->vkDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
79 outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
80 }
81 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070082 case GpuStatsInfo::Driver::ANGLE:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070083 if (outAppInfo->angleDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
84 outAppInfo->angleDriverLoadingTime.emplace_back(driverLoadingTime);
85 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080086 break;
87 default:
88 break;
89 }
90}
91
Yiwei Zhangfdd7e782020-01-31 15:59:34 -080092void GpuStats::insertDriverStats(const std::string& driverPackageName,
93 const std::string& driverVersionName, uint64_t driverVersionCode,
94 int64_t driverBuildTime, const std::string& appPackageName,
95 const int32_t vulkanVersion, GpuStatsInfo::Driver driver,
96 bool isDriverLoaded, int64_t driverLoadingTime) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080097 ATRACE_CALL();
98
99 std::lock_guard<std::mutex> lock(mLock);
100 ALOGV("Received:\n"
101 "\tdriverPackageName[%s]\n"
102 "\tdriverVersionName[%s]\n"
103 "\tdriverVersionCode[%" PRIu64 "]\n"
104 "\tdriverBuildTime[%" PRId64 "]\n"
105 "\tappPackageName[%s]\n"
Yiwei Zhang794d2952019-05-06 17:43:59 -0700106 "\tvulkanVersion[%d]\n"
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800107 "\tdriver[%d]\n"
108 "\tisDriverLoaded[%d]\n"
109 "\tdriverLoadingTime[%" PRId64 "]",
110 driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime,
Yiwei Zhang794d2952019-05-06 17:43:59 -0700111 appPackageName.c_str(), vulkanVersion, static_cast<int32_t>(driver), isDriverLoaded,
112 driverLoadingTime);
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800113
114 if (!mGlobalStats.count(driverVersionCode)) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800115 GpuStatsGlobalInfo globalInfo;
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -0700116 addLoadingCount(driver, isDriverLoaded, &globalInfo);
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800117 globalInfo.driverPackageName = driverPackageName;
118 globalInfo.driverVersionName = driverVersionName;
119 globalInfo.driverVersionCode = driverVersionCode;
120 globalInfo.driverBuildTime = driverBuildTime;
Yiwei Zhang794d2952019-05-06 17:43:59 -0700121 globalInfo.vulkanVersion = vulkanVersion;
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800122 mGlobalStats.insert({driverVersionCode, globalInfo});
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -0700123 } else {
124 addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode]);
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800125 }
126
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800127 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
128 if (!mAppStats.count(appStatsKey)) {
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700129 if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
130 ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats.");
131 return;
132 }
133
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800134 GpuStatsAppInfo appInfo;
135 addLoadingTime(driver, driverLoadingTime, &appInfo);
136 appInfo.appPackageName = appPackageName;
137 appInfo.driverVersionCode = driverVersionCode;
138 mAppStats.insert({appStatsKey, appInfo});
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800139 return;
140 }
141
142 addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
143}
144
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700145void GpuStats::insertTargetStats(const std::string& appPackageName,
146 const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
147 const uint64_t /*value*/) {
148 ATRACE_CALL();
149
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700150 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700151
152 std::lock_guard<std::mutex> lock(mLock);
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700153 if (!mAppStats.count(appStatsKey)) {
154 return;
155 }
156
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700157 switch (stats) {
158 case GpuStatsInfo::Stats::CPU_VULKAN_IN_USE:
159 mAppStats[appStatsKey].cpuVulkanInUse = true;
160 break;
Yiwei Zhang69395cd2019-07-03 16:55:39 -0700161 case GpuStatsInfo::Stats::FALSE_PREROTATION:
162 mAppStats[appStatsKey].falsePrerotation = true;
163 break;
Yiwei Zhang011538f2019-12-20 14:37:21 -0800164 case GpuStatsInfo::Stats::GLES_1_IN_USE:
165 mAppStats[appStatsKey].gles1InUse = true;
166 break;
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700167 default:
168 break;
169 }
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700170}
171
Yiwei Zhang174a2a02019-05-06 19:08:31 -0700172void GpuStats::interceptSystemDriverStatsLocked() {
173 // Append cpuVulkanVersion and glesVersion to system driver stats
174 if (!mGlobalStats.count(0) || mGlobalStats[0].glesVersion) {
175 return;
176 }
177
178 mGlobalStats[0].cpuVulkanVersion = property_get_int32("ro.cpuvulkan.version", 0);
179 mGlobalStats[0].glesVersion = property_get_int32("ro.opengles.version", 0);
180}
181
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800182void GpuStats::dump(const Vector<String16>& args, std::string* result) {
183 ATRACE_CALL();
184
185 if (!result) {
186 ALOGE("Dump result shouldn't be nullptr.");
187 return;
188 }
189
190 std::lock_guard<std::mutex> lock(mLock);
191 bool dumpAll = true;
192
193 std::unordered_set<std::string> argsSet;
194 for (size_t i = 0; i < args.size(); i++) {
195 argsSet.insert(String8(args[i]).c_str());
196 }
197
198 const bool dumpGlobal = argsSet.count("--global") != 0;
199 if (dumpGlobal) {
200 dumpGlobalLocked(result);
201 dumpAll = false;
202 }
203
204 const bool dumpApp = argsSet.count("--app") != 0;
205 if (dumpApp) {
206 dumpAppLocked(result);
207 dumpAll = false;
208 }
209
Yiwei Zhangfdd7e782020-01-31 15:59:34 -0800210 if (dumpAll) {
211 dumpGlobalLocked(result);
212 dumpAppLocked(result);
213 }
214
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800215 if (argsSet.count("--clear")) {
216 bool clearAll = true;
217
218 if (dumpGlobal) {
219 mGlobalStats.clear();
220 clearAll = false;
221 }
222
223 if (dumpApp) {
224 mAppStats.clear();
225 clearAll = false;
226 }
227
228 if (clearAll) {
229 mGlobalStats.clear();
230 mAppStats.clear();
231 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800232 }
233}
234
235void GpuStats::dumpGlobalLocked(std::string* result) {
Yiwei Zhang174a2a02019-05-06 19:08:31 -0700236 interceptSystemDriverStatsLocked();
237
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800238 for (const auto& ele : mGlobalStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800239 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800240 result->append("\n");
241 }
242}
243
244void GpuStats::dumpAppLocked(std::string* result) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800245 for (const auto& ele : mAppStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800246 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800247 result->append("\n");
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800248 }
249}
250
Yiwei Zhang29f85932020-02-04 17:14:54 -0800251static std::string protoOutputStreamToByteString(android::util::ProtoOutputStream& proto) {
252 if (!proto.size()) return "";
253
254 std::string byteString;
255 sp<android::util::ProtoReader> reader = proto.data();
256 while (reader->readBuffer() != nullptr) {
257 const size_t toRead = reader->currentToRead();
258 byteString.append((char*)reader->readBuffer(), toRead);
259 reader->move(toRead);
260 }
261
262 if (byteString.size() != proto.size()) return "";
263
264 return byteString;
265}
266
267static std::string int64VectorToProtoByteString(const std::vector<int64_t>& value) {
268 if (value.empty()) return "";
269
270 android::util::ProtoOutputStream proto;
271 for (const auto& ele : value) {
272 proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED |
273 1 /* field id */,
274 (long long)ele);
275 }
276
277 return protoOutputStreamToByteString(proto);
278}
279
280AStatsManager_PullAtomCallbackReturn GpuStats::pullAppInfoAtom(AStatsEventList* data) {
281 ATRACE_CALL();
282
283 std::lock_guard<std::mutex> lock(mLock);
284
285 if (data) {
286 for (const auto& ele : mAppStats) {
287 AStatsEvent* event = AStatsEventList_addStatsEvent(data);
288 AStatsEvent_setAtomId(event, android::util::GPU_STATS_APP_INFO);
289 AStatsEvent_writeString(event, ele.second.appPackageName.c_str());
290 AStatsEvent_writeInt64(event, ele.second.driverVersionCode);
291
292 std::string bytes = int64VectorToProtoByteString(ele.second.glDriverLoadingTime);
293 AStatsEvent_writeByteArray(event, (const uint8_t*)bytes.c_str(), bytes.length());
294
295 bytes = int64VectorToProtoByteString(ele.second.vkDriverLoadingTime);
296 AStatsEvent_writeByteArray(event, (const uint8_t*)bytes.c_str(), bytes.length());
297
298 bytes = int64VectorToProtoByteString(ele.second.angleDriverLoadingTime);
299 AStatsEvent_writeByteArray(event, (const uint8_t*)bytes.c_str(), bytes.length());
300
301 AStatsEvent_writeBool(event, ele.second.cpuVulkanInUse);
302 AStatsEvent_writeBool(event, ele.second.falsePrerotation);
303 AStatsEvent_writeBool(event, ele.second.gles1InUse);
304 AStatsEvent_build(event);
305 }
306 }
307
308 mAppStats.clear();
309
310 return AStatsManager_PULL_SUCCESS;
311}
312
Yiwei Zhangb59a1272020-02-04 14:58:01 -0800313AStatsManager_PullAtomCallbackReturn GpuStats::pullGlobalInfoAtom(AStatsEventList* data) {
314 ATRACE_CALL();
315
316 std::lock_guard<std::mutex> lock(mLock);
317 // flush cpuVulkanVersion and glesVersion to builtin driver stats
318 interceptSystemDriverStatsLocked();
319
320 if (data) {
321 for (const auto& ele : mGlobalStats) {
322 AStatsEvent* event = AStatsEventList_addStatsEvent(data);
323 AStatsEvent_setAtomId(event, android::util::GPU_STATS_GLOBAL_INFO);
324 AStatsEvent_writeString(event, ele.second.driverPackageName.c_str());
325 AStatsEvent_writeString(event, ele.second.driverVersionName.c_str());
326 AStatsEvent_writeInt64(event, ele.second.driverVersionCode);
327 AStatsEvent_writeInt64(event, ele.second.driverBuildTime);
328 AStatsEvent_writeInt64(event, ele.second.glLoadingCount);
329 AStatsEvent_writeInt64(event, ele.second.glLoadingFailureCount);
330 AStatsEvent_writeInt64(event, ele.second.vkLoadingCount);
331 AStatsEvent_writeInt64(event, ele.second.vkLoadingFailureCount);
332 AStatsEvent_writeInt32(event, ele.second.vulkanVersion);
333 AStatsEvent_writeInt32(event, ele.second.cpuVulkanVersion);
334 AStatsEvent_writeInt32(event, ele.second.glesVersion);
335 AStatsEvent_writeInt64(event, ele.second.angleLoadingCount);
336 AStatsEvent_writeInt64(event, ele.second.angleLoadingFailureCount);
337 AStatsEvent_build(event);
338 }
339 }
340
341 mGlobalStats.clear();
342
343 return AStatsManager_PULL_SUCCESS;
344}
345
346AStatsManager_PullAtomCallbackReturn GpuStats::pullAtomCallback(int32_t atomTag,
347 AStatsEventList* data,
348 void* cookie) {
349 ATRACE_CALL();
350
351 GpuStats* pGpuStats = reinterpret_cast<GpuStats*>(cookie);
352 if (atomTag == android::util::GPU_STATS_GLOBAL_INFO) {
353 return pGpuStats->pullGlobalInfoAtom(data);
Yiwei Zhang29f85932020-02-04 17:14:54 -0800354 } else if (atomTag == android::util::GPU_STATS_APP_INFO) {
355 return pGpuStats->pullAppInfoAtom(data);
Yiwei Zhangb59a1272020-02-04 14:58:01 -0800356 }
357
358 return AStatsManager_PULL_SKIP;
359}
360
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800361} // namespace android