• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google Inc.
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 
10 #include "include/core/SkSurface.h"
11 #include "include/gpu/graphite/BackendTexture.h"
12 #include "include/gpu/graphite/Context.h"
13 #include "include/gpu/graphite/ContextOptions.h"
14 #include "include/gpu/graphite/GraphiteTypes.h"
15 #include "include/gpu/graphite/Recorder.h"
16 #include "include/gpu/graphite/Recording.h"
17 #include "include/gpu/graphite/dawn/DawnBackendContext.h"
18 #include "include/gpu/graphite/dawn/DawnUtils.h"
19 #include "tools/ToolUtils.h"
20 
21 #include "dawn/dawn_proc.h"
22 
23 namespace sk_app {
24 
GraphiteDawnWindowContext(const DisplayParams & params,wgpu::TextureFormat swapChainFormat)25 GraphiteDawnWindowContext::GraphiteDawnWindowContext(const DisplayParams& params,
26                                                      wgpu::TextureFormat swapChainFormat)
27     : WindowContext(params)
28     , fSwapChainFormat(swapChainFormat)
29     , fInstance(std::make_unique<dawn::native::Instance>()) {
30 }
31 
initializeContext(int width,int height)32 void GraphiteDawnWindowContext::initializeContext(int width, int height) {
33     SkASSERT(!fContext);
34 
35     fWidth = width;
36     fHeight = height;
37 
38     if (!onInitializeContext())
39         return;
40 
41     SkASSERT(fDevice);
42     SkASSERT(fSurface);
43     SkASSERT(fSwapChain);
44 
45     skgpu::graphite::DawnBackendContext backendContext;
46     backendContext.fDevice = fDevice;
47     backendContext.fQueue = fDevice.GetQueue();
48     skgpu::graphite::ContextOptions contextOptions;
49     contextOptions.fStoreContextRefInRecorder = true; // Needed to make synchronous readPixels work
50     fGraphiteContext = skgpu::graphite::ContextFactory::MakeDawn(backendContext,
51                                                                  contextOptions);
52     if (!fGraphiteContext) {
53         SkASSERT(false);
54         return;
55     }
56 
57     fGraphiteRecorder = fGraphiteContext->makeRecorder(ToolUtils::CreateTestingRecorderOptions());
58     SkASSERT(fGraphiteRecorder);
59 }
60 
61 GraphiteDawnWindowContext::~GraphiteDawnWindowContext() = default;
62 
destroyContext()63 void GraphiteDawnWindowContext::destroyContext() {
64     if (!fDevice.Get()) {
65         return;
66     }
67 
68     this->onDestroyContext();
69 
70     fGraphiteRecorder = nullptr;
71     fGraphiteContext = nullptr;
72     fSwapChain = nullptr;
73     fSurface = nullptr;
74     fDevice = nullptr;
75     fInstance = nullptr;
76 }
77 
getBackbufferSurface()78 sk_sp<SkSurface> GraphiteDawnWindowContext::getBackbufferSurface() {
79     auto textureView = fSwapChain.GetCurrentTextureView();
80     skgpu::graphite::DawnTextureInfo info(/*sampleCount=*/1,
81                                           skgpu::Mipmapped::kNo,
82                                           fSwapChainFormat,
83                                           kTextureUsage);
84     skgpu::graphite::BackendTexture backendTex(this->dimensions(),
85                                                info,
86                                                std::move(textureView));
87     SkASSERT(this->graphiteRecorder());
88     auto surface = SkSurface::MakeGraphiteFromBackendTexture(
89         this->graphiteRecorder(),
90         backendTex,
91         kBGRA_8888_SkColorType,
92         fDisplayParams.fColorSpace,
93         &fDisplayParams.fSurfaceProps);
94     SkASSERT(surface);
95     return surface;
96 }
97 
swapBuffers()98 void GraphiteDawnWindowContext::swapBuffers() {
99     // This chunk of code should not be in this class but higher up either in Window or
100     // WindowContext
101     std::unique_ptr<skgpu::graphite::Recording> recording = fGraphiteRecorder->snap();
102     if (recording) {
103         skgpu::graphite::InsertRecordingInfo info;
104         info.fRecording = recording.get();
105         fGraphiteContext->insertRecording(info);
106         fGraphiteContext->submit(skgpu::graphite::SyncToCpu::kNo);
107     }
108 
109     fSwapChain.Present();
110     this->onSwapBuffers();
111 }
112 
setDisplayParams(const DisplayParams & params)113 void GraphiteDawnWindowContext::setDisplayParams(const DisplayParams& params) {
114     fDisplayParams = params;
115 }
116 
createDevice(wgpu::BackendType type)117 wgpu::Device GraphiteDawnWindowContext::createDevice(wgpu::BackendType type) {
118     fInstance->DiscoverDefaultAdapters();
119     DawnProcTable backendProcs = dawn::native::GetProcs();
120     dawnProcSetProcs(&backendProcs);
121 
122     std::vector<dawn::native::Adapter> adapters = fInstance->GetAdapters();
123     for (dawn::native::Adapter adapter : adapters) {
124         wgpu::AdapterProperties properties;
125         adapter.GetProperties(&properties);
126         if (properties.backendType != type) {
127             continue;
128         }
129         auto device = wgpu::Device::Acquire(adapter.CreateDevice());
130         device.SetUncapturedErrorCallback(
131                 [](WGPUErrorType type, const char* message, void*) {
132                     SkDebugf("Device error: %s\n", message);
133                     SkASSERT(false);
134                 },
135                 0);
136         return device;
137     }
138     return nullptr;
139 }
140 
createSwapChain()141 wgpu::SwapChain GraphiteDawnWindowContext::createSwapChain() {
142     wgpu::SwapChainDescriptor swapChainDesc;
143     swapChainDesc.usage = kTextureUsage;
144     swapChainDesc.format = fSwapChainFormat;
145     swapChainDesc.width = fWidth;
146     swapChainDesc.height = fHeight;
147     swapChainDesc.presentMode = wgpu::PresentMode::Fifo;
148     swapChainDesc.implementation = 0;
149     auto swapChain = fDevice.CreateSwapChain(fSurface, &swapChainDesc);
150     SkASSERT(swapChain);
151     return swapChain;
152 }
153 
154 }   //namespace sk_app
155