blob: 430c3504565e39fef5b3191a98d6031812577288 [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 Zhangbaaef882020-02-02 17:45:30 -080020#include <gpustats/GpuStats.h>
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080021
Yiwei Zhang174a2a02019-05-06 19:08:31 -070022#include <cutils/properties.h>
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080023#include <log/log.h>
Yiwei Zhangb59a1272020-02-04 14:58:01 -080024#include <stats_event.h>
25#include <statslog.h>
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080026#include <utils/Trace.h>
27
Yiwei Zhang174a2a02019-05-06 19:08:31 -070028#include <unordered_set>
29
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080030namespace android {
31
Yiwei Zhangb59a1272020-02-04 14:58:01 -080032GpuStats::GpuStats() {
33 AStatsManager_registerPullAtomCallback(android::util::GPU_STATS_GLOBAL_INFO,
34 GpuStats::pullAtomCallback, nullptr, this);
35}
36
37GpuStats::~GpuStats() {
38 AStatsManager_unregisterPullAtomCallback(android::util::GPU_STATS_GLOBAL_INFO);
39}
40
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070041static void addLoadingCount(GpuStatsInfo::Driver driver, bool isDriverLoaded,
Yiwei Zhangf40fb102019-02-27 21:05:06 -080042 GpuStatsGlobalInfo* const outGlobalInfo) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080043 switch (driver) {
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070044 case GpuStatsInfo::Driver::GL:
45 case GpuStatsInfo::Driver::GL_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080046 outGlobalInfo->glLoadingCount++;
47 if (!isDriverLoaded) outGlobalInfo->glLoadingFailureCount++;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080048 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070049 case GpuStatsInfo::Driver::VULKAN:
50 case GpuStatsInfo::Driver::VULKAN_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080051 outGlobalInfo->vkLoadingCount++;
52 if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080053 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070054 case GpuStatsInfo::Driver::ANGLE:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070055 outGlobalInfo->angleLoadingCount++;
56 if (!isDriverLoaded) outGlobalInfo->angleLoadingFailureCount++;
57 break;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080058 default:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070059 break;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080060 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080061}
62
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070063static void addLoadingTime(GpuStatsInfo::Driver driver, int64_t driverLoadingTime,
Yiwei Zhangf40fb102019-02-27 21:05:06 -080064 GpuStatsAppInfo* const outAppInfo) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080065 switch (driver) {
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070066 case GpuStatsInfo::Driver::GL:
67 case GpuStatsInfo::Driver::GL_UPDATED:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070068 if (outAppInfo->glDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
69 outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
70 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080071 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070072 case GpuStatsInfo::Driver::VULKAN:
73 case GpuStatsInfo::Driver::VULKAN_UPDATED:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070074 if (outAppInfo->vkDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
75 outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
76 }
77 break;
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -070078 case GpuStatsInfo::Driver::ANGLE:
Yiwei Zhang8e7c4b62019-05-08 15:57:59 -070079 if (outAppInfo->angleDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
80 outAppInfo->angleDriverLoadingTime.emplace_back(driverLoadingTime);
81 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080082 break;
83 default:
84 break;
85 }
86}
87
Yiwei Zhangfdd7e782020-01-31 15:59:34 -080088void GpuStats::insertDriverStats(const std::string& driverPackageName,
89 const std::string& driverVersionName, uint64_t driverVersionCode,
90 int64_t driverBuildTime, const std::string& appPackageName,
91 const int32_t vulkanVersion, GpuStatsInfo::Driver driver,
92 bool isDriverLoaded, int64_t driverLoadingTime) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080093 ATRACE_CALL();
94
95 std::lock_guard<std::mutex> lock(mLock);
96 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);
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700149 if (!mAppStats.count(appStatsKey)) {
150 return;
151 }
152
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700153 switch (stats) {
154 case GpuStatsInfo::Stats::CPU_VULKAN_IN_USE:
155 mAppStats[appStatsKey].cpuVulkanInUse = true;
156 break;
Yiwei Zhang69395cd2019-07-03 16:55:39 -0700157 case GpuStatsInfo::Stats::FALSE_PREROTATION:
158 mAppStats[appStatsKey].falsePrerotation = true;
159 break;
Yiwei Zhang011538f2019-12-20 14:37:21 -0800160 case GpuStatsInfo::Stats::GLES_1_IN_USE:
161 mAppStats[appStatsKey].gles1InUse = true;
162 break;
Yiwei Zhangbcba4112019-07-03 13:39:32 -0700163 default:
164 break;
165 }
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -0700166}
167
Yiwei Zhang174a2a02019-05-06 19:08:31 -0700168void GpuStats::interceptSystemDriverStatsLocked() {
169 // Append cpuVulkanVersion and glesVersion to system driver stats
170 if (!mGlobalStats.count(0) || mGlobalStats[0].glesVersion) {
171 return;
172 }
173
174 mGlobalStats[0].cpuVulkanVersion = property_get_int32("ro.cpuvulkan.version", 0);
175 mGlobalStats[0].glesVersion = property_get_int32("ro.opengles.version", 0);
176}
177
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800178void GpuStats::dump(const Vector<String16>& args, std::string* result) {
179 ATRACE_CALL();
180
181 if (!result) {
182 ALOGE("Dump result shouldn't be nullptr.");
183 return;
184 }
185
186 std::lock_guard<std::mutex> lock(mLock);
187 bool dumpAll = true;
188
189 std::unordered_set<std::string> argsSet;
190 for (size_t i = 0; i < args.size(); i++) {
191 argsSet.insert(String8(args[i]).c_str());
192 }
193
194 const bool dumpGlobal = argsSet.count("--global") != 0;
195 if (dumpGlobal) {
196 dumpGlobalLocked(result);
197 dumpAll = false;
198 }
199
200 const bool dumpApp = argsSet.count("--app") != 0;
201 if (dumpApp) {
202 dumpAppLocked(result);
203 dumpAll = false;
204 }
205
Yiwei Zhangfdd7e782020-01-31 15:59:34 -0800206 if (dumpAll) {
207 dumpGlobalLocked(result);
208 dumpAppLocked(result);
209 }
210
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800211 if (argsSet.count("--clear")) {
212 bool clearAll = true;
213
214 if (dumpGlobal) {
215 mGlobalStats.clear();
216 clearAll = false;
217 }
218
219 if (dumpApp) {
220 mAppStats.clear();
221 clearAll = false;
222 }
223
224 if (clearAll) {
225 mGlobalStats.clear();
226 mAppStats.clear();
227 }
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800228 }
229}
230
231void GpuStats::dumpGlobalLocked(std::string* result) {
Yiwei Zhang174a2a02019-05-06 19:08:31 -0700232 interceptSystemDriverStatsLocked();
233
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800234 for (const auto& ele : mGlobalStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800235 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800236 result->append("\n");
237 }
238}
239
240void GpuStats::dumpAppLocked(std::string* result) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800241 for (const auto& ele : mAppStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800242 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800243 result->append("\n");
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800244 }
245}
246
Yiwei Zhangb59a1272020-02-04 14:58:01 -0800247AStatsManager_PullAtomCallbackReturn GpuStats::pullGlobalInfoAtom(AStatsEventList* data) {
248 ATRACE_CALL();
249
250 std::lock_guard<std::mutex> lock(mLock);
251 // flush cpuVulkanVersion and glesVersion to builtin driver stats
252 interceptSystemDriverStatsLocked();
253
254 if (data) {
255 for (const auto& ele : mGlobalStats) {
256 AStatsEvent* event = AStatsEventList_addStatsEvent(data);
257 AStatsEvent_setAtomId(event, android::util::GPU_STATS_GLOBAL_INFO);
258 AStatsEvent_writeString(event, ele.second.driverPackageName.c_str());
259 AStatsEvent_writeString(event, ele.second.driverVersionName.c_str());
260 AStatsEvent_writeInt64(event, ele.second.driverVersionCode);
261 AStatsEvent_writeInt64(event, ele.second.driverBuildTime);
262 AStatsEvent_writeInt64(event, ele.second.glLoadingCount);
263 AStatsEvent_writeInt64(event, ele.second.glLoadingFailureCount);
264 AStatsEvent_writeInt64(event, ele.second.vkLoadingCount);
265 AStatsEvent_writeInt64(event, ele.second.vkLoadingFailureCount);
266 AStatsEvent_writeInt32(event, ele.second.vulkanVersion);
267 AStatsEvent_writeInt32(event, ele.second.cpuVulkanVersion);
268 AStatsEvent_writeInt32(event, ele.second.glesVersion);
269 AStatsEvent_writeInt64(event, ele.second.angleLoadingCount);
270 AStatsEvent_writeInt64(event, ele.second.angleLoadingFailureCount);
271 AStatsEvent_build(event);
272 }
273 }
274
275 mGlobalStats.clear();
276
277 return AStatsManager_PULL_SUCCESS;
278}
279
280AStatsManager_PullAtomCallbackReturn GpuStats::pullAtomCallback(int32_t atomTag,
281 AStatsEventList* data,
282 void* cookie) {
283 ATRACE_CALL();
284
285 GpuStats* pGpuStats = reinterpret_cast<GpuStats*>(cookie);
286 if (atomTag == android::util::GPU_STATS_GLOBAL_INFO) {
287 return pGpuStats->pullGlobalInfoAtom(data);
288 }
289
290 return AStatsManager_PULL_SKIP;
291}
292
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800293} // namespace android