1 /* 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 <cutils/properties.h> 23 #include <log/log.h> 24 #include <utils/Trace.h> 25 26 #include <unordered_set> 27 28 namespace android { 29 30 static void addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded, 31 GpuStatsGlobalInfo* const outGlobalInfo) { 32 switch (driver) { 33 case GraphicsEnv::Driver::GL: 34 case GraphicsEnv::Driver::GL_UPDATED: 35 outGlobalInfo->glLoadingCount++; 36 if (!isDriverLoaded) outGlobalInfo->glLoadingFailureCount++; 37 break; 38 case GraphicsEnv::Driver::VULKAN: 39 case GraphicsEnv::Driver::VULKAN_UPDATED: 40 outGlobalInfo->vkLoadingCount++; 41 if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++; 42 break; 43 case GraphicsEnv::Driver::ANGLE: 44 outGlobalInfo->angleLoadingCount++; 45 if (!isDriverLoaded) outGlobalInfo->angleLoadingFailureCount++; 46 break; 47 default: 48 break; 49 } 50 } 51 52 static void addLoadingTime(GraphicsEnv::Driver driver, int64_t driverLoadingTime, 53 GpuStatsAppInfo* const outAppInfo) { 54 switch (driver) { 55 case GraphicsEnv::Driver::GL: 56 case GraphicsEnv::Driver::GL_UPDATED: 57 if (outAppInfo->glDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) { 58 outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime); 59 } 60 break; 61 case GraphicsEnv::Driver::VULKAN: 62 case GraphicsEnv::Driver::VULKAN_UPDATED: 63 if (outAppInfo->vkDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) { 64 outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime); 65 } 66 break; 67 case GraphicsEnv::Driver::ANGLE: 68 if (outAppInfo->angleDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) { 69 outAppInfo->angleDriverLoadingTime.emplace_back(driverLoadingTime); 70 } 71 break; 72 default: 73 break; 74 } 75 } 76 77 void GpuStats::insert(const std::string& driverPackageName, const std::string& driverVersionName, 78 uint64_t driverVersionCode, int64_t driverBuildTime, 79 const std::string& appPackageName, const int32_t vulkanVersion, 80 GraphicsEnv::Driver driver, bool isDriverLoaded, int64_t driverLoadingTime) { 81 ATRACE_CALL(); 82 83 std::lock_guard<std::mutex> lock(mLock); 84 ALOGV("Received:\n" 85 "\tdriverPackageName[%s]\n" 86 "\tdriverVersionName[%s]\n" 87 "\tdriverVersionCode[%" PRIu64 "]\n" 88 "\tdriverBuildTime[%" PRId64 "]\n" 89 "\tappPackageName[%s]\n" 90 "\tvulkanVersion[%d]\n" 91 "\tdriver[%d]\n" 92 "\tisDriverLoaded[%d]\n" 93 "\tdriverLoadingTime[%" PRId64 "]", 94 driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime, 95 appPackageName.c_str(), vulkanVersion, static_cast<int32_t>(driver), isDriverLoaded, 96 driverLoadingTime); 97 98 if (!mGlobalStats.count(driverVersionCode)) { 99 GpuStatsGlobalInfo globalInfo; 100 addLoadingCount(driver, isDriverLoaded, &globalInfo); 101 globalInfo.driverPackageName = driverPackageName; 102 globalInfo.driverVersionName = driverVersionName; 103 globalInfo.driverVersionCode = driverVersionCode; 104 globalInfo.driverBuildTime = driverBuildTime; 105 globalInfo.vulkanVersion = vulkanVersion; 106 mGlobalStats.insert({driverVersionCode, globalInfo}); 107 } else { 108 addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode]); 109 } 110 111 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode); 112 if (!mAppStats.count(appStatsKey)) { 113 if (mAppStats.size() >= MAX_NUM_APP_RECORDS) { 114 ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats."); 115 return; 116 } 117 118 GpuStatsAppInfo appInfo; 119 addLoadingTime(driver, driverLoadingTime, &appInfo); 120 appInfo.appPackageName = appPackageName; 121 appInfo.driverVersionCode = driverVersionCode; 122 mAppStats.insert({appStatsKey, appInfo}); 123 return; 124 } 125 126 addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]); 127 } 128 129 void GpuStats::setCpuVulkanInUse(const std::string& appPackageName, 130 const uint64_t driverVersionCode) { 131 const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode); 132 if (!mAppStats.count(appStatsKey)) { 133 return; 134 } 135 136 mAppStats[appStatsKey].cpuVulkanInUse = true; 137 } 138 139 void GpuStats::interceptSystemDriverStatsLocked() { 140 // Append cpuVulkanVersion and glesVersion to system driver stats 141 if (!mGlobalStats.count(0) || mGlobalStats[0].glesVersion) { 142 return; 143 } 144 145 mGlobalStats[0].cpuVulkanVersion = property_get_int32("ro.cpuvulkan.version", 0); 146 mGlobalStats[0].glesVersion = property_get_int32("ro.opengles.version", 0); 147 } 148 149 void GpuStats::dump(const Vector<String16>& args, std::string* result) { 150 ATRACE_CALL(); 151 152 if (!result) { 153 ALOGE("Dump result shouldn't be nullptr."); 154 return; 155 } 156 157 std::lock_guard<std::mutex> lock(mLock); 158 bool dumpAll = true; 159 160 std::unordered_set<std::string> argsSet; 161 for (size_t i = 0; i < args.size(); i++) { 162 argsSet.insert(String8(args[i]).c_str()); 163 } 164 165 const bool dumpGlobal = argsSet.count("--global") != 0; 166 if (dumpGlobal) { 167 dumpGlobalLocked(result); 168 dumpAll = false; 169 } 170 171 const bool dumpApp = argsSet.count("--app") != 0; 172 if (dumpApp) { 173 dumpAppLocked(result); 174 dumpAll = false; 175 } 176 177 if (argsSet.count("--clear")) { 178 bool clearAll = true; 179 180 if (dumpGlobal) { 181 mGlobalStats.clear(); 182 clearAll = false; 183 } 184 185 if (dumpApp) { 186 mAppStats.clear(); 187 clearAll = false; 188 } 189 190 if (clearAll) { 191 mGlobalStats.clear(); 192 mAppStats.clear(); 193 } 194 195 dumpAll = false; 196 } 197 198 if (dumpAll) { 199 dumpGlobalLocked(result); 200 dumpAppLocked(result); 201 } 202 } 203 204 void GpuStats::dumpGlobalLocked(std::string* result) { 205 interceptSystemDriverStatsLocked(); 206 207 for (const auto& ele : mGlobalStats) { 208 result->append(ele.second.toString()); 209 result->append("\n"); 210 } 211 } 212 213 void GpuStats::dumpAppLocked(std::string* result) { 214 for (const auto& ele : mAppStats) { 215 result->append(ele.second.toString()); 216 result->append("\n"); 217 } 218 } 219 220 void GpuStats::pullGlobalStats(std::vector<GpuStatsGlobalInfo>* outStats) { 221 ATRACE_CALL(); 222 223 std::lock_guard<std::mutex> lock(mLock); 224 outStats->clear(); 225 outStats->reserve(mGlobalStats.size()); 226 227 interceptSystemDriverStatsLocked(); 228 229 for (const auto& ele : mGlobalStats) { 230 outStats->emplace_back(ele.second); 231 } 232 233 mGlobalStats.clear(); 234 } 235 236 void GpuStats::pullAppStats(std::vector<GpuStatsAppInfo>* outStats) { 237 ATRACE_CALL(); 238 239 std::lock_guard<std::mutex> lock(mLock); 240 outStats->clear(); 241 outStats->reserve(mAppStats.size()); 242 243 for (const auto& ele : mAppStats) { 244 outStats->emplace_back(ele.second); 245 } 246 247 mAppStats.clear(); 248 } 249 250 } // namespace android 251