summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Van Patten <timvp@google.com>2021-12-08 16:52:44 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-12-08 16:52:44 +0000
commitb4b5b8d01ec408517ee19d726485ba6221e0e148 (patch)
tree8fc20843826db01b8ccd61b07968c140e855bcb7
parent4241a8d4c000ad9296cf5ab673df197f2a2bd9aa (diff)
parenta9ad69b663bc5358d7641d873b657ab00138dcba (diff)
downloadnative-b4b5b8d01ec408517ee19d726485ba6221e0e148.tar.gz
Merge "Add angleInUse field to 'dumpsys gpu'"
-rw-r--r--libs/graphicsenv/GpuStatsInfo.cpp3
-rw-r--r--libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h6
-rw-r--r--services/gpuservice/gpustats/GpuStats.cpp48
-rw-r--r--services/gpuservice/gpustats/include/gpustats/GpuStats.h12
-rw-r--r--services/gpuservice/tests/unittests/GpuStatsTest.cpp46
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,