Adding new Vulkan metrics to GPU Stats
Following fields are added into GpuStatsAppInfo for tracking:
bool createdGlesContext = false;
bool createdVulkanDevice = false;
bool createdVulkanSwapchain = false;
uint32_t vulkanApiVersion = 0;
uint64_t vulkanDeviceFeaturesEnabled = 0;
std::vector<int32_t> vulkanInstanceExtensions = {};
std::vector<int32_t> vulkanDeviceExtensions = {};
Extensions are tracked as 32-bit hashes.
setTargetStatsArray GPU service function added to provide
an array of stat values, used for reporting list of extensions.
Bug: b/244286661
Test: adb shell dumpsys gpu
Test: atest GpuStatsTest
Change-Id: I4ae4e3b687cd6274a9b4127a336dd0f91f5f9e39
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index 7b9782f..aaa8c18 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -82,6 +82,12 @@
mGpuStats->insertTargetStats(appPackageName, driverVersionCode, stats, value);
}
+void GpuService::setTargetStatsArray(const std::string& appPackageName,
+ const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
+ const uint64_t* values, const uint32_t valueCount) {
+ mGpuStats->insertTargetStatsArray(appPackageName, driverVersionCode, stats, values, valueCount);
+}
+
void GpuService::setUpdatableDriverPath(const std::string& driverPath) {
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
diff --git a/services/gpuservice/GpuService.h b/services/gpuservice/GpuService.h
index d7313d1..e7e0cba 100644
--- a/services/gpuservice/GpuService.h
+++ b/services/gpuservice/GpuService.h
@@ -56,6 +56,9 @@
int64_t driverLoadingTime) override;
void setTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode,
const GpuStatsInfo::Stats stats, const uint64_t value) override;
+ void setTargetStatsArray(const std::string& appPackageName,
+ const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
+ const uint64_t* values, const uint32_t valueCount) override;
void setUpdatableDriverPath(const std::string& driverPath) override;
std::string getUpdatableDriverPath() override;
diff --git a/services/gpuservice/gpustats/GpuStats.cpp b/services/gpuservice/gpustats/GpuStats.cpp
index d033453..f06a045 100644
--- a/services/gpuservice/gpustats/GpuStats.cpp
+++ b/services/gpuservice/gpustats/GpuStats.cpp
@@ -175,29 +175,83 @@
void GpuStats::insertTargetStats(const std::string& appPackageName,
const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
- const uint64_t /*value*/) {
+ const uint64_t value) {
+ return insertTargetStatsArray(appPackageName, driverVersionCode, stats, &value, 1);
+}
+
+void GpuStats::insertTargetStatsArray(const std::string& appPackageName,
+ const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
+ const uint64_t* values, const uint32_t valueCount) {
ATRACE_CALL();
const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
std::lock_guard<std::mutex> lock(mLock);
registerStatsdCallbacksIfNeeded();
- if (!mAppStats.count(appStatsKey)) {
+
+ const auto foundApp = mAppStats.find(appStatsKey);
+ if (foundApp == mAppStats.end()) {
return;
}
- switch (stats) {
- case GpuStatsInfo::Stats::CPU_VULKAN_IN_USE:
- mAppStats[appStatsKey].cpuVulkanInUse = true;
- break;
- case GpuStatsInfo::Stats::FALSE_PREROTATION:
- mAppStats[appStatsKey].falsePrerotation = true;
- break;
- case GpuStatsInfo::Stats::GLES_1_IN_USE:
- mAppStats[appStatsKey].gles1InUse = true;
- break;
- default:
- break;
+ GpuStatsAppInfo& targetAppStats = foundApp->second;
+
+ if (stats == GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION
+ || stats == GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION) {
+ // Handle extension arrays separately as we need to store a unique set of them
+ // in the stats vector. Storing in std::set<> is not efficient for serialization tasks.
+ std::vector<int32_t>& targetVec =
+ (stats == GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION) ?
+ targetAppStats.vulkanInstanceExtensions :
+ targetAppStats.vulkanDeviceExtensions;
+ const bool addAll = (targetVec.size() == 0);
+ targetVec.reserve(valueCount);
+
+ // Add new extensions into the set
+ for(uint32_t i = 0;
+ (i < valueCount) && (targetVec.size() < GpuStatsAppInfo::MAX_NUM_EXTENSIONS);
+ i++) {
+ const int32_t extVal = int32_t(values[i] & 0xFFFFFFFF);
+ if (addAll
+ || std::find(targetVec.cbegin(), targetVec.cend(), extVal) == targetVec.cend()) {
+ targetVec.push_back(extVal);
+ }
+ }
+ }
+ else {
+ // Handle other type of stats info events
+ for(uint32_t i = 0; i < valueCount; i++) {
+ const uint64_t value = values[i];
+ switch (stats) {
+ case GpuStatsInfo::Stats::CPU_VULKAN_IN_USE:
+ targetAppStats.cpuVulkanInUse = true;
+ break;
+ case GpuStatsInfo::Stats::FALSE_PREROTATION:
+ targetAppStats.falsePrerotation = true;
+ break;
+ case GpuStatsInfo::Stats::GLES_1_IN_USE:
+ targetAppStats.gles1InUse = true;
+ break;
+ case GpuStatsInfo::Stats::CREATED_GLES_CONTEXT:
+ targetAppStats.createdGlesContext = true;
+ break;
+ case GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE:
+ targetAppStats.createdVulkanDevice = true;
+ break;
+ case GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION:
+ targetAppStats.vulkanApiVersion = uint32_t(value & 0xffffffff);
+ break;
+ case GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN:
+ targetAppStats.createdVulkanSwapchain = true;
+ break;
+ case GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED:
+ // Merge all requested feature bits together for this app
+ targetAppStats.vulkanDeviceFeaturesEnabled |= value;
+ break;
+ default:
+ break;
+ }
+ }
}
}
@@ -347,7 +401,14 @@
ele.second.cpuVulkanInUse,
ele.second.falsePrerotation,
ele.second.gles1InUse,
- ele.second.angleInUse);
+ ele.second.angleInUse,
+ ele.second.createdGlesContext,
+ ele.second.createdVulkanDevice,
+ ele.second.createdVulkanSwapchain,
+ ele.second.vulkanApiVersion,
+ ele.second.vulkanDeviceFeaturesEnabled,
+ ele.second.vulkanInstanceExtensions,
+ ele.second.vulkanDeviceExtensions);
}
}
diff --git a/services/gpuservice/gpustats/include/gpustats/GpuStats.h b/services/gpuservice/gpustats/include/gpustats/GpuStats.h
index 2aba651..22c64db 100644
--- a/services/gpuservice/gpustats/include/gpustats/GpuStats.h
+++ b/services/gpuservice/gpustats/include/gpustats/GpuStats.h
@@ -41,11 +41,14 @@
// Insert target stats into app stats or potentially global stats as well.
void insertTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode,
const GpuStatsInfo::Stats stats, const uint64_t value);
+ void insertTargetStatsArray(const std::string& appPackageName,
+ const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
+ const uint64_t* values, const uint32_t valueCount);
// dumpsys interface
void dump(const Vector<String16>& args, std::string* result);
// This limits the worst case number of loading times tracked.
- static const size_t MAX_NUM_LOADING_TIMES = 50;
+ static const size_t MAX_NUM_LOADING_TIMES = 16;
// 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;
diff --git a/services/gpuservice/tests/unittests/GpuStatsTest.cpp b/services/gpuservice/tests/unittests/GpuStatsTest.cpp
index 7ea2288..4ce533f 100644
--- a/services/gpuservice/tests/unittests/GpuStatsTest.cpp
+++ b/services/gpuservice/tests/unittests/GpuStatsTest.cpp
@@ -52,6 +52,13 @@
#define DRIVER_LOADING_TIME_2 789
#define DRIVER_LOADING_TIME_3 891
+constexpr uint64_t VULKAN_FEATURES_MASK = 0x600D;
+constexpr uint32_t VULKAN_API_VERSION = 0x400000;
+constexpr int32_t VULKAN_INSTANCE_EXTENSION_1 = 0x1234;
+constexpr int32_t VULKAN_INSTANCE_EXTENSION_2 = 0x8765;
+constexpr int32_t VULKAN_DEVICE_EXTENSION_1 = 0x9012;
+constexpr int32_t VULKAN_DEVICE_EXTENSION_2 = 0x3456;
+
enum InputCommand : int32_t {
DUMP_ALL = 0,
DUMP_GLOBAL = 1,
@@ -218,6 +225,24 @@
GpuStatsInfo::Stats::FALSE_PREROTATION, 0);
mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
GpuStatsInfo::Stats::GLES_1_IN_USE, 0);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_GLES_CONTEXT, 0);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION,
+ VULKAN_API_VERSION);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE, 0);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN, 0);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED,
+ VULKAN_FEATURES_MASK);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION,
+ VULKAN_INSTANCE_EXTENSION_1);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION,
+ VULKAN_DEVICE_EXTENSION_1);
EXPECT_TRUE(inputCommand(InputCommand::DUMP_APP).empty());
}
@@ -233,10 +258,51 @@
GpuStatsInfo::Stats::FALSE_PREROTATION, 0);
mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
GpuStatsInfo::Stats::GLES_1_IN_USE, 0);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_GLES_CONTEXT, 0);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION,
+ VULKAN_API_VERSION);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE, 0);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN, 0);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED,
+ VULKAN_FEATURES_MASK);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION,
+ VULKAN_INSTANCE_EXTENSION_1);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION,
+ VULKAN_INSTANCE_EXTENSION_2);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION,
+ VULKAN_DEVICE_EXTENSION_1);
+ mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION,
+ VULKAN_DEVICE_EXTENSION_2);
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"));
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdGlesContext = 1"));
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdVulkanDevice = 1"));
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdVulkanSwapchain = 1"));
+ std::stringstream expectedResult;
+ expectedResult << "vulkanApiVersion = 0x" << std::hex << VULKAN_API_VERSION;
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str()));
+ expectedResult.str("");
+ expectedResult << "vulkanDeviceFeaturesEnabled = 0x" << std::hex << VULKAN_FEATURES_MASK;
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str()));
+ expectedResult.str("");
+ expectedResult << "vulkanInstanceExtensions: 0x" << std::hex << VULKAN_INSTANCE_EXTENSION_1
+ << " 0x" << std::hex << VULKAN_INSTANCE_EXTENSION_2;
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str()));
+ expectedResult.str("");
+ expectedResult << "vulkanDeviceExtensions: 0x" << std::hex << VULKAN_DEVICE_EXTENSION_1
+ << " 0x" << std::hex << VULKAN_DEVICE_EXTENSION_2;
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str()));
}
// Verify we always have the most recently used apps in mAppStats, even when we fill it.
@@ -260,11 +326,52 @@
GpuStatsInfo::Stats::FALSE_PREROTATION, 0);
mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
GpuStatsInfo::Stats::GLES_1_IN_USE, 0);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_GLES_CONTEXT, 0);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION,
+ VULKAN_API_VERSION);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE, 0);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN, 0);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED,
+ VULKAN_FEATURES_MASK);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION,
+ VULKAN_INSTANCE_EXTENSION_1);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION,
+ VULKAN_INSTANCE_EXTENSION_2);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION,
+ VULKAN_DEVICE_EXTENSION_1);
+ mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE,
+ GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION,
+ VULKAN_DEVICE_EXTENSION_2);
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"));
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdGlesContext = 1"));
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdVulkanDevice = 1"));
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdVulkanSwapchain = 1"));
+ std::stringstream expectedResult;
+ expectedResult << "vulkanApiVersion = 0x" << std::hex << VULKAN_API_VERSION;
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str()));
+ expectedResult.str("");
+ expectedResult << "vulkanDeviceFeaturesEnabled = 0x" << std::hex << VULKAN_FEATURES_MASK;
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str()));
+ expectedResult.str("");
+ expectedResult << "vulkanInstanceExtensions: 0x" << std::hex << VULKAN_INSTANCE_EXTENSION_1
+ << " 0x" << std::hex << VULKAN_INSTANCE_EXTENSION_2;
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str()));
+ expectedResult.str("");
+ expectedResult << "vulkanDeviceExtensions: 0x" << std::hex << VULKAN_DEVICE_EXTENSION_1
+ << " 0x" << std::hex << VULKAN_DEVICE_EXTENSION_2;
+ EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str()));
}
// mAppStats purges GpuStats::APP_RECORD_HEADROOM apps removed everytime it's filled up.