blob: 43c949276558f068a6352b8946481684fb9a04c3 [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
22#include <android-base/stringprintf.h>
23#include <log/log.h>
24#include <utils/Trace.h>
25
26#include <unordered_set>
27
28namespace android {
29
30using base::StringAppendF;
31
32static bool addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded,
33 GpuStatsGlobalAtom* const outGlobalAtom) {
34 switch (driver) {
35 case GraphicsEnv::Driver::GL:
36 case GraphicsEnv::Driver::GL_UPDATED:
37 outGlobalAtom->glLoadingCount++;
38 if (!isDriverLoaded) outGlobalAtom->glLoadingFailureCount++;
39 break;
40 case GraphicsEnv::Driver::VULKAN:
41 case GraphicsEnv::Driver::VULKAN_UPDATED:
42 outGlobalAtom->vkLoadingCount++;
43 if (!isDriverLoaded) outGlobalAtom->vkLoadingFailureCount++;
44 break;
45 default:
46 // Currently we don't support GraphicsEnv::Driver::ANGLE because the
47 // basic driver package info only belongs to system or updated driver.
48 return false;
49 }
50
51 return true;
52}
53
54static void addLoadingTime(GraphicsEnv::Driver driver, int64_t driverLoadingTime,
55 GpuStatsAppAtom* const outAppAtom) {
56 switch (driver) {
57 case GraphicsEnv::Driver::GL:
58 case GraphicsEnv::Driver::GL_UPDATED:
59 outAppAtom->glDriverLoadingTime.emplace_back(driverLoadingTime);
60 break;
61 case GraphicsEnv::Driver::VULKAN:
62 case GraphicsEnv::Driver::VULKAN_UPDATED:
63 outAppAtom->vkDriverLoadingTime.emplace_back(driverLoadingTime);
64 break;
65 default:
66 break;
67 }
68}
69
70void GpuStats::insert(const std::string& driverPackageName, const std::string& driverVersionName,
71 uint64_t driverVersionCode, int64_t driverBuildTime,
72 const std::string& appPackageName, GraphicsEnv::Driver driver,
73 bool isDriverLoaded, int64_t driverLoadingTime) {
74 ATRACE_CALL();
75
76 std::lock_guard<std::mutex> lock(mLock);
77 ALOGV("Received:\n"
78 "\tdriverPackageName[%s]\n"
79 "\tdriverVersionName[%s]\n"
80 "\tdriverVersionCode[%" PRIu64 "]\n"
81 "\tdriverBuildTime[%" PRId64 "]\n"
82 "\tappPackageName[%s]\n"
83 "\tdriver[%d]\n"
84 "\tisDriverLoaded[%d]\n"
85 "\tdriverLoadingTime[%" PRId64 "]",
86 driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime,
87 appPackageName.c_str(), static_cast<int32_t>(driver), isDriverLoaded, driverLoadingTime);
88
89 if (!mGlobalStats.count(driverVersionCode)) {
90 GpuStatsGlobalAtom globalAtom;
91 if (!addLoadingCount(driver, isDriverLoaded, &globalAtom)) {
92 return;
93 }
94 globalAtom.driverPackageName = driverPackageName;
95 globalAtom.driverVersionName = driverVersionName;
96 globalAtom.driverVersionCode = driverVersionCode;
97 globalAtom.driverBuildTime = driverBuildTime;
98 mGlobalStats.insert({driverVersionCode, globalAtom});
99 } else if (!addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode])) {
100 return;
101 }
102
103 if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
104 ALOGV("GpuStatsAppAtom has reached maximum size. Ignore new stats.");
105 return;
106 }
107
108 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
109 if (!mAppStats.count(appStatsKey)) {
110 GpuStatsAppAtom appAtom;
111 addLoadingTime(driver, driverLoadingTime, &appAtom);
112 appAtom.appPackageName = appPackageName;
113 appAtom.driverVersionCode = driverVersionCode;
114 mAppStats.insert({appStatsKey, appAtom});
115 return;
116 }
117
118 addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
119}
120
121void GpuStats::dump(const Vector<String16>& args, std::string* result) {
122 ATRACE_CALL();
123
124 if (!result) {
125 ALOGE("Dump result shouldn't be nullptr.");
126 return;
127 }
128
129 std::lock_guard<std::mutex> lock(mLock);
130 bool dumpAll = true;
131
132 std::unordered_set<std::string> argsSet;
133 for (size_t i = 0; i < args.size(); i++) {
134 argsSet.insert(String8(args[i]).c_str());
135 }
136
137 const bool dumpGlobal = argsSet.count("--global") != 0;
138 if (dumpGlobal) {
139 dumpGlobalLocked(result);
140 dumpAll = false;
141 }
142
143 const bool dumpApp = argsSet.count("--app") != 0;
144 if (dumpApp) {
145 dumpAppLocked(result);
146 dumpAll = false;
147 }
148
149 if (argsSet.count("--clear")) {
150 bool clearAll = true;
151
152 if (dumpGlobal) {
153 mGlobalStats.clear();
154 clearAll = false;
155 }
156
157 if (dumpApp) {
158 mAppStats.clear();
159 clearAll = false;
160 }
161
162 if (clearAll) {
163 mGlobalStats.clear();
164 mAppStats.clear();
165 }
166
167 dumpAll = false;
168 }
169
170 if (dumpAll) {
171 dumpGlobalLocked(result);
172 dumpAppLocked(result);
173 }
174}
175
176void GpuStats::dumpGlobalLocked(std::string* result) {
177 result->append("GpuStats global:\n");
178
179 for (const auto& ele : mGlobalStats) {
180 StringAppendF(result, " driverPackageName = %s\n", ele.second.driverPackageName.c_str());
181 StringAppendF(result, " driverVersionName = %s\n", ele.second.driverVersionName.c_str());
182 StringAppendF(result, " driverVersionCode = %" PRIu64 "\n", ele.second.driverVersionCode);
183 StringAppendF(result, " driverBuildTime = %" PRId64 "\n", ele.second.driverBuildTime);
184 StringAppendF(result, " glLoadingCount = %d\n", ele.second.glLoadingCount);
185 StringAppendF(result, " glLoadingFailureCount = %d\n", ele.second.glLoadingFailureCount);
186 StringAppendF(result, " vkLoadingCount = %d\n", ele.second.vkLoadingCount);
187 StringAppendF(result, " vkLoadingFailureCount = %d\n", ele.second.vkLoadingFailureCount);
188 result->append("\n");
189 }
190}
191
192void GpuStats::dumpAppLocked(std::string* result) {
193 result->append("GpuStats app:\n");
194
195 for (const auto& ele : mAppStats) {
196 StringAppendF(result, " appPackageName = %s\n", ele.second.appPackageName.c_str());
197 StringAppendF(result, " driverVersionCode = %" PRIu64 "\n", ele.second.driverVersionCode);
198
199 result->append(" glDriverLoadingTime:");
200 for (int32_t loadingTime : ele.second.glDriverLoadingTime) {
201 StringAppendF(result, " %d", loadingTime);
202 }
203 result->append("\n");
204
205 result->append(" vkDriverLoadingTime:");
206 for (int32_t loadingTime : ele.second.vkDriverLoadingTime) {
207 StringAppendF(result, " %d", loadingTime);
208 }
209 result->append("\n\n");
210 }
211}
212
213} // namespace android