Home | History | Annotate | Download | only in gpustats
      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