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 // Important to put this first because webgpu_cpp.h and X.h don't get along.
8 // Include these first, before X11 defines None, Success, Status etc.
9 #include "dawn/native/DawnNative.h" // NO_G3_REWRITE
10 #include "webgpu/webgpu_cpp.h" // NO_G3_REWRITE
11
12 #include "tools/window/unix/GraphiteDawnVulkanWindowContext_unix.h"
13
14 #include "tools/window/GraphiteDawnWindowContext.h"
15 #include "tools/window/unix/XlibWindowInfo.h"
16
17 using skwindow::XlibWindowInfo;
18 using skwindow::DisplayParams;
19 using skwindow::internal::GraphiteDawnWindowContext;
20
21 namespace {
22
23 class GraphiteDawnVulkanWindowContext_unix : public GraphiteDawnWindowContext {
24 public:
25 GraphiteDawnVulkanWindowContext_unix(const XlibWindowInfo& info,
26 std::unique_ptr<const DisplayParams> params);
27
28 ~GraphiteDawnVulkanWindowContext_unix() override;
29
30 bool onInitializeContext() override;
31 void onDestroyContext() override;
32 void resize(int w, int h) override;
33
34 private:
35 Display* fDisplay;
36 XWindow fWindow;
37 };
38
GraphiteDawnVulkanWindowContext_unix(const XlibWindowInfo & info,std::unique_ptr<const DisplayParams> params)39 GraphiteDawnVulkanWindowContext_unix::GraphiteDawnVulkanWindowContext_unix(
40 const XlibWindowInfo& info, std::unique_ptr<const DisplayParams> params)
41 : GraphiteDawnWindowContext(std::move(params), wgpu::TextureFormat::BGRA8Unorm)
42 , fDisplay(info.fDisplay)
43 , fWindow(info.fWindow) {
44 XWindow root;
45 int x, y;
46 unsigned int border_width, depth;
47 unsigned int width, height;
48 XGetGeometry(fDisplay, fWindow, &root, &x, &y, &width, &height, &border_width, &depth);
49 this->initializeContext(width, height);
50 }
51
~GraphiteDawnVulkanWindowContext_unix()52 GraphiteDawnVulkanWindowContext_unix::~GraphiteDawnVulkanWindowContext_unix() {
53 this->destroyContext();
54 }
55
onInitializeContext()56 bool GraphiteDawnVulkanWindowContext_unix::onInitializeContext() {
57 SkASSERT(!!fWindow);
58
59 auto device = this->createDevice(wgpu::BackendType::Vulkan);
60 if (!device) {
61 SkASSERT(device);
62 return false;
63 }
64
65 wgpu::SurfaceDescriptorFromXlibWindow surfaceChainedDesc;
66 surfaceChainedDesc.display = fDisplay;
67 surfaceChainedDesc.window = fWindow;
68
69 wgpu::SurfaceDescriptor surfaceDesc;
70 surfaceDesc.nextInChain = &surfaceChainedDesc;
71
72 auto surface = wgpu::Instance(fInstance->Get()).CreateSurface(&surfaceDesc);
73 if (!surface) {
74 SkASSERT(false);
75 return false;
76 }
77
78 fDevice = std::move(device);
79 fSurface = std::move(surface);
80 configureSurface();
81
82 return true;
83 }
84
onDestroyContext()85 void GraphiteDawnVulkanWindowContext_unix::onDestroyContext() {}
86
resize(int w,int h)87 void GraphiteDawnVulkanWindowContext_unix::resize(int w, int h) {
88 configureSurface();
89 }
90
91 } // anonymous namespace
92
93 namespace skwindow {
94
MakeGraphiteDawnVulkanForXlib(const XlibWindowInfo & info,std::unique_ptr<const DisplayParams> params)95 std::unique_ptr<WindowContext> MakeGraphiteDawnVulkanForXlib(
96 const XlibWindowInfo& info, std::unique_ptr<const DisplayParams> params) {
97 std::unique_ptr<WindowContext> ctx(
98 new GraphiteDawnVulkanWindowContext_unix(info, std::move(params)));
99 if (!ctx->isValid()) {
100 return nullptr;
101 }
102 return ctx;
103 }
104
105 } // namespace skwindow
106