blob: 618530523a12fbb47d28823df24fe05d93627f4a [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
20#include "GpuStats.h"
21
Yiwei Zhangf40fb102019-02-27 21:05:06 -080022#include <unordered_set>
23
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080024#include <log/log.h>
25#include <utils/Trace.h>
26
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080027namespace android {
28
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080029static bool addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded,
Yiwei Zhangf40fb102019-02-27 21:05:06 -080030 GpuStatsGlobalInfo* const outGlobalInfo) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080031 switch (driver) {
32 case GraphicsEnv::Driver::GL:
33 case GraphicsEnv::Driver::GL_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080034 outGlobalInfo->glLoadingCount++;
35 if (!isDriverLoaded) outGlobalInfo->glLoadingFailureCount++;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080036 break;
37 case GraphicsEnv::Driver::VULKAN:
38 case GraphicsEnv::Driver::VULKAN_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080039 outGlobalInfo->vkLoadingCount++;
40 if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++;
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080041 break;
42 default:
43 // Currently we don't support GraphicsEnv::Driver::ANGLE because the
44 // basic driver package info only belongs to system or updated driver.
45 return false;
46 }
47
48 return true;
49}
50
51static void addLoadingTime(GraphicsEnv::Driver driver, int64_t driverLoadingTime,
Yiwei Zhangf40fb102019-02-27 21:05:06 -080052 GpuStatsAppInfo* const outAppInfo) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080053 switch (driver) {
54 case GraphicsEnv::Driver::GL:
55 case GraphicsEnv::Driver::GL_UPDATED:
Yiwei Zhangf2d84132019-03-06 11:32:50 -080056 if (outAppInfo->glDriverLoadingTime.size() >= GpuStats::MAX_NUM_LOADING_TIMES) break;
Yiwei Zhangf40fb102019-02-27 21:05:06 -080057 outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080058 break;
59 case GraphicsEnv::Driver::VULKAN:
60 case GraphicsEnv::Driver::VULKAN_UPDATED:
Yiwei Zhangf2d84132019-03-06 11:32:50 -080061 if (outAppInfo->vkDriverLoadingTime.size() >= GpuStats::MAX_NUM_LOADING_TIMES) break;
Yiwei Zhangf40fb102019-02-27 21:05:06 -080062 outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080063 break;
64 default:
65 break;
66 }
67}
68
69void GpuStats::insert(const std::string& driverPackageName, const std::string& driverVersionName,
70 uint64_t driverVersionCode, int64_t driverBuildTime,
71 const std::string& appPackageName, GraphicsEnv::Driver driver,
72 bool isDriverLoaded, int64_t driverLoadingTime) {
73 ATRACE_CALL();
74
75 std::lock_guard<std::mutex> lock(mLock);
76 ALOGV("Received:\n"
77 "\tdriverPackageName[%s]\n"
78 "\tdriverVersionName[%s]\n"
79 "\tdriverVersionCode[%" PRIu64 "]\n"
80 "\tdriverBuildTime[%" PRId64 "]\n"
81 "\tappPackageName[%s]\n"
82 "\tdriver[%d]\n"
83 "\tisDriverLoaded[%d]\n"
84 "\tdriverLoadingTime[%" PRId64 "]",
85 driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime,
86 appPackageName.c_str(), static_cast<int32_t>(driver), isDriverLoaded, driverLoadingTime);
87
88 if (!mGlobalStats.count(driverVersionCode)) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -080089 GpuStatsGlobalInfo globalInfo;
90 if (!addLoadingCount(driver, isDriverLoaded, &globalInfo)) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080091 return;
92 }
Yiwei Zhangf40fb102019-02-27 21:05:06 -080093 globalInfo.driverPackageName = driverPackageName;
94 globalInfo.driverVersionName = driverVersionName;
95 globalInfo.driverVersionCode = driverVersionCode;
96 globalInfo.driverBuildTime = driverBuildTime;
97 mGlobalStats.insert({driverVersionCode, globalInfo});
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080098 } else if (!addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode])) {
99 return;
100 }
101
102 if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800103 ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats.");
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800104 return;
105 }
106
107 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
108 if (!mAppStats.count(appStatsKey)) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800109 GpuStatsAppInfo appInfo;
110 addLoadingTime(driver, driverLoadingTime, &appInfo);
111 appInfo.appPackageName = appPackageName;
112 appInfo.driverVersionCode = driverVersionCode;
113 mAppStats.insert({appStatsKey, appInfo});
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800114 return;
115 }
116
117 addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
118}
119
120void GpuStats::dump(const Vector<String16>& args, std::string* result) {
121 ATRACE_CALL();
122
123 if (!result) {
124 ALOGE("Dump result shouldn't be nullptr.");
125 return;
126 }
127
128 std::lock_guard<std::mutex> lock(mLock);
129 bool dumpAll = true;
130
131 std::unordered_set<std::string> argsSet;
132 for (size_t i = 0; i < args.size(); i++) {
133 argsSet.insert(String8(args[i]).c_str());
134 }
135
136 const bool dumpGlobal = argsSet.count("--global") != 0;
137 if (dumpGlobal) {
138 dumpGlobalLocked(result);
139 dumpAll = false;
140 }
141
142 const bool dumpApp = argsSet.count("--app") != 0;
143 if (dumpApp) {
144 dumpAppLocked(result);
145 dumpAll = false;
146 }
147
148 if (argsSet.count("--clear")) {
149 bool clearAll = true;
150
151 if (dumpGlobal) {
152 mGlobalStats.clear();
153 clearAll = false;
154 }
155
156 if (dumpApp) {
157 mAppStats.clear();
158 clearAll = false;
159 }
160
161 if (clearAll) {
162 mGlobalStats.clear();
163 mAppStats.clear();
164 }
165
166 dumpAll = false;
167 }
168
169 if (dumpAll) {
170 dumpGlobalLocked(result);
171 dumpAppLocked(result);
172 }
173}
174
175void GpuStats::dumpGlobalLocked(std::string* result) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800176 for (const auto& ele : mGlobalStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800177 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800178 result->append("\n");
179 }
180}
181
182void GpuStats::dumpAppLocked(std::string* result) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800183 for (const auto& ele : mAppStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800184 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800185 result->append("\n");
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800186 }
187}
188
Yiwei Zhangbaea97f2019-02-27 16:35:37 -0800189void GpuStats::pullGlobalStats(std::vector<GpuStatsGlobalInfo>* outStats) {
190 ATRACE_CALL();
191
192 std::lock_guard<std::mutex> lock(mLock);
193 outStats->clear();
194 outStats->reserve(mGlobalStats.size());
195
196 for (const auto& ele : mGlobalStats) {
197 outStats->emplace_back(ele.second);
198 }
199
200 mGlobalStats.clear();
201}
202
Yiwei Zhang178e0672019-03-04 14:17:12 -0800203void GpuStats::pullAppStats(std::vector<GpuStatsAppInfo>* outStats) {
204 ATRACE_CALL();
205
206 std::lock_guard<std::mutex> lock(mLock);
207 outStats->clear();
208 outStats->reserve(mAppStats.size());
209
210 for (const auto& ele : mAppStats) {
211 outStats->emplace_back(ele.second);
212 }
213
214 mAppStats.clear();
215}
216
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800217} // namespace android