1 /*
2 * Copyright 2019 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 "include/core/SkSurface.h"
9 #include "include/gpu/GrBackendSurface.h"
10 #include "include/gpu/GrContext.h"
11 #include "src/core/SkAutoMalloc.h"
12 #include "tools/sk_app/DawnWindowContext.h"
13
14 #include "dawn/dawn_proc.h"
15
16 static wgpu::TextureUsage kUsage = wgpu::TextureUsage::OutputAttachment |
17 wgpu::TextureUsage::CopySrc;
18
PrintDeviceError(WGPUErrorType,const char * message,void *)19 static void PrintDeviceError(WGPUErrorType, const char* message, void*) {
20 printf("Device error: %s\n", message);
21 SkASSERT(false);
22 }
23
24 namespace sk_app {
25
DawnWindowContext(const DisplayParams & params,wgpu::TextureFormat swapChainFormat)26 DawnWindowContext::DawnWindowContext(const DisplayParams& params,
27 wgpu::TextureFormat swapChainFormat)
28 : WindowContext(params)
29 , fSwapChainFormat(swapChainFormat)
30 , fInstance(std::make_unique<dawn_native::Instance>()) {
31 }
32
initializeContext(int width,int height)33 void DawnWindowContext::initializeContext(int width, int height) {
34 fWidth = width;
35 fHeight = height;
36 fDevice = onInitializeContext();
37 fContext = GrContext::MakeDawn(fDevice, fDisplayParams.fGrContextOptions);
38
39 if (!fContext) {
40 return;
41 }
42 fSwapChainImplementation = this->createSwapChainImplementation(-1, -1, fDisplayParams);
43 wgpu::SwapChainDescriptor swapChainDesc;
44 swapChainDesc.implementation = reinterpret_cast<int64_t>(&fSwapChainImplementation);
45 fSwapChain = fDevice.CreateSwapChain(&swapChainDesc);
46 if (!fSwapChain) {
47 fContext.reset();
48 return;
49 }
50 fSwapChain.Configure(fSwapChainFormat, kUsage, width, height);
51 fDevice.SetUncapturedErrorCallback(PrintDeviceError, 0);
52 }
53
~DawnWindowContext()54 DawnWindowContext::~DawnWindowContext() {
55 }
56
destroyContext()57 void DawnWindowContext::destroyContext() {
58 if (!fDevice.Get()) {
59 return;
60 }
61
62 this->onDestroyContext();
63
64 fContext.reset();
65 fDevice = nullptr;
66 }
67
getBackbufferSurface()68 sk_sp<SkSurface> DawnWindowContext::getBackbufferSurface() {
69 GrDawnRenderTargetInfo rtInfo;
70 rtInfo.fTextureView = fSwapChain.GetCurrentTextureView();
71 rtInfo.fFormat = fSwapChainFormat;
72 rtInfo.fLevelCount = 1; // FIXME
73 GrBackendRenderTarget backendRenderTarget(fWidth, fHeight, fDisplayParams.fMSAASampleCount, 8,
74 rtInfo);
75 fSurface = SkSurface::MakeFromBackendRenderTarget(fContext.get(),
76 backendRenderTarget,
77 this->getRTOrigin(),
78 fDisplayParams.fColorType,
79 fDisplayParams.fColorSpace,
80 &fDisplayParams.fSurfaceProps);
81 return fSurface;
82 }
83
swapBuffers()84 void DawnWindowContext::swapBuffers() {
85 fSwapChain.Present();
86 this->onSwapBuffers();
87 }
88
resize(int w,int h)89 void DawnWindowContext::resize(int w, int h) {
90 fWidth = w;
91 fHeight = h;
92 fSwapChainImplementation = this->createSwapChainImplementation(w, h, fDisplayParams);
93 wgpu::SwapChainDescriptor swapChainDesc;
94 swapChainDesc.implementation = reinterpret_cast<int64_t>(&fSwapChainImplementation);
95 fSwapChain = fDevice.CreateSwapChain(&swapChainDesc);
96 if (!fSwapChain) {
97 fContext.reset();
98 return;
99 }
100 fSwapChain.Configure(fSwapChainFormat, kUsage, fWidth, fHeight);
101 }
102
setDisplayParams(const DisplayParams & params)103 void DawnWindowContext::setDisplayParams(const DisplayParams& params) {
104 fDisplayParams = params;
105 }
106
createDevice(dawn_native::BackendType type)107 wgpu::Device DawnWindowContext::createDevice(dawn_native::BackendType type) {
108 fInstance->DiscoverDefaultAdapters();
109 DawnProcTable backendProcs = dawn_native::GetProcs();
110 dawnProcSetProcs(&backendProcs);
111
112 std::vector<dawn_native::Adapter> adapters = fInstance->GetAdapters();
113 for (dawn_native::Adapter adapter : adapters) {
114 if (adapter.GetBackendType() == type) {
115 return adapter.CreateDevice();
116 }
117 }
118 return nullptr;
119 }
120
121 } //namespace sk_app
122