summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/GpuService.cpp
diff options
context:
space:
mode:
author Jesse Hall <jessehall@google.com> 2016-04-06 22:01:25 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2016-04-06 22:01:25 +0000
commit16ce3cec53f3daf18f851c776e50e146f2dfacef (patch)
tree6bdd0020476733afc8903d86ca50492c36cdbac9 /services/surfaceflinger/GpuService.cpp
parent10a91a5a5b0c9e992a3ccf368ead9e27be75b15e (diff)
parent8b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0 (diff)
Merge changes from topic 'vkjson' into nyc-dev
* changes: GpuService: Add 'help' and 'vkjson' commands Add service "gpu" in the SurfaceFlinger process
Diffstat (limited to 'services/surfaceflinger/GpuService.cpp')
-rw-r--r--services/surfaceflinger/GpuService.cpp175
1 files changed, 175 insertions, 0 deletions
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