diff options
author | Tim Van Patten <timvp@google.com> | 2021-12-08 16:52:44 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-12-08 16:52:44 +0000 |
commit | b4b5b8d01ec408517ee19d726485ba6221e0e148 (patch) | |
tree | 8fc20843826db01b8ccd61b07968c140e855bcb7 | |
parent | 4241a8d4c000ad9296cf5ab673df197f2a2bd9aa (diff) | |
parent | a9ad69b663bc5358d7641d873b657ab00138dcba (diff) | |
download | native-b4b5b8d01ec408517ee19d726485ba6221e0e148.tar.gz |
Merge "Add angleInUse field to 'dumpsys gpu'"
-rw-r--r-- | libs/graphicsenv/GpuStatsInfo.cpp | 3 | ||||
-rw-r--r-- | libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h | 6 | ||||
-rw-r--r-- | services/gpuservice/gpustats/GpuStats.cpp | 48 | ||||
-rw-r--r-- | services/gpuservice/gpustats/include/gpustats/GpuStats.h | 12 | ||||
-rw-r--r-- | services/gpuservice/tests/unittests/GpuStatsTest.cpp | 46 |
5 files changed, 105 insertions, 10 deletions
diff --git a/libs/graphicsenv/GpuStatsInfo.cpp b/libs/graphicsenv/GpuStatsInfo.cpp index f2d0943e86..858739c9dd 100644 --- a/libs/graphicsenv/GpuStatsInfo.cpp +++ b/libs/graphicsenv/GpuStatsInfo.cpp @@ -88,6 +88,7 @@ status_t GpuStatsAppInfo::writeToParcel(Parcel* parcel) const { if ((status = parcel->writeBool(cpuVulkanInUse)) != OK) return status; if ((status = parcel->writeBool(falsePrerotation)) != OK) return status; if ((status = parcel->writeBool(gles1InUse)) != OK) return status; + if ((status = parcel->writeBool(angleInUse)) != OK) return status; return OK; } @@ -101,6 +102,7 @@ status_t GpuStatsAppInfo::readFromParcel(const Parcel* parcel) { if ((status = parcel->readBool(&cpuVulkanInUse)) != OK) return status; if ((status = parcel->readBool(&falsePrerotation)) != OK) return status; if ((status = parcel->readBool(&gles1InUse)) != OK) return status; + if ((status = parcel->readBool(&angleInUse)) != OK) return status; return OK; } @@ -111,6 +113,7 @@ std::string GpuStatsAppInfo::toString() const { StringAppendF(&result, "cpuVulkanInUse = %d\n", cpuVulkanInUse); StringAppendF(&result, "falsePrerotation = %d\n", falsePrerotation); StringAppendF(&result, "gles1InUse = %d\n", gles1InUse); + StringAppendF(&result, "angleInUse = %d\n", angleInUse); result.append("glDriverLoadingTime:"); for (int32_t loadingTime : glDriverLoadingTime) { StringAppendF(&result, " %d", loadingTime); diff --git a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h index 9aba69fd07..5b513d2a79 100644 --- a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h +++ b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h @@ -16,6 +16,7 @@ #pragma once +#include <chrono> #include <string> #include <vector> @@ -52,7 +53,7 @@ public: }; /* - * class for transporting gpu app stats from GpuService to authorized recipents. + * class for transporting gpu app stats from GpuService to authorized recipients. * This class is intended to be a data container. */ class GpuStatsAppInfo : public Parcelable { @@ -72,6 +73,9 @@ public: bool cpuVulkanInUse = false; bool falsePrerotation = false; bool gles1InUse = false; + bool angleInUse = false; + + std::chrono::time_point<std::chrono::system_clock> lastAccessTime; }; /* diff --git a/services/gpuservice/gpustats/GpuStats.cpp b/services/gpuservice/gpustats/GpuStats.cpp index 220952d892..d033453dd7 100644 --- a/services/gpuservice/gpustats/GpuStats.cpp +++ b/services/gpuservice/gpustats/GpuStats.cpp @@ -84,6 +84,38 @@ static void addLoadingTime(GpuStatsInfo::Driver driver, int64_t driverLoadingTim } } +void GpuStats::purgeOldDriverStats() { + ALOG_ASSERT(mAppStats.size() == MAX_NUM_APP_RECORDS); + + struct GpuStatsApp { + // Key is <app package name>+<driver version code>. + const std::string *appStatsKey = nullptr; + const std::chrono::time_point<std::chrono::system_clock> *lastAccessTime = nullptr; + }; + std::vector<GpuStatsApp> gpuStatsApps(MAX_NUM_APP_RECORDS); + + // Create a list of pointers to package names and their last access times. + int index = 0; + for (const auto & [appStatsKey, gpuStatsAppInfo] : mAppStats) { + GpuStatsApp &gpuStatsApp = gpuStatsApps[index]; + gpuStatsApp.appStatsKey = &appStatsKey; + gpuStatsApp.lastAccessTime = &gpuStatsAppInfo.lastAccessTime; + ++index; + } + + // Sort the list with the oldest access times at the front. + std::sort(gpuStatsApps.begin(), gpuStatsApps.end(), [](GpuStatsApp a, GpuStatsApp b) -> bool { + return *a.lastAccessTime < *b.lastAccessTime; + }); + + // Remove the oldest packages from mAppStats to make room for new apps. + for (int i = 0; i < APP_RECORD_HEADROOM; ++i) { + mAppStats.erase(*gpuStatsApps[i].appStatsKey); + gpuStatsApps[i].appStatsKey = nullptr; + gpuStatsApps[i].lastAccessTime = nullptr; + } +} + void GpuStats::insertDriverStats(const std::string& driverPackageName, const std::string& driverVersionName, uint64_t driverVersionCode, int64_t driverBuildTime, const std::string& appPackageName, @@ -123,19 +155,22 @@ void GpuStats::insertDriverStats(const std::string& driverPackageName, const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode); if (!mAppStats.count(appStatsKey)) { if (mAppStats.size() >= MAX_NUM_APP_RECORDS) { - ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats."); - return; + ALOGV("GpuStatsAppInfo has reached maximum size. Removing old stats to make room."); + purgeOldDriverStats(); } GpuStatsAppInfo appInfo; addLoadingTime(driver, driverLoadingTime, &appInfo); appInfo.appPackageName = appPackageName; appInfo.driverVersionCode = driverVersionCode; + appInfo.angleInUse = driverPackageName == "angle"; + appInfo.lastAccessTime = std::chrono::system_clock::now(); mAppStats.insert({appStatsKey, appInfo}); - return; + } else { + mAppStats[appStatsKey].angleInUse = driverPackageName == "angle"; + addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]); + mAppStats[appStatsKey].lastAccessTime = std::chrono::system_clock::now(); } - - addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]); } void GpuStats::insertTargetStats(const std::string& appPackageName, @@ -311,7 +346,8 @@ AStatsManager_PullAtomCallbackReturn GpuStats::pullAppInfoAtom(AStatsEventList* angleDriverBytes.length()), ele.second.cpuVulkanInUse, ele.second.falsePrerotation, - ele.second.gles1InUse); + ele.second.gles1InUse, + ele.second.angleInUse); } } diff --git a/services/gpuservice/gpustats/include/gpustats/GpuStats.h b/services/gpuservice/gpustats/include/gpustats/GpuStats.h index 55f0da1bc5..2aba651af9 100644 --- a/services/gpuservice/gpustats/include/gpustats/GpuStats.h +++ b/services/gpuservice/gpustats/include/gpustats/GpuStats.h @@ -46,6 +46,11 @@ public: // This limits the worst case number of loading times tracked. static const size_t MAX_NUM_LOADING_TIMES = 50; + // Below limits the memory usage of GpuStats to be less than 10KB. This is + // the preferred number for statsd while maintaining nice data quality. + static const size_t MAX_NUM_APP_RECORDS = 100; + // The number of apps to remove when mAppStats fills up. + static const size_t APP_RECORD_HEADROOM = 10; private: // Friend class for testing. @@ -55,6 +60,10 @@ private: static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atomTag, AStatsEventList* data, void* cookie); + + // Remove old packages from mAppStats. + void purgeOldDriverStats(); + // Pull global into into global atom. AStatsManager_PullAtomCallbackReturn pullGlobalInfoAtom(AStatsEventList* data); // Pull app into into app atom. @@ -68,9 +77,6 @@ private: // Registers statsd callbacks if they have not already been registered void registerStatsdCallbacksIfNeeded(); - // Below limits the memory usage of GpuStats to be less than 10KB. This is - // the preferred number for statsd while maintaining nice data quality. - static const size_t MAX_NUM_APP_RECORDS = 100; // GpuStats access should be guarded by mLock. std::mutex mLock; // True if statsd callbacks have been registered. diff --git a/services/gpuservice/tests/unittests/GpuStatsTest.cpp b/services/gpuservice/tests/unittests/GpuStatsTest.cpp index 37ebeae18d..20c8ccf9bf 100644 --- a/services/gpuservice/tests/unittests/GpuStatsTest.cpp +++ b/services/gpuservice/tests/unittests/GpuStatsTest.cpp @@ -17,6 +17,7 @@ #undef LOG_TAG #define LOG_TAG "gpuservice_unittest" +#include <unistd.h> #include <cutils/properties.h> #include <gmock/gmock.h> #include <gpustats/GpuStats.h> @@ -221,6 +222,51 @@ TEST_F(GpuStatsTest, canInsertTargetStatsAfterProperSetup) { EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("gles1InUse = 1")); } +// Verify we always have the most recently used apps in mAppStats, even when we fill it. +TEST_F(GpuStatsTest, canInsertMoreThanMaxNumAppRecords) { + constexpr int kNumExtraApps = 15; + static_assert(kNumExtraApps > GpuStats::APP_RECORD_HEADROOM); + + // Insert stats for GpuStats::MAX_NUM_APP_RECORDS so we fill it up. + for (int i = 0; i < GpuStats::MAX_NUM_APP_RECORDS + kNumExtraApps; ++i) { + std::stringstream nameStream; + nameStream << "testapp" << "_" << i; + std::string fullPkgName = nameStream.str(); + + mGpuStats->insertDriverStats(BUILTIN_DRIVER_PKG_NAME, BUILTIN_DRIVER_VER_NAME, + BUILTIN_DRIVER_VER_CODE, BUILTIN_DRIVER_BUILD_TIME, + fullPkgName, VULKAN_VERSION, GpuStatsInfo::Driver::GL, true, + DRIVER_LOADING_TIME_1); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CPU_VULKAN_IN_USE, 0); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::FALSE_PREROTATION, 0); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::GLES_1_IN_USE, 0); + + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(fullPkgName.c_str())); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("cpuVulkanInUse = 1")); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("falsePrerotation = 1")); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("gles1InUse = 1")); + } + + // mAppStats purges GpuStats::APP_RECORD_HEADROOM apps removed everytime it's filled up. + int numPurges = kNumExtraApps / GpuStats::APP_RECORD_HEADROOM; + numPurges += (kNumExtraApps % GpuStats::APP_RECORD_HEADROOM) == 0 ? 0 : 1; + + // Verify the remaining apps are present. + for (int i = numPurges * GpuStats::APP_RECORD_HEADROOM; + i < GpuStats::MAX_NUM_APP_RECORDS + kNumExtraApps; + ++i) { + std::stringstream nameStream; + // Add a newline to search for the exact package name. + nameStream << "testapp" << "_" << i << "\n"; + std::string fullPkgName = nameStream.str(); + + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(fullPkgName.c_str())); + } +} + TEST_F(GpuStatsTest, canDumpAllBeforeClearAll) { mGpuStats->insertDriverStats(BUILTIN_DRIVER_PKG_NAME, BUILTIN_DRIVER_VER_NAME, BUILTIN_DRIVER_VER_CODE, BUILTIN_DRIVER_BUILD_TIME, APP_PKG_NAME_1, |