blob: 146e2c29b15ae461b51a45c98e8a56d4e52545cd [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 Zhangf40fb102019-02-27 21:05:06 -080056 outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080057 break;
58 case GraphicsEnv::Driver::VULKAN:
59 case GraphicsEnv::Driver::VULKAN_UPDATED:
Yiwei Zhangf40fb102019-02-27 21:05:06 -080060 outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080061 break;
62 default:
63 break;
64 }
65}
66
67void GpuStats::insert(const std::string& driverPackageName, const std::string& driverVersionName,
68 uint64_t driverVersionCode, int64_t driverBuildTime,
69 const std::string& appPackageName, GraphicsEnv::Driver driver,
70 bool isDriverLoaded, int64_t driverLoadingTime) {
71 ATRACE_CALL();
72
73 std::lock_guard<std::mutex> lock(mLock);
74 ALOGV("Received:\n"
75 "\tdriverPackageName[%s]\n"
76 "\tdriverVersionName[%s]\n"
77 "\tdriverVersionCode[%" PRIu64 "]\n"
78 "\tdriverBuildTime[%" PRId64 "]\n"
79 "\tappPackageName[%s]\n"
80 "\tdriver[%d]\n"
81 "\tisDriverLoaded[%d]\n"
82 "\tdriverLoadingTime[%" PRId64 "]",
83 driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime,
84 appPackageName.c_str(), static_cast<int32_t>(driver), isDriverLoaded, driverLoadingTime);
85
86 if (!mGlobalStats.count(driverVersionCode)) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -080087 GpuStatsGlobalInfo globalInfo;
88 if (!addLoadingCount(driver, isDriverLoaded, &globalInfo)) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080089 return;
90 }
Yiwei Zhangf40fb102019-02-27 21:05:06 -080091 globalInfo.driverPackageName = driverPackageName;
92 globalInfo.driverVersionName = driverVersionName;
93 globalInfo.driverVersionCode = driverVersionCode;
94 globalInfo.driverBuildTime = driverBuildTime;
95 mGlobalStats.insert({driverVersionCode, globalInfo});
Yiwei Zhang2d4c1882019-02-24 22:28:08 -080096 } else if (!addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode])) {
97 return;
98 }
99
100 if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800101 ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats.");
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800102 return;
103 }
104
105 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
106 if (!mAppStats.count(appStatsKey)) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800107 GpuStatsAppInfo appInfo;
108 addLoadingTime(driver, driverLoadingTime, &appInfo);
109 appInfo.appPackageName = appPackageName;
110 appInfo.driverVersionCode = driverVersionCode;
111 mAppStats.insert({appStatsKey, appInfo});
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800112 return;
113 }
114
115 addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
116}
117
118void GpuStats::dump(const Vector<String16>& args, std::string* result) {
119 ATRACE_CALL();
120
121 if (!result) {
122 ALOGE("Dump result shouldn't be nullptr.");
123 return;
124 }
125
126 std::lock_guard<std::mutex> lock(mLock);
127 bool dumpAll = true;
128
129 std::unordered_set<std::string> argsSet;
130 for (size_t i = 0; i < args.size(); i++) {
131 argsSet.insert(String8(args[i]).c_str());
132 }
133
134 const bool dumpGlobal = argsSet.count("--global") != 0;
135 if (dumpGlobal) {
136 dumpGlobalLocked(result);
137 dumpAll = false;
138 }
139
140 const bool dumpApp = argsSet.count("--app") != 0;
141 if (dumpApp) {
142 dumpAppLocked(result);
143 dumpAll = false;
144 }
145
146 if (argsSet.count("--clear")) {
147 bool clearAll = true;
148
149 if (dumpGlobal) {
150 mGlobalStats.clear();
151 clearAll = false;
152 }
153
154 if (dumpApp) {
155 mAppStats.clear();
156 clearAll = false;
157 }
158
159 if (clearAll) {
160 mGlobalStats.clear();
161 mAppStats.clear();
162 }
163
164 dumpAll = false;
165 }
166
167 if (dumpAll) {
168 dumpGlobalLocked(result);
169 dumpAppLocked(result);
170 }
171}
172
173void GpuStats::dumpGlobalLocked(std::string* result) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800174 for (const auto& ele : mGlobalStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800175 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800176 result->append("\n");
177 }
178}
179
180void GpuStats::dumpAppLocked(std::string* result) {
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800181 for (const auto& ele : mAppStats) {
Yiwei Zhangf40fb102019-02-27 21:05:06 -0800182 result->append(ele.second.toString());
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800183 result->append("\n");
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800184 }
185}
186
Yiwei Zhangbaea97f2019-02-27 16:35:37 -0800187void GpuStats::pullGlobalStats(std::vector<GpuStatsGlobalInfo>* outStats) {
188 ATRACE_CALL();
189
190 std::lock_guard<std::mutex> lock(mLock);
191 outStats->clear();
192 outStats->reserve(mGlobalStats.size());
193
194 for (const auto& ele : mGlobalStats) {
195 outStats->emplace_back(ele.second);
196 }
197
198 mGlobalStats.clear();
199}
200
Yiwei Zhang2d4c1882019-02-24 22:28:08 -0800201} // namespace android