summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/Android.mk8
-rw-r--r--services/surfaceflinger/GpuService.cpp175
-rw-r--r--services/surfaceflinger/GpuService.h57
-rw-r--r--services/surfaceflinger/main_surfaceflinger.cpp7
4 files changed, 245 insertions, 2 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 44a3334033..fb6307ee59 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -12,6 +12,7 @@ LOCAL_SRC_FILES := \
EventThread.cpp \
FenceTracker.cpp \
FrameTracker.cpp \
+ GpuService.cpp \
Layer.cpp \
LayerDim.cpp \
MessageQueue.cpp \
@@ -37,6 +38,9 @@ LOCAL_SRC_FILES := \
RenderEngine/GLES11RenderEngine.cpp \
RenderEngine/GLES20RenderEngine.cpp
+LOCAL_C_INCLUDES := \
+ frameworks/native/vulkan/include \
+ external/vulkan-validation-layers/libs/vkjson
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
@@ -106,6 +110,7 @@ endif
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
LOCAL_CFLAGS += -std=c++14
+LOCAL_STATIC_LIBRARIES := libvkjson
LOCAL_SHARED_LIBRARIES := \
libcutils \
liblog \
@@ -118,7 +123,8 @@ LOCAL_SHARED_LIBRARIES := \
libbinder \
libui \
libgui \
- libpowermanager
+ libpowermanager \
+ libvulkan
LOCAL_MODULE := libsurfaceflinger
diff --git a/services/surfaceflinger/GpuService.cpp b/services/surfaceflinger/GpuService.cpp
new file mode 100644
index 0000000000..0c2997191c
--- /dev/null
+++ b/services/surfaceflinger/GpuService.cpp
@@ -0,0 +1,175 @@
+/*
+ * 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/Parcel.h>
+#include <utils/String8.h>
+#include <vkjson.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class BpGpuService : public BpInterface<IGpuService>
+{
+public:
+ 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)
+{
+ switch (code) {
+ case SHELL_COMMAND_TRANSACTION: {
+ int in = data.readFileDescriptor();
+ int out = data.readFileDescriptor();
+ int err = data.readFileDescriptor();
+ int argc = data.readInt32();
+ Vector<String16> args;
+ for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
+ args.add(data.readString16());
+ }
+ return shellCommand(in, out, err, args);
+ }
+
+ 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 = "gpu";
+
+GpuService::GpuService() {}
+
+status_t GpuService::shellCommand(int /*in*/, int out, int err,
+ 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[0] == String16("vkjson"))
+ return cmd_vkjson(out, err);
+ else if (args[0] == String16("help"))
+ return cmd_help(out);
+
+ return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+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 device capabilities as JSON\n");
+ fclose(outs);
+ return NO_ERROR;
+}
+
+VkResult vkjsonPrint(FILE* out, FILE* err) {
+ VkResult result;
+
+ const VkApplicationInfo app_info = {
+ VK_STRUCTURE_TYPE_APPLICATION_INFO, nullptr,
+ "vkjson", 1, /* app name, version */
+ "", 0, /* engine name, version */
+ VK_API_VERSION
+ };
+ const VkInstanceCreateInfo instance_info = {
+ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr,
+ 0, /* flags */
+ &app_info,
+ 0, nullptr, /* layers */
+ 0, nullptr, /* extensions */
+ };
+ VkInstance instance;
+ result = vkCreateInstance(&instance_info, nullptr, &instance);
+ if (result != VK_SUCCESS) {
+ fprintf(err, "vkCreateInstance failed: %d\n", result);
+ return result;
+ }
+
+ uint32_t ngpu = 0;
+ result = vkEnumeratePhysicalDevices(instance, &ngpu, nullptr);
+ if (result != VK_SUCCESS) {
+ fprintf(err, "vkEnumeratePhysicalDevices failed: %d\n", result);
+ return result;
+ }
+ std::vector<VkPhysicalDevice> gpus(ngpu, VK_NULL_HANDLE);
+ result = vkEnumeratePhysicalDevices(instance, &ngpu, gpus.data());
+ if (result != VK_SUCCESS) {
+ fprintf(err, "vkEnumeratePhysicalDevices failed: %d\n", result);
+ return result;
+ }
+
+ for (size_t i = 0, n = gpus.size(); i < n; i++) {
+ auto props = VkJsonGetAllProperties(gpus[i]);
+ std::string json = VkJsonAllPropertiesToJson(props);
+ fwrite(json.data(), 1, json.size(), out);
+ if (i < n - 1)
+ fputc(',', out);
+ fputc('\n', out);
+ }
+
+ vkDestroyInstance(instance, nullptr);
+
+ return VK_SUCCESS;
+}
+
+status_t cmd_vkjson(int out, int err) {
+ int errnum;
+ FILE* outs = fdopen(out, "w");
+ if (!outs) {
+ errnum = errno;
+ ALOGE("vkjson: failed to create output stream: %s", strerror(errnum));
+ return -errnum;
+ }
+ FILE* errs = fdopen(err, "w");
+ if (!errs) {
+ errnum = errno;
+ ALOGE("vkjson: failed to create error stream: %s", strerror(errnum));
+ fclose(outs);
+ return -errnum;
+ }
+ fprintf(outs, "[\n");
+ VkResult result = vkjsonPrint(outs, errs);
+ fprintf(outs, "]\n");
+ fclose(errs);
+ fclose(outs);
+ return result >= 0 ? NO_ERROR : UNKNOWN_ERROR;
+}
+
+} // anonymous namespace
+
+} // namespace android
diff --git a/services/surfaceflinger/GpuService.h b/services/surfaceflinger/GpuService.h
new file mode 100644
index 0000000000..b8c28d2495
--- /dev/null
+++ b/services/surfaceflinger/GpuService.h
@@ -0,0 +1,57 @@
+/*
+ * 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 <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,
+ Vector<String16>& args) = 0;
+
+ virtual 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:
+ virtual status_t shellCommand(int in, int out, int err,
+ Vector<String16>& args) override;
+};
+
+} // namespace android
+
+#endif // ANDROID_GPUSERVICE_H
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index 4cd7aebf6b..97a1e8b62b 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -21,6 +21,7 @@
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
+#include "GpuService.h"
#include "SurfaceFlinger.h"
using namespace android;
@@ -56,7 +57,11 @@ int main(int, char**) {
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
- // run in this thread
+ // publish GpuService
+ sp<GpuService> gpuservice = new GpuService();
+ sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
+
+ // run surface flinger in this thread
flinger->run();
return 0;