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/win/WindowContextFactory_win.h"
10 
11 using sk_app::DisplayParams;
12 using sk_app::GraphiteDawnWindowContext;
13 
14 namespace {
15 
16 class GraphiteDawnD3D12WindowContext_win : public GraphiteDawnWindowContext {
17 public:
18     GraphiteDawnD3D12WindowContext_win(HWND hwnd, const DisplayParams& params);
19 
20     ~GraphiteDawnD3D12WindowContext_win() override;
21 
22     bool onInitializeContext() override;
23     void onDestroyContext() override;
24     void onSwapBuffers() override;
25     void resize(int w, int h) override;
26 
27 private:
28     HWND fWindow;
29 
30     using INHERITED = GraphiteDawnWindowContext;
31 };
32 
GraphiteDawnD3D12WindowContext_win(HWND hwnd,const DisplayParams & params)33 GraphiteDawnD3D12WindowContext_win::GraphiteDawnD3D12WindowContext_win(HWND hwnd,
34                                                                        const DisplayParams& params)
35         : INHERITED(params, wgpu::TextureFormat::BGRA8Unorm), fWindow(hwnd) {
36     RECT rect;
37     GetClientRect(hwnd, &rect);
38     this->initializeContext(rect.right - rect.left, rect.bottom - rect.top);
39 }
40 
~GraphiteDawnD3D12WindowContext_win()41 GraphiteDawnD3D12WindowContext_win::~GraphiteDawnD3D12WindowContext_win() {
42     this->destroyContext();
43 }
44 
onInitializeContext()45 bool GraphiteDawnD3D12WindowContext_win::onInitializeContext() {
46     SkASSERT(!!fWindow);
47 
48     auto device = this->createDevice(wgpu::BackendType::D3D12);
49     if (!device) {
50         SkASSERT(device);
51         return false;
52     }
53 
54     wgpu::SurfaceDescriptorFromWindowsHWND surfaceChainedDesc;
55     surfaceChainedDesc.hwnd = fWindow;
56     surfaceChainedDesc.hinstance = GetModuleHandle(nullptr);
57     wgpu::SurfaceDescriptor surfaceDesc;
58     surfaceDesc.nextInChain = &surfaceChainedDesc;
59 
60     auto surface = wgpu::Instance(fInstance->Get()).CreateSurface(&surfaceDesc);
61     if (!surface) {
62         SkASSERT(false);
63         return false;
64     }
65 
66     fDevice = std::move(device);
67     fSurface = std::move(surface);
68     fSwapChain = this->createSwapChain();
69 
70     return true;
71 }
72 
onDestroyContext()73 void GraphiteDawnD3D12WindowContext_win::onDestroyContext() {}
74 
onSwapBuffers()75 void GraphiteDawnD3D12WindowContext_win::onSwapBuffers() {}
76 
resize(int w,int h)77 void GraphiteDawnD3D12WindowContext_win::resize(int w, int h) {
78     fSwapChain = this->createSwapChain();
79 }
80 
81 }  // anonymous namespace
82 
83 namespace sk_app {
84 namespace window_context_factory {
85 
MakeGraphiteDawnD3D12ForWin(HWND hwnd,const DisplayParams & params)86 std::unique_ptr<WindowContext> MakeGraphiteDawnD3D12ForWin(HWND hwnd, const DisplayParams& params) {
87     std::unique_ptr<WindowContext> ctx(new GraphiteDawnD3D12WindowContext_win(hwnd, params));
88     if (!ctx->isValid()) {
89         return nullptr;
90     }
91     return ctx;
92 }
93 
94 }  // namespace window_context_factory
95 }  // namespace sk_app
96