Game Driver: plumb driver choice and loading time to GpuStats
This change plumb the below info from GL and Vulkan loader:
1. Intended driver to use
2. Whether intended driver is loaded
3. Total driver loading time
Bug: 123529932
Test: Build, flash and boot. Verify the GpuService receiver side.
Change-Id: I967d4361bf0e04c02390c7555617575c19ecadd4
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 75fe2d3..a07627a 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -157,10 +157,11 @@
}
void GraphicsEnv::setGpuStats(const std::string& driverPackageName,
- const std::string& driverVersionName,
- const uint64_t driverVersionCode, const std::string& appPackageName) {
+ const std::string& driverVersionName, uint64_t driverVersionCode,
+ const std::string& appPackageName) {
ATRACE_CALL();
+ std::lock_guard<std::mutex> lock(mStatsLock);
ALOGV("setGpuStats:\n"
"\tdriverPackageName[%s]\n"
"\tdriverVersionName[%s]\n"
@@ -169,15 +170,89 @@
driverPackageName.c_str(), driverVersionName.c_str(),
(unsigned long long)driverVersionCode, appPackageName.c_str());
- mGpuStats = {
- .driverPackageName = driverPackageName,
- .driverVersionName = driverVersionName,
- .driverVersionCode = driverVersionCode,
- .appPackageName = appPackageName,
- };
+ mGpuStats.driverPackageName = driverPackageName;
+ mGpuStats.driverVersionName = driverVersionName;
+ mGpuStats.driverVersionCode = driverVersionCode;
+ mGpuStats.appPackageName = appPackageName;
}
-void GraphicsEnv::sendGpuStats() {
+void GraphicsEnv::setDriverToLoad(GraphicsEnv::Driver driver) {
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ switch (driver) {
+ case GraphicsEnv::Driver::GL:
+ case GraphicsEnv::Driver::GL_UPDATED:
+ case GraphicsEnv::Driver::ANGLE: {
+ if (mGpuStats.glDriverToLoad == GraphicsEnv::Driver::NONE) {
+ mGpuStats.glDriverToLoad = driver;
+ break;
+ }
+
+ if (mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE) {
+ mGpuStats.glDriverFallback = driver;
+ }
+ break;
+ }
+ case Driver::VULKAN:
+ case Driver::VULKAN_UPDATED: {
+ if (mGpuStats.vkDriverToLoad == GraphicsEnv::Driver::NONE) {
+ mGpuStats.vkDriverToLoad = driver;
+ break;
+ }
+
+ if (mGpuStats.vkDriverFallback == GraphicsEnv::Driver::NONE) {
+ mGpuStats.vkDriverFallback = driver;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void GraphicsEnv::setDriverLoaded(GraphicsEnv::Api api, bool isLoaded, int64_t driverLoadingTime) {
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ GraphicsEnv::Driver driver = GraphicsEnv::Driver::NONE;
+ bool isIntendedDriverLoaded = false;
+ if (api == GraphicsEnv::Api::API_GL) {
+ driver = mGpuStats.glDriverToLoad;
+ isIntendedDriverLoaded = isLoaded &&
+ ((mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE) ||
+ (mGpuStats.glDriverToLoad == mGpuStats.glDriverFallback));
+ } else {
+ driver = mGpuStats.vkDriverToLoad;
+ isIntendedDriverLoaded =
+ isLoaded && (mGpuStats.vkDriverFallback == GraphicsEnv::Driver::NONE);
+ }
+
+ sendGpuStatsLocked(driver, isIntendedDriverLoaded, driverLoadingTime);
+}
+
+void GraphicsEnv::clearDriverLoadingInfo(GraphicsEnv::Api api) {
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ if (api == GraphicsEnv::Api::API_GL) {
+ mGpuStats.glDriverToLoad = GraphicsEnv::Driver::NONE;
+ mGpuStats.glDriverFallback = GraphicsEnv::Driver::NONE;
+ }
+}
+
+static sp<IGpuService> getGpuService() {
+ const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
+ if (!binder) {
+ ALOGE("Failed to get gpu service");
+ return nullptr;
+ }
+
+ return interface_cast<IGpuService>(binder);
+}
+
+void GraphicsEnv::sendGpuStatsLocked(GraphicsEnv::Driver driver, bool isDriverLoaded,
+ int64_t driverLoadingTime) {
ATRACE_CALL();
// Do not sendGpuStats for those skipping the GraphicsEnvironment setup
@@ -187,20 +262,20 @@
"\tdriverPackageName[%s]\n"
"\tdriverVersionName[%s]\n"
"\tdriverVersionCode[%llu]\n"
- "\tappPackageName[%s]\n",
+ "\tappPackageName[%s]\n"
+ "\tdriver[%d]\n"
+ "\tisDriverLoaded[%d]\n"
+ "\tdriverLoadingTime[%lld]",
mGpuStats.driverPackageName.c_str(), mGpuStats.driverVersionName.c_str(),
- (unsigned long long)mGpuStats.driverVersionCode, mGpuStats.appPackageName.c_str());
+ (unsigned long long)mGpuStats.driverVersionCode, mGpuStats.appPackageName.c_str(),
+ static_cast<int32_t>(driver), isDriverLoaded, (long long)driverLoadingTime);
- const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
- if (!binder) {
- ALOGE("Failed to get gpu service for [%s]", mGpuStats.appPackageName.c_str());
- return;
+ const sp<IGpuService> gpuService = getGpuService();
+ if (gpuService) {
+ gpuService->setGpuStats(mGpuStats.driverPackageName, mGpuStats.driverVersionName,
+ mGpuStats.driverVersionCode, mGpuStats.appPackageName, driver,
+ isDriverLoaded, driverLoadingTime);
}
-
- interface_cast<IGpuService>(binder)->setGpuStats(mGpuStats.driverPackageName,
- mGpuStats.driverVersionName,
- mGpuStats.driverVersionCode,
- mGpuStats.appPackageName);
}
void* GraphicsEnv::loadLibrary(std::string name) {
diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp
index 762a27b..2a57caf 100644
--- a/libs/graphicsenv/IGpuService.cpp
+++ b/libs/graphicsenv/IGpuService.cpp
@@ -28,8 +28,9 @@
explicit BpGpuService(const sp<IBinder>& impl) : BpInterface<IGpuService>(impl) {}
virtual void setGpuStats(const std::string& driverPackageName,
- const std::string& driverVersionName, const uint64_t driverVersionCode,
- const std::string& appPackageName) {
+ const std::string& driverVersionName, uint64_t driverVersionCode,
+ const std::string& appPackageName, GraphicsEnv::Driver driver,
+ bool isDriverLoaded, int64_t driverLoadingTime) {
Parcel data, reply;
data.writeInterfaceToken(IGpuService::getInterfaceDescriptor());
@@ -37,6 +38,9 @@
data.writeUtf8AsUtf16(driverVersionName);
data.writeUint64(driverVersionCode);
data.writeUtf8AsUtf16(appPackageName);
+ data.writeInt32(static_cast<int32_t>(driver));
+ data.writeBool(isDriverLoaded);
+ data.writeInt64(driverLoadingTime);
remote()->transact(BnGpuService::SET_GPU_STATS, data, &reply);
}
@@ -65,7 +69,18 @@
std::string appPackageName;
if ((status = data.readUtf8FromUtf16(&appPackageName)) != OK) return status;
- setGpuStats(driverPackageName, driverVersionName, driverVersionCode, appPackageName);
+ int32_t driver;
+ if ((status = data.readInt32(&driver)) != OK) return status;
+
+ bool isDriverLoaded;
+ if ((status = data.readBool(&isDriverLoaded)) != OK) return status;
+
+ int64_t driverLoadingTime;
+ if ((status = data.readInt64(&driverLoadingTime)) != OK) return status;
+
+ setGpuStats(driverPackageName, driverVersionName, driverVersionCode, appPackageName,
+ static_cast<GraphicsEnv::Driver>(driver), isDriverLoaded,
+ driverLoadingTime);
return OK;
}
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index c4482b7..d88a5c1 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -28,11 +28,41 @@
struct NativeLoaderNamespace;
class GraphicsEnv {
+public:
+ enum Api {
+ API_GL = 0,
+ API_VK = 1,
+ };
+
+ enum Driver {
+ NONE = 0,
+ GL = 1,
+ GL_UPDATED = 2,
+ VULKAN = 3,
+ VULKAN_UPDATED = 4,
+ ANGLE = 5,
+ };
+
+private:
struct GpuStats {
std::string driverPackageName;
std::string driverVersionName;
uint64_t driverVersionCode;
std::string appPackageName;
+ Driver glDriverToLoad;
+ Driver glDriverFallback;
+ Driver vkDriverToLoad;
+ Driver vkDriverFallback;
+
+ GpuStats()
+ : driverPackageName(""),
+ driverVersionName(""),
+ driverVersionCode(0),
+ appPackageName(""),
+ glDriverToLoad(Driver::NONE),
+ glDriverFallback(Driver::NONE),
+ vkDriverToLoad(Driver::NONE),
+ vkDriverFallback(Driver::NONE) {}
};
public:
@@ -48,8 +78,11 @@
void setDriverPath(const std::string path);
android_namespace_t* getDriverNamespace();
void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
- const uint64_t versionCode, const std::string& appPackageName);
- void sendGpuStats();
+ uint64_t versionCode, const std::string& appPackageName);
+ void setDriverToLoad(Driver driver);
+ void setDriverLoaded(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
+ void clearDriverLoadingInfo(Api api);
+ void sendGpuStatsLocked(Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
bool shouldUseAngle(std::string appName);
bool shouldUseAngle();
@@ -82,6 +115,7 @@
GraphicsEnv() = default;
std::string mDriverPath;
+ std::mutex mStatsLock;
GpuStats mGpuStats;
std::string mAnglePath;
std::string mAngleAppName;
diff --git a/libs/graphicsenv/include/graphicsenv/IGpuService.h b/libs/graphicsenv/include/graphicsenv/IGpuService.h
index 1e74d60..bfde76f 100644
--- a/libs/graphicsenv/include/graphicsenv/IGpuService.h
+++ b/libs/graphicsenv/include/graphicsenv/IGpuService.h
@@ -18,6 +18,7 @@
#include <binder/IInterface.h>
#include <cutils/compiler.h>
+#include <graphicsenv/GraphicsEnv.h>
#include <vector>
@@ -29,12 +30,13 @@
*/
class IGpuService : public IInterface {
public:
- DECLARE_META_INTERFACE(GpuService);
+ DECLARE_META_INTERFACE(GpuService)
// set GPU stats from GraphicsEnvironment.
virtual void setGpuStats(const std::string& driverPackageName,
- const std::string& driverVersionName, const uint64_t driverVersionCode,
- const std::string& appPackageName) = 0;
+ const std::string& driverVersionName, uint64_t driverVersionCode,
+ const std::string& appPackageName, GraphicsEnv::Driver driver,
+ bool isDriverLoaded, int64_t driverLoadingTime) = 0;
};
class BnGpuService : public BnInterface<IGpuService> {
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 4cafe2b..259242b 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -27,6 +27,7 @@
#include <android/dlext.h>
#include <cutils/properties.h>
#include <log/log.h>
+#include <utils/Timers.h>
#ifndef __ANDROID_VNDK__
#include <graphicsenv/GraphicsEnv.h>
@@ -217,6 +218,7 @@
void* Loader::open(egl_connection_t* cnx)
{
ATRACE_CALL();
+ const nsecs_t openTime = systemTime();
void* dso;
driver_t* hnd = nullptr;
@@ -234,6 +236,8 @@
if (dso) {
hnd = new driver_t(dso);
} else {
+ android::GraphicsEnv::getInstance().clearDriverLoadingInfo(
+ android::GraphicsEnv::Api::API_GL);
// Always load EGL first
dso = load_driver("EGL", cnx, EGL);
if (dso) {
@@ -243,19 +247,30 @@
}
}
+ if (!hnd) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL,
+ false, systemTime() - openTime);
+ }
+
LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation");
cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so");
cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so");
cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so");
+ if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL,
+ false, systemTime() - openTime);
+ }
+
LOG_ALWAYS_FATAL_IF(!cnx->libEgl,
"couldn't load system EGL wrapper libraries");
LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1,
"couldn't load system OpenGL ES wrapper libraries");
- android::GraphicsEnv::getInstance().sendGpuStats();
+ android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL, true,
+ systemTime() - openTime);
return (void*)hnd;
}
@@ -591,17 +606,21 @@
void* dso = nullptr;
android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
if (ns) {
+ android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::ANGLE);
dso = load_angle(kind, ns, cnx);
}
#ifndef __ANDROID_VNDK__
if (!dso) {
android_namespace_t* ns = android::GraphicsEnv::getInstance().getDriverNamespace();
if (ns) {
+ android::GraphicsEnv::getInstance().setDriverToLoad(
+ android::GraphicsEnv::Driver::GL_UPDATED);
dso = load_updated_driver(kind, ns);
}
}
#endif
if (!dso) {
+ android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
dso = load_system_driver(kind);
if (!dso)
return nullptr;
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index 68c185c..8a9778a 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -38,8 +38,9 @@
GpuService::GpuService() = default;
void GpuService::setGpuStats(const std::string& driverPackageName,
- const std::string& driverVersionName, const uint64_t driverVersionCode,
- const std::string& appPackageName) {
+ const std::string& driverVersionName, uint64_t driverVersionCode,
+ const std::string& appPackageName, GraphicsEnv::Driver driver,
+ bool isDriverLoaded, int64_t driverLoadingTime) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mStateLock);
@@ -47,9 +48,13 @@
"\tdriverPackageName[%s]\n"
"\tdriverVersionName[%s]\n"
"\tdriverVersionCode[%llu]\n"
- "\tappPackageName[%s]\n",
+ "\tappPackageName[%s]\n"
+ "\tdriver[%d]\n"
+ "\tisDriverLoaded[%d]\n"
+ "\tdriverLoadingTime[%lld]",
driverPackageName.c_str(), driverVersionName.c_str(),
- (unsigned long long)driverVersionCode, appPackageName.c_str());
+ (unsigned long long)driverVersionCode, appPackageName.c_str(),
+ static_cast<int32_t>(driver), isDriverLoaded, (long long)driverLoadingTime);
}
status_t GpuService::shellCommand(int /*in*/, int out, int err, std::vector<String16>& args) {
diff --git a/services/gpuservice/GpuService.h b/services/gpuservice/GpuService.h
index 5304fa1..2756557 100644
--- a/services/gpuservice/GpuService.h
+++ b/services/gpuservice/GpuService.h
@@ -38,7 +38,8 @@
private:
// IGpuService interface
void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
- const uint64_t driverVersionCode, const std::string& appPackageName);
+ uint64_t driverVersionCode, const std::string& appPackageName,
+ GraphicsEnv::Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
// GpuStats access must be protected by mStateLock
std::mutex mStateLock;
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 3a8e34e..b3259de 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -33,6 +33,7 @@
#include <configstore/Utils.h>
#include <cutils/properties.h>
#include <graphicsenv/GraphicsEnv.h>
+#include <utils/Timers.h>
#include <utils/Trace.h>
#include <utils/Vector.h>
@@ -210,6 +211,8 @@
auto ns = android_get_exported_namespace("sphal");
if (!ns)
return -ENOENT;
+ android::GraphicsEnv::getInstance().setDriverToLoad(
+ android::GraphicsEnv::Driver::VULKAN);
return LoadDriver(ns, module);
}
@@ -219,12 +222,16 @@
auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
if (!ns)
return -ENOENT;
+ android::GraphicsEnv::getInstance().setDriverToLoad(
+ android::GraphicsEnv::Driver::VULKAN_UPDATED);
return LoadDriver(ns, module);
}
bool Hal::Open() {
ATRACE_CALL();
+ const nsecs_t openTime = systemTime();
+
ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
// Use a stub device unless we successfully open a real HAL device.
@@ -250,11 +257,12 @@
}
}
if (result != 0) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
return true;
}
- android::GraphicsEnv::getInstance().sendGpuStats();
hwvulkan_device_t* device;
ATRACE_BEGIN("hwvulkan module open");
@@ -263,6 +271,8 @@
reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
if (result != 0) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
// Any device with a Vulkan HAL should be able to open the device.
ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
result);
@@ -273,6 +283,9 @@
hal_.InitDebugReportIndex();
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, true, systemTime() - openTime);
+
return true;
}