blob: 4b66ce42a340b06ed871da15b0832ad26845f23d [file] [log] [blame]
Stephen Whitea800ec92019-08-02 15:04:52 -04001/*
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
Stephen White1e2adcf2019-10-16 09:48:53 -040014#include "dawn/dawn_proc.h"
15
Stephen White3cc8d4f2019-10-30 09:56:23 -040016static wgpu::TextureUsage kUsage = wgpu::TextureUsage::OutputAttachment |
17 wgpu::TextureUsage::CopySrc;
Stephen White7b86d4e2019-10-18 08:53:17 -040018
Stephen Whitea521c962019-12-04 09:57:48 -050019static void PrintDeviceError(WGPUErrorType, const char* message, void*) {
Stephen Whitea800ec92019-08-02 15:04:52 -040020 printf("Device error: %s\n", message);
21 SkASSERT(false);
22}
23
24namespace sk_app {
25
26DawnWindowContext::DawnWindowContext(const DisplayParams& params,
Stephen White3cc8d4f2019-10-30 09:56:23 -040027 wgpu::TextureFormat swapChainFormat)
Stephen Whitea800ec92019-08-02 15:04:52 -040028 : WindowContext(params)
29 , fSwapChainFormat(swapChainFormat)
30 , fInstance(std::make_unique<dawn_native::Instance>()) {
31}
32
33void 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);
Stephen White3cc8d4f2019-10-30 09:56:23 -040043 wgpu::SwapChainDescriptor swapChainDesc;
Stephen Whitea800ec92019-08-02 15:04:52 -040044 swapChainDesc.implementation = reinterpret_cast<int64_t>(&fSwapChainImplementation);
45 fSwapChain = fDevice.CreateSwapChain(&swapChainDesc);
46 if (!fSwapChain) {
47 fContext.reset();
48 return;
49 }
Stephen White7b86d4e2019-10-18 08:53:17 -040050 fSwapChain.Configure(fSwapChainFormat, kUsage, width, height);
Stephen White20c626a2019-10-15 13:35:37 -040051 fDevice.SetUncapturedErrorCallback(PrintDeviceError, 0);
Stephen Whitea800ec92019-08-02 15:04:52 -040052}
53
54DawnWindowContext::~DawnWindowContext() {
55}
56
57void DawnWindowContext::destroyContext() {
58 if (!fDevice.Get()) {
59 return;
60 }
61
62 this->onDestroyContext();
63
64 fContext.reset();
65 fDevice = nullptr;
66}
67
68sk_sp<SkSurface> DawnWindowContext::getBackbufferSurface() {
69 GrDawnImageInfo imageInfo;
70 imageInfo.fTexture = fSwapChain.GetNextTexture();
71 imageInfo.fFormat = fSwapChainFormat;
72 imageInfo.fLevelCount = 1; // FIXME
73 GrBackendTexture backendTexture(fWidth, fHeight, imageInfo);
74 fSurface = SkSurface::MakeFromBackendTextureAsRenderTarget(fContext.get(),
75 backendTexture,
76 this->getRTOrigin(),
77 fDisplayParams.fMSAASampleCount,
78 fDisplayParams.fColorType,
79 fDisplayParams.fColorSpace,
80 &fDisplayParams.fSurfaceProps);
81 return fSurface;
82}
83
84void DawnWindowContext::swapBuffers() {
85 GrBackendRenderTarget backendRT = fSurface->getBackendRenderTarget(
86 SkSurface::kFlushRead_BackendHandleAccess);
87 GrDawnImageInfo imageInfo;
88 SkAssertResult(backendRT.getDawnImageInfo(&imageInfo));
89
90 fSwapChain.Present(imageInfo.fTexture);
91 this->onSwapBuffers();
92}
93
94void DawnWindowContext::resize(int w, int h) {
95 fWidth = w;
96 fHeight = h;
97 fSwapChainImplementation = this->createSwapChainImplementation(w, h, fDisplayParams);
Stephen White3cc8d4f2019-10-30 09:56:23 -040098 wgpu::SwapChainDescriptor swapChainDesc;
Stephen Whitea800ec92019-08-02 15:04:52 -040099 swapChainDesc.implementation = reinterpret_cast<int64_t>(&fSwapChainImplementation);
100 fSwapChain = fDevice.CreateSwapChain(&swapChainDesc);
101 if (!fSwapChain) {
102 fContext.reset();
103 return;
104 }
Stephen White7b86d4e2019-10-18 08:53:17 -0400105 fSwapChain.Configure(fSwapChainFormat, kUsage, fWidth, fHeight);
Stephen Whitea800ec92019-08-02 15:04:52 -0400106}
107
108void DawnWindowContext::setDisplayParams(const DisplayParams& params) {
109 fDisplayParams = params;
110}
111
Stephen White3cc8d4f2019-10-30 09:56:23 -0400112wgpu::Device DawnWindowContext::createDevice(dawn_native::BackendType type) {
Stephen Whitea800ec92019-08-02 15:04:52 -0400113 fInstance->DiscoverDefaultAdapters();
114 DawnProcTable backendProcs = dawn_native::GetProcs();
Stephen White1e2adcf2019-10-16 09:48:53 -0400115 dawnProcSetProcs(&backendProcs);
Stephen Whitea800ec92019-08-02 15:04:52 -0400116
117 std::vector<dawn_native::Adapter> adapters = fInstance->GetAdapters();
118 for (dawn_native::Adapter adapter : adapters) {
119 if (adapter.GetBackendType() == type) {
120 return adapter.CreateDevice();
121 }
122 }
123 return nullptr;
124}
125
126} //namespace sk_app