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/sk_app/GraphiteDawnWindowContext.h"
9 #include "tools/sk_app/unix/WindowContextFactory_unix.h"
10
11 using sk_app::window_context_factory::XlibWindowInfo;
12 using sk_app::DisplayParams;
13 using sk_app::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 onSwapBuffers() override;
26 void resize(int w, int h) override;
27
28 private:
29 Display* fDisplay;
30 XWindow fWindow;
31
32 using INHERITED = GraphiteDawnWindowContext;
33 };
34
GraphiteDawnVulkanWindowContext_unix(const XlibWindowInfo & info,const DisplayParams & params)35 GraphiteDawnVulkanWindowContext_unix::GraphiteDawnVulkanWindowContext_unix(
36 const XlibWindowInfo& info,
37 const DisplayParams& params)
38 : INHERITED(params, wgpu::TextureFormat::BGRA8Unorm)
39 , fDisplay(info.fDisplay)
40 , fWindow(info.fWindow) {
41 XWindow root;
42 int x, y;
43 unsigned int border_width, depth;
44 unsigned int width, height;
45 XGetGeometry(fDisplay, fWindow, &root, &x, &y, &width, &height, &border_width, &depth);
46 this->initializeContext(width, height);
47 }
48
~GraphiteDawnVulkanWindowContext_unix()49 GraphiteDawnVulkanWindowContext_unix::~GraphiteDawnVulkanWindowContext_unix() {
50 this->destroyContext();
51 }
52
onInitializeContext()53 bool GraphiteDawnVulkanWindowContext_unix::onInitializeContext() {
54 SkASSERT(!!fWindow);
55
56 auto device = this->createDevice(wgpu::BackendType::Vulkan);
57 if (!device) {
58 SkASSERT(device);
59 return false;
60 }
61
62 wgpu::SurfaceDescriptorFromXlibWindow surfaceChainedDesc;
63 surfaceChainedDesc.display = fDisplay;
64 surfaceChainedDesc.window = fWindow;
65
66 wgpu::SurfaceDescriptor surfaceDesc;
67 surfaceDesc.nextInChain = &surfaceChainedDesc;
68
69 auto surface = wgpu::Instance(fInstance->Get()).CreateSurface(&surfaceDesc);
70 if (!surface) {
71 SkASSERT(false);
72 return false;
73 }
74
75 fDevice = std::move(device);
76 fSurface = std::move(surface);
77 fSwapChain = this->createSwapChain();
78
79 return true;
80 }
81
onDestroyContext()82 void GraphiteDawnVulkanWindowContext_unix::onDestroyContext() {}
83
onSwapBuffers()84 void GraphiteDawnVulkanWindowContext_unix::onSwapBuffers() {}
85
resize(int w,int h)86 void GraphiteDawnVulkanWindowContext_unix::resize(int w, int h) {
87 fSwapChain = this->createSwapChain();
88 }
89
90 } // anonymous namespace
91
92 namespace sk_app {
93 namespace window_context_factory {
94
MakeGraphiteDawnVulkanForXlib(const XlibWindowInfo & info,const DisplayParams & params)95 std::unique_ptr<WindowContext> MakeGraphiteDawnVulkanForXlib(const XlibWindowInfo& info,
96 const DisplayParams& params) {
97 std::unique_ptr<WindowContext> ctx(new GraphiteDawnVulkanWindowContext_unix(info, params));
98 if (!ctx->isValid()) {
99 return nullptr;
100 }
101 return ctx;
102 }
103
104 } // namespace window_context_factory
105 } // namespace sk_app
106