diff options
-rw-r--r-- | services/surfaceflinger/Android.mk | 8 | ||||
-rw-r--r-- | services/surfaceflinger/GpuService.cpp | 175 | ||||
-rw-r--r-- | services/surfaceflinger/GpuService.h | 57 | ||||
-rw-r--r-- | services/surfaceflinger/main_surfaceflinger.cpp | 7 |
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; |