[GPU Service] Separate GPU Service out of SurfaceFlinger.
Historically GPU service lives in SurfaceFlinger because it's a convenient
hack. This patch separates GPU service out of SurfaceFlinger. The GPU service
is a service that accesses to GPU, queries GPU capabilities and reports back.
Minor: Replace Vector with std::vector.
BUG: 118347356
Test: Build, flash and boot, `adb shell cmd gpuservice vkjson` to verify
Change-Id: If8feedc0a58bcd3c2e4111f8997117a618f5a516
Merged-In: If8feedc0a58bcd3c2e4111f8997117a618f5a516
diff --git a/services/gpuservice/Android.bp b/services/gpuservice/Android.bp
new file mode 100644
index 0000000..250bbee
--- /dev/null
+++ b/services/gpuservice/Android.bp
@@ -0,0 +1,74 @@
+filegroup {
+ name: "gpuservice_sources",
+ srcs: [
+ "GpuService.cpp",
+ ],
+}
+
+filegroup {
+ name: "gpuservice_binary_sources",
+ srcs: ["main_gpuservice.cpp"],
+}
+
+cc_defaults {
+ name: "gpuservice_defaults",
+ cflags: [
+ "-DLOG_TAG=\"GpuService\"",
+ "-Wall",
+ "-Werror",
+ "-Wformat",
+ "-Wthread-safety",
+ "-Wunused",
+ "-Wunreachable-code",
+ ],
+ cppflags: ["-std=c++1z"],
+ srcs: [
+ ":gpuservice_sources",
+ ],
+ include_dirs: [
+ "frameworks/native/vulkan/vkjson",
+ "frameworks/native/vulkan/include",
+ ],
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libutils",
+ "libvulkan",
+ ],
+ static_libs: [
+ "libvkjson",
+ ],
+}
+
+cc_defaults {
+ name: "gpuservice_production_defaults",
+ defaults: ["gpuservice_defaults"],
+ cflags: [
+ "-fvisibility=hidden",
+ "-fwhole-program-vtables", // requires ThinLTO
+ ],
+ lto: {
+ thin: true,
+ },
+}
+
+cc_defaults {
+ name: "gpuservice_binary",
+ defaults: ["gpuservice_defaults"],
+ whole_static_libs: [
+ "libsigchain",
+ ],
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+ ldflags: ["-Wl,--export-dynamic"],
+}
+
+cc_binary {
+ name: "gpuservice",
+ defaults: ["gpuservice_binary"],
+ init_rc: ["gpuservice.rc"],
+ srcs: [":gpuservice_binary_sources"],
+}
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
new file mode 100644
index 0000000..e4ca6bc
--- /dev/null
+++ b/services/gpuservice/GpuService.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#include "GpuService.h"
+
+#include <binder/IResultReceiver.h>
+#include <binder/Parcel.h>
+#include <utils/String8.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);
+ status_t cmd_vkjson(int out, int err);
+}
+
+const char* const GpuService::SERVICE_NAME = "gpuservice";
+
+GpuService::GpuService() = default;
+
+status_t GpuService::shellCommand(int /*in*/, int out, int err,
+ std::vector<String16>& args) {
+ ALOGV("GpuService::shellCommand");
+ for (size_t i = 0, n = args.size(); i < n; i++)
+ ALOGV(" arg[%zu]: '%s'", i, String8(args[i]).string());
+
+ if (args.size() >= 1) {
+ if (args[0] == String16("vkjson"))
+ return cmd_vkjson(out, err);
+ if (args[0] == String16("help"))
+ return cmd_help(out);
+ }
+ // no command, or unrecognized command
+ cmd_help(err);
+ return BAD_VALUE;
+}
+
+namespace {
+
+status_t cmd_help(int out) {
+ FILE* outs = fdopen(out, "w");
+ if (!outs) {
+ ALOGE("vkjson: failed to create out stream: %s (%d)", strerror(errno),
+ errno);
+ return BAD_VALUE;
+ }
+ fprintf(outs,
+ "GPU Service commands:\n"
+ " vkjson dump Vulkan properties as JSON\n");
+ fclose(outs);
+ return NO_ERROR;
+}
+
+void vkjsonPrint(FILE* out) {
+ std::string json = VkJsonInstanceToJson(VkJsonGetInstance());
+ fwrite(json.data(), 1, json.size(), out);
+ fputc('\n', out);
+}
+
+status_t cmd_vkjson(int out, int /*err*/) {
+ FILE* outs = fdopen(out, "w");
+ if (!outs) {
+ int errnum = errno;
+ ALOGE("vkjson: failed to create output stream: %s", strerror(errnum));
+ return -errnum;
+ }
+ vkjsonPrint(outs);
+ fclose(outs);
+ return NO_ERROR;
+}
+
+} // anonymous namespace
+
+} // namespace android
diff --git a/services/gpuservice/GpuService.h b/services/gpuservice/GpuService.h
new file mode 100644
index 0000000..e2b396e
--- /dev/null
+++ b/services/gpuservice/GpuService.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#ifndef ANDROID_GPUSERVICE_H
+#define ANDROID_GPUSERVICE_H
+
+#include <vector>
+
+#include <binder/IInterface.h>
+#include <cutils/compiler.h>
+
+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;
+
+ GpuService() ANDROID_API;
+
+protected:
+ status_t shellCommand(int in, int out, int err,
+ std::vector<String16>& args) override;
+};
+
+} // namespace android
+
+#endif // ANDROID_GPUSERVICE_H
diff --git a/services/gpuservice/gpuservice.rc b/services/gpuservice/gpuservice.rc
new file mode 100644
index 0000000..d23cf46
--- /dev/null
+++ b/services/gpuservice/gpuservice.rc
@@ -0,0 +1,4 @@
+service gpuservice /system/bin/gpuservice
+ class core
+ user gpu_service
+ group graphics
diff --git a/services/gpuservice/main_gpuservice.cpp b/services/gpuservice/main_gpuservice.cpp
new file mode 100644
index 0000000..64aafca
--- /dev/null
+++ b/services/gpuservice/main_gpuservice.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <sys/resource.h>
+#include "GpuService.h"
+
+using namespace android;
+
+int main(int /* argc */, char** /* argv */) {
+ signal(SIGPIPE, SIG_IGN);
+
+ // publish GpuService
+ sp<GpuService> gpuservice = new GpuService();
+ sp<IServiceManager> sm(defaultServiceManager());
+ sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
+
+ // limit the number of binder threads to 4.
+ ProcessState::self()->setThreadPoolMaxThreadCount(4);
+
+ // start the thread pool
+ sp<ProcessState> ps(ProcessState::self());
+ ps->startThreadPool();
+ ps->giveThreadPoolName();
+ IPCThreadState::self()->joinThreadPool();
+
+ return 0;
+}