Game Driver: make GpuService the GpuStats holder
Move IGpuService to graphicsenv to avoid dependency circle. Add ATRACE
to GraphicsEnv. Implement the prototype SET_GPU_STATS IPC to collect
GpuStats from applications.
Bug: 123529932
Test: Build, flash and boot.
Change-Id: I7d76324c5adb6ad00f1e5420ab2c7f4067f33253
diff --git a/libs/graphicsenv/Android.bp b/libs/graphicsenv/Android.bp
index 280c14a..d940752 100644
--- a/libs/graphicsenv/Android.bp
+++ b/libs/graphicsenv/Android.bp
@@ -17,14 +17,17 @@
srcs: [
"GraphicsEnv.cpp",
+ "IGpuService.cpp"
],
cflags: ["-Wall", "-Werror"],
shared_libs: [
"libbase",
+ "libbinder",
"libcutils",
"liblog",
+ "libutils",
],
export_include_dirs: ["include"],
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 337308b..c20d54b 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -14,8 +14,11 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
//#define LOG_NDEBUG 1
#define LOG_TAG "GraphicsEnv"
+
#include <graphicsenv/GraphicsEnv.h>
#include <dlfcn.h>
@@ -25,15 +28,16 @@
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android/dlext.h>
+#include <binder/IServiceManager.h>
#include <cutils/properties.h>
+#include <graphicsenv/IGpuService.h>
#include <log/log.h>
#include <sys/prctl.h>
+#include <utils/Trace.h>
#include <memory>
#include <string>
-#include <dlfcn.h>
-
// TODO(b/37049319) Get this from a header once one exists
extern "C" {
android_namespace_t* android_get_exported_namespace(const char*);
@@ -155,9 +159,16 @@
void GraphicsEnv::setGpuStats(const std::string driverPackageName,
const std::string driverVersionName, const uint64_t driverVersionCode,
const std::string appPackageName) {
- ALOGV("setGpuStats: drvPkgName[%s], drvVerName[%s], drvVerCode[%lld], appPkgName[%s]",
- driverPackageName.c_str(), driverVersionName.c_str(), (long long)driverVersionCode,
- appPackageName.c_str());
+ ATRACE_CALL();
+
+ ALOGV("setGpuStats:\n"
+ "\tdriverPackageName[%s]\n"
+ "\tdriverVersionName[%s]\n"
+ "\tdriverVersionCode[%llu]\n"
+ "\tappPackageName[%s]\n",
+ driverPackageName.c_str(), driverVersionName.c_str(),
+ (unsigned long long)driverVersionCode, appPackageName.c_str());
+
mGpuStats = {
.driverPackageName = driverPackageName,
.driverVersionName = driverVersionName,
@@ -166,6 +177,32 @@
};
}
+void GraphicsEnv::sendGpuStats() {
+ ATRACE_CALL();
+
+ // Do not sendGpuStats for those skipping the GraphicsEnvironment setup
+ if (mGpuStats.appPackageName.empty()) return;
+
+ ALOGV("sendGpuStats:\n"
+ "\tdriverPackageName[%s]\n"
+ "\tdriverVersionName[%s]\n"
+ "\tdriverVersionCode[%llu]\n"
+ "\tappPackageName[%s]\n",
+ mGpuStats.driverPackageName.c_str(), mGpuStats.driverVersionName.c_str(),
+ (unsigned long long)mGpuStats.driverVersionCode, mGpuStats.appPackageName.c_str());
+
+ const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
+ if (!binder) {
+ ALOGE("Failed to get gpu service for [%s]", mGpuStats.appPackageName.c_str());
+ return;
+ }
+
+ interface_cast<IGpuService>(binder)->setGpuStats(mGpuStats.driverPackageName,
+ mGpuStats.driverVersionName,
+ mGpuStats.driverVersionCode,
+ mGpuStats.appPackageName);
+}
+
void* GraphicsEnv::loadLibrary(std::string name) {
const android_dlextinfo dlextinfo = {
.flags = ANDROID_DLEXT_USE_NAMESPACE,
diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp
new file mode 100644
index 0000000..98a6395
--- /dev/null
+++ b/libs/graphicsenv/IGpuService.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GpuService"
+
+#include <graphicsenv/IGpuService.h>
+
+#include <binder/IResultReceiver.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class BpGpuService : public BpInterface<IGpuService> {
+public:
+ 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) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGpuService::getInterfaceDescriptor());
+
+ data.writeUtf8AsUtf16(driverPackageName);
+ data.writeUtf8AsUtf16(driverVersionName);
+ data.writeUint64(driverVersionCode);
+ data.writeUtf8AsUtf16(appPackageName);
+
+ remote()->transact(BnGpuService::SET_GPU_STATS, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(GpuService, "android.graphicsenv.IGpuService");
+
+status_t BnGpuService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags) {
+ ALOGV("onTransact code[0x%X]", code);
+
+ status_t status;
+ switch (code) {
+ case SET_GPU_STATS: {
+ CHECK_INTERFACE(IGpuService, data, reply);
+
+ std::string driverPackageName;
+ if ((status = data.readUtf8FromUtf16(&driverPackageName)) != OK) return status;
+
+ std::string driverVersionName;
+ if ((status = data.readUtf8FromUtf16(&driverVersionName)) != OK) return status;
+
+ uint64_t driverVersionCode;
+ if ((status = data.readUint64(&driverVersionCode)) != OK) return status;
+
+ std::string appPackageName;
+ if ((status = data.readUtf8FromUtf16(&appPackageName)) != OK) return status;
+
+ setGpuStats(driverPackageName, driverVersionName, driverVersionCode, appPackageName);
+
+ return OK;
+ }
+ case SHELL_COMMAND_TRANSACTION: {
+ int in = data.readFileDescriptor();
+ int out = data.readFileDescriptor();
+ int err = data.readFileDescriptor();
+
+ std::vector<String16> args;
+ data.readString16Vector(&args);
+
+ sp<IBinder> unusedCallback;
+ if ((status = data.readNullableStrongBinder(&unusedCallback)) != OK) return status;
+
+ sp<IResultReceiver> resultReceiver;
+ if ((status = data.readNullableStrongBinder(&resultReceiver)) != OK) return status;
+
+ status = shellCommand(in, out, err, args);
+ if (resultReceiver != nullptr) resultReceiver->send(status);
+
+ return OK;
+ }
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+} // namespace android
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index a247bec..d4edfa0 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -49,6 +49,7 @@
android_namespace_t* getDriverNamespace();
void setGpuStats(const std::string driverPackageName, const std::string driverVersionName,
const uint64_t versionCode, const std::string appPackageName);
+ void sendGpuStats();
bool shouldUseAngle(std::string appName);
bool shouldUseAngle();
diff --git a/libs/graphicsenv/include/graphicsenv/IGpuService.h b/libs/graphicsenv/include/graphicsenv/IGpuService.h
new file mode 100644
index 0000000..c080c53
--- /dev/null
+++ b/libs/graphicsenv/include/graphicsenv/IGpuService.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/IInterface.h>
+#include <cutils/compiler.h>
+
+#include <vector>
+
+namespace android {
+
+/*
+ * This class defines the Binder IPC interface for GPU-related queries and
+ * control.
+ */
+class IGpuService : public IInterface {
+public:
+ 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;
+};
+
+class BnGpuService : public BnInterface<IGpuService> {
+public:
+ enum IGpuServiceTag {
+ SET_GPU_STATS = IBinder::FIRST_CALL_TRANSACTION,
+ // Always append new enum to the end.
+ };
+
+ status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags = 0) override;
+
+protected:
+ virtual status_t shellCommand(int in, int out, int err, std::vector<String16>& args) = 0;
+};
+
+} // namespace android
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 8a409ae..4cafe2b 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -255,6 +255,8 @@
LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1,
"couldn't load system OpenGL ES wrapper libraries");
+ android::GraphicsEnv::getInstance().sendGpuStats();
+
return (void*)hnd;
}
diff --git a/services/gpuservice/Android.bp b/services/gpuservice/Android.bp
index 47bed65..e21d8e7 100644
--- a/services/gpuservice/Android.bp
+++ b/services/gpuservice/Android.bp
@@ -30,6 +30,8 @@
],
shared_libs: [
"libbinder",
+ "libcutils",
+ "libgraphicsenv",
"liblog",
"libutils",
"libvulkan",
@@ -59,6 +61,7 @@
],
shared_libs: [
"libbinder",
+ "libcutils",
"liblog",
"libutils",
],
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index 150896c..9906dea 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -14,48 +14,19 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include "GpuService.h"
#include <binder/IResultReceiver.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
+#include <utils/Trace.h>
+
#include <vkjson.h>
namespace android {
-class BpGpuService : public BpInterface<IGpuService> {
-public:
- explicit BpGpuService(const sp<IBinder>& impl) : BpInterface<IGpuService>(impl) {}
-};
-
-IMPLEMENT_META_INTERFACE(GpuService, "android.ui.IGpuService");
-
-status_t BnGpuService::onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags) {
- status_t status;
- switch (code) {
- case SHELL_COMMAND_TRANSACTION: {
- int in = data.readFileDescriptor();
- int out = data.readFileDescriptor();
- int err = data.readFileDescriptor();
- std::vector<String16> args;
- data.readString16Vector(&args);
- sp<IBinder> unusedCallback;
- sp<IResultReceiver> resultReceiver;
- if ((status = data.readNullableStrongBinder(&unusedCallback)) != OK)
- return status;
- if ((status = data.readNullableStrongBinder(&resultReceiver)) != OK)
- return status;
- status = shellCommand(in, out, err, args);
- if (resultReceiver != nullptr)
- resultReceiver->send(status);
- return OK;
- }
-
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
namespace {
status_t cmd_help(int out);
@@ -66,9 +37,25 @@
GpuService::GpuService() = default;
-status_t GpuService::shellCommand(int /*in*/, int out, int err,
- std::vector<String16>& args) {
- ALOGV("GpuService::shellCommand");
+void GpuService::setGpuStats(const std::string driverPackageName,
+ const std::string driverVersionName, const uint64_t driverVersionCode,
+ const std::string appPackageName) {
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mStateLock);
+ ALOGV("Received:\n"
+ "\tdriverPackageName[%s]\n"
+ "\tdriverVersionName[%s]\n"
+ "\tdriverVersionCode[%llu]\n"
+ "\tappPackageName[%s]\n",
+ driverPackageName.c_str(), driverVersionName.c_str(),
+ (unsigned long long)driverVersionCode, appPackageName.c_str());
+}
+
+status_t GpuService::shellCommand(int /*in*/, int out, int err, std::vector<String16>& args) {
+ ATRACE_CALL();
+
+ ALOGV("shellCommand");
for (size_t i = 0, n = args.size(); i < n; i++)
ALOGV(" arg[%zu]: '%s'", i, String8(args[i]).string());
diff --git a/services/gpuservice/GpuService.h b/services/gpuservice/GpuService.h
index e2b396e..edfd364 100644
--- a/services/gpuservice/GpuService.h
+++ b/services/gpuservice/GpuService.h
@@ -17,31 +17,15 @@
#ifndef ANDROID_GPUSERVICE_H
#define ANDROID_GPUSERVICE_H
-#include <vector>
-
#include <binder/IInterface.h>
#include <cutils/compiler.h>
+#include <graphicsenv/IGpuService.h>
+
+#include <mutex>
+#include <vector>
namespace android {
-/*
- * This class defines the Binder IPC interface for GPU-related queries and
- * control.
- */
-class IGpuService : public IInterface {
-public:
- DECLARE_META_INTERFACE(GpuService);
-};
-
-class BnGpuService: public BnInterface<IGpuService> {
-protected:
- virtual status_t shellCommand(int in, int out, int err,
- std::vector<String16>& args) = 0;
-
- status_t onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags = 0) override;
-};
-
class GpuService : public BnGpuService {
public:
static const char* const SERVICE_NAME ANDROID_API;
@@ -49,8 +33,15 @@
GpuService() ANDROID_API;
protected:
- status_t shellCommand(int in, int out, int err,
- std::vector<String16>& args) override;
+ status_t shellCommand(int in, int out, int err, std::vector<String16>& args) override;
+
+private:
+ // IGpuService interface
+ void setGpuStats(const std::string driverPackageName, const std::string driverVersionName,
+ const uint64_t driverVersionCode, const std::string appPackageName);
+
+ // GpuStats access must be protected by mStateLock
+ std::mutex mStateLock;
};
} // namespace android
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 421f727..3a8e34e 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -254,6 +254,8 @@
return true;
}
+ android::GraphicsEnv::getInstance().sendGpuStats();
+
hwvulkan_device_t* device;
ATRACE_BEGIN("hwvulkan module open");
result =