blob: b203a96424421136be45a6ced214f095d4222853 [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"
Robert Phillipsed653392020-07-10 13:55:21 -040010#include "include/gpu/GrDirectContext.h"
Stephen Whitea800ec92019-08-02 15:04:52 -040011#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) {
Robert Phillipsed653392020-07-10 13:55:21 -040034 SkASSERT(!fContext);
35
Stephen Whitea800ec92019-08-02 15:04:52 -040036 fWidth = width;
37 fHeight = height;
38 fDevice = onInitializeContext();
Stephen Whitea800ec92019-08-02 15:04:52 -040039
Robert Phillipsed653392020-07-10 13:55:21 -040040 // CONTEXT TODO: MakeDawn should return an sk_sp<GrDirectContext>
41 auto tmp = GrContext::MakeDawn(fDevice, fDisplayParams.fGrContextOptions);
42 fContext = sk_ref_sp<GrDirectContext>(tmp->asDirectContext());
Stephen Whitea800ec92019-08-02 15:04:52 -040043 if (!fContext) {
44 return;
45 }
46 fSwapChainImplementation = this->createSwapChainImplementation(-1, -1, fDisplayParams);
Stephen White3cc8d4f2019-10-30 09:56:23 -040047 wgpu::SwapChainDescriptor swapChainDesc;
Stephen Whitea800ec92019-08-02 15:04:52 -040048 swapChainDesc.implementation = reinterpret_cast<int64_t>(&fSwapChainImplementation);
Sean Gilhuly695f57d2020-03-30 13:23:00 -040049 fSwapChain = fDevice.CreateSwapChain(nullptr, &swapChainDesc);
Stephen Whitea800ec92019-08-02 15:04:52 -040050 if (!fSwapChain) {
51 fContext.reset();
52 return;
53 }
Stephen White7b86d4e2019-10-18 08:53:17 -040054 fSwapChain.Configure(fSwapChainFormat, kUsage, width, height);
Stephen White20c626a2019-10-15 13:35:37 -040055 fDevice.SetUncapturedErrorCallback(PrintDeviceError, 0);
Stephen Whitea800ec92019-08-02 15:04:52 -040056}
57
58DawnWindowContext::~DawnWindowContext() {
59}
60
61void DawnWindowContext::destroyContext() {
62 if (!fDevice.Get()) {
63 return;
64 }
65
66 this->onDestroyContext();
67
68 fContext.reset();
69 fDevice = nullptr;
70}
71
72sk_sp<SkSurface> DawnWindowContext::getBackbufferSurface() {
Stephen Whitef03c1162020-01-28 12:39:45 -050073 GrDawnRenderTargetInfo rtInfo;
74 rtInfo.fTextureView = fSwapChain.GetCurrentTextureView();
75 rtInfo.fFormat = fSwapChainFormat;
76 rtInfo.fLevelCount = 1; // FIXME
77 GrBackendRenderTarget backendRenderTarget(fWidth, fHeight, fDisplayParams.fMSAASampleCount, 8,
78 rtInfo);
79 fSurface = SkSurface::MakeFromBackendRenderTarget(fContext.get(),
80 backendRenderTarget,
81 this->getRTOrigin(),
82 fDisplayParams.fColorType,
83 fDisplayParams.fColorSpace,
84 &fDisplayParams.fSurfaceProps);
Stephen Whitea800ec92019-08-02 15:04:52 -040085 return fSurface;
86}
87
88void DawnWindowContext::swapBuffers() {
Stephen Whitef03c1162020-01-28 12:39:45 -050089 fSwapChain.Present();
Stephen Whitea800ec92019-08-02 15:04:52 -040090 this->onSwapBuffers();
91}
92
93void DawnWindowContext::resize(int w, int h) {
94 fWidth = w;
95 fHeight = h;
96 fSwapChainImplementation = this->createSwapChainImplementation(w, h, fDisplayParams);
Stephen White3cc8d4f2019-10-30 09:56:23 -040097 wgpu::SwapChainDescriptor swapChainDesc;
Stephen Whitea800ec92019-08-02 15:04:52 -040098 swapChainDesc.implementation = reinterpret_cast<int64_t>(&fSwapChainImplementation);
Sean Gilhuly695f57d2020-03-30 13:23:00 -040099 fSwapChain = fDevice.CreateSwapChain(nullptr, &swapChainDesc);
Stephen Whitea800ec92019-08-02 15:04:52 -0400100 if (!fSwapChain) {
101 fContext.reset();
102 return;
103 }
Stephen White7b86d4e2019-10-18 08:53:17 -0400104 fSwapChain.Configure(fSwapChainFormat, kUsage, fWidth, fHeight);
Stephen Whitea800ec92019-08-02 15:04:52 -0400105}
106
107void DawnWindowContext::setDisplayParams(const DisplayParams& params) {
108 fDisplayParams = params;
109}
110
Stephen White3cc8d4f2019-10-30 09:56:23 -0400111wgpu::Device DawnWindowContext::createDevice(dawn_native::BackendType type) {
Stephen Whitea800ec92019-08-02 15:04:52 -0400112 fInstance->DiscoverDefaultAdapters();
113 DawnProcTable backendProcs = dawn_native::GetProcs();
Stephen White1e2adcf2019-10-16 09:48:53 -0400114 dawnProcSetProcs(&backendProcs);
Stephen Whitea800ec92019-08-02 15:04:52 -0400115
116 std::vector<dawn_native::Adapter> adapters = fInstance->GetAdapters();
117 for (dawn_native::Adapter adapter : adapters) {
118 if (adapter.GetBackendType() == type) {
119 return adapter.CreateDevice();
120 }
121 }
122 return nullptr;
123}
124
125} //namespace sk_app