1 /*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "tools/window/GraphiteDawnWindowContext.h"
9 #include "tools/window/unix/WindowContextFactory_unix.h"
10
11 using skwindow::XlibWindowInfo;
12 using skwindow::DisplayParams;
13 using skwindow::internal::GraphiteDawnWindowContext;
14
15 namespace {
16
17 class GraphiteDawnVulkanWindowContext_unix : public GraphiteDawnWindowContext {
18 public:
19 GraphiteDawnVulkanWindowContext_unix(const XlibWindowInfo& info, const DisplayParams& params);
20
21 ~GraphiteDawnVulkanWindowContext_unix() override;
22
23 bool onInitializeContext() override;
24 void onDestroyContext() override;
25 void resize(int w, int h) override;
26
27 private:
28 Display* fDisplay;
29 XWindow fWindow;
30 };
31
GraphiteDawnVulkanWindowContext_unix(const XlibWindowInfo & info,const DisplayParams & params)32 GraphiteDawnVulkanWindowContext_unix::GraphiteDawnVulkanWindowContext_unix(
33 const XlibWindowInfo& info,
34 const DisplayParams& params)
35 : GraphiteDawnWindowContext(params, wgpu::TextureFormat::BGRA8Unorm)
36 , fDisplay(info.fDisplay)
37 , fWindow(info.fWindow) {
38 XWindow root;
39 int x, y;
40 unsigned int border_width, depth;
41 unsigned int width, height;
42 XGetGeometry(fDisplay, fWindow, &root, &x, &y, &width, &height, &border_width, &depth);
43 this->initializeContext(width, height);
44 }
45
~GraphiteDawnVulkanWindowContext_unix()46 GraphiteDawnVulkanWindowContext_unix::~GraphiteDawnVulkanWindowContext_unix() {
47 this->destroyContext();
48 }
49
onInitializeContext()50 bool GraphiteDawnVulkanWindowContext_unix::onInitializeContext() {
51 SkASSERT(!!fWindow);
52
53 auto device = this->createDevice(wgpu::BackendType::Vulkan);
54 if (!device) {
55 SkASSERT(device);
56 return false;
57 }
58
59 wgpu::SurfaceDescriptorFromXlibWindow surfaceChainedDesc;
60 surfaceChainedDesc.display = fDisplay;
61 surfaceChainedDesc.window = fWindow;
62
63 wgpu::SurfaceDescriptor surfaceDesc;
64 surfaceDesc.nextInChain = &surfaceChainedDesc;
65
66 auto surface = wgpu::Instance(fInstance->Get()).CreateSurface(&surfaceDesc);
67 if (!surface) {
68 SkASSERT(false);
69 return false;
70 }
71
72 fDevice = std::move(device);
73 fSurface = std::move(surface);
74 fSwapChain = this->createSwapChain();
75
76 return true;
77 }
78
onDestroyContext()79 void GraphiteDawnVulkanWindowContext_unix::onDestroyContext() {}
80
resize(int w,int h)81 void GraphiteDawnVulkanWindowContext_unix::resize(int w, int h) {
82 fSwapChain = this->createSwapChain();
83 }
84
85 } // anonymous namespace
86
87 namespace skwindow {
88
MakeGraphiteDawnVulkanForXlib(const XlibWindowInfo & info,const DisplayParams & params)89 std::unique_ptr<WindowContext> MakeGraphiteDawnVulkanForXlib(const XlibWindowInfo& info,
90 const DisplayParams& params) {
91 std::unique_ptr<WindowContext> ctx(new GraphiteDawnVulkanWindowContext_unix(info, params));
92 if (!ctx->isValid()) {
93 return nullptr;
94 }
95 return ctx;
96 }
97
98 } // namespace skwindow
99