| /* |
| * Copyright 2019 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "tools/sk_app/DawnWindowContext.h" |
| #include "tools/sk_app/unix/WindowContextFactory_unix.h" |
| #include "dawn/native/DawnNative.h" |
| #include "dawn/native/VulkanBackend.h" |
| #include "src/ports/SkOSLibrary.h" |
| #include "tools/gpu/vk/VkTestUtils.h" |
| |
| #include <vulkan/vulkan.h> |
| #include <X11/Xlib-xcb.h> |
| |
| using sk_app::window_context_factory::XlibWindowInfo; |
| using sk_app::DisplayParams; |
| using sk_app::DawnWindowContext; |
| |
| namespace sk_app { |
| |
| class DawnVulkanWindowContext_xlib : public DawnWindowContext { |
| public: |
| DawnVulkanWindowContext_xlib(const XlibWindowInfo&, const DisplayParams&); |
| ~DawnVulkanWindowContext_xlib() override {} |
| wgpu::Device onInitializeContext() override; |
| void onDestroyContext() override {} |
| DawnSwapChainImplementation createSwapChainImplementation( |
| int width, int height, const DisplayParams& params) override; |
| void onSwapBuffers() override {} |
| |
| private: |
| Display* fDisplay; |
| XWindow fWindow; |
| VkSurfaceKHR fVkSurface = nullptr; |
| }; |
| |
| DawnVulkanWindowContext_xlib::DawnVulkanWindowContext_xlib(const XlibWindowInfo& winInfo, |
| const DisplayParams& params) |
| : DawnWindowContext(params, wgpu::TextureFormat::BGRA8Unorm) |
| , fDisplay(winInfo.fDisplay) |
| , fWindow(winInfo.fWindow) { |
| XWindow root; |
| int x, y; |
| unsigned int border_width, depth; |
| unsigned int width, height; |
| XGetGeometry(fDisplay, fWindow, &root, &x, &y, &width, &height, &border_width, &depth); |
| this->initializeContext(width, height); |
| } |
| |
| DawnSwapChainImplementation DawnVulkanWindowContext_xlib::createSwapChainImplementation( |
| int width, int height, const DisplayParams& params) { |
| return dawn::native::vulkan::CreateNativeSwapChainImpl(fDevice.Get(), fVkSurface); |
| } |
| |
| wgpu::Device DawnVulkanWindowContext_xlib::onInitializeContext() { |
| wgpu::Device device = this->createDevice(wgpu::BackendType::Vulkan); |
| if (!device) { |
| return nullptr; |
| } |
| |
| void *vkLib = SkLoadDynamicLibrary("libvulkan.so.1"); |
| if (!vkLib) { |
| return nullptr; |
| } |
| VkInstance instance = dawn::native::vulkan::GetInstance(device.Get()); |
| if (!instance) { |
| return nullptr; |
| } |
| auto createXcbSurfaceKHR = |
| reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>(SkGetProcedureAddress(vkLib, |
| "vkCreateXcbSurfaceKHR")); |
| if (!createXcbSurfaceKHR) { |
| printf("couldn't get extensions :(\n"); |
| return nullptr; |
| } |
| |
| VkXcbSurfaceCreateInfoKHR surfaceCreateInfo; |
| memset(&surfaceCreateInfo, 0, sizeof(VkXcbSurfaceCreateInfoKHR)); |
| surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; |
| surfaceCreateInfo.pNext = nullptr; |
| surfaceCreateInfo.flags = 0; |
| surfaceCreateInfo.connection = XGetXCBConnection(fDisplay); |
| surfaceCreateInfo.window = fWindow; |
| |
| createXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &fVkSurface); |
| return device; |
| } |
| |
| namespace window_context_factory { |
| |
| std::unique_ptr<WindowContext> MakeDawnVulkanForXlib(const XlibWindowInfo& winInfo, |
| const DisplayParams& params) { |
| std::unique_ptr<WindowContext> ctx(new DawnVulkanWindowContext_xlib(winInfo, params)); |
| if (!ctx->isValid()) { |
| return nullptr; |
| } |
| return ctx; |
| } |
| |
| } |
| |
| } // namespace sk_app |