/* * Copyright 2019 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "include/core/SkSurface.h" #include "include/gpu/GrBackendSurface.h" #include "include/gpu/GrContext.h" #include "src/core/SkAutoMalloc.h" #include "tools/sk_app/DawnWindowContext.h" #include "dawn/dawn_proc.h" static wgpu::TextureUsage kUsage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc; static void PrintDeviceError(DawnErrorType, const char* message, void*) { printf("Device error: %s\n", message); SkASSERT(false); } namespace sk_app { DawnWindowContext::DawnWindowContext(const DisplayParams& params, wgpu::TextureFormat swapChainFormat) : WindowContext(params) , fSwapChainFormat(swapChainFormat) , fInstance(std::make_unique()) { } void DawnWindowContext::initializeContext(int width, int height) { fWidth = width; fHeight = height; fDevice = onInitializeContext(); fContext = GrContext::MakeDawn(fDevice, fDisplayParams.fGrContextOptions); if (!fContext) { return; } fSwapChainImplementation = this->createSwapChainImplementation(-1, -1, fDisplayParams); wgpu::SwapChainDescriptor swapChainDesc; swapChainDesc.implementation = reinterpret_cast(&fSwapChainImplementation); fSwapChain = fDevice.CreateSwapChain(&swapChainDesc); if (!fSwapChain) { fContext.reset(); return; } fSwapChain.Configure(fSwapChainFormat, kUsage, width, height); fDevice.SetUncapturedErrorCallback(PrintDeviceError, 0); } DawnWindowContext::~DawnWindowContext() { } void DawnWindowContext::destroyContext() { if (!fDevice.Get()) { return; } this->onDestroyContext(); fContext.reset(); fDevice = nullptr; } sk_sp DawnWindowContext::getBackbufferSurface() { GrDawnImageInfo imageInfo; imageInfo.fTexture = fSwapChain.GetNextTexture(); imageInfo.fFormat = fSwapChainFormat; imageInfo.fLevelCount = 1; // FIXME GrBackendTexture backendTexture(fWidth, fHeight, imageInfo); fSurface = SkSurface::MakeFromBackendTextureAsRenderTarget(fContext.get(), backendTexture, this->getRTOrigin(), fDisplayParams.fMSAASampleCount, fDisplayParams.fColorType, fDisplayParams.fColorSpace, &fDisplayParams.fSurfaceProps); return fSurface; } void DawnWindowContext::swapBuffers() { GrBackendRenderTarget backendRT = fSurface->getBackendRenderTarget( SkSurface::kFlushRead_BackendHandleAccess); GrDawnImageInfo imageInfo; SkAssertResult(backendRT.getDawnImageInfo(&imageInfo)); fSwapChain.Present(imageInfo.fTexture); this->onSwapBuffers(); } void DawnWindowContext::resize(int w, int h) { fWidth = w; fHeight = h; fSwapChainImplementation = this->createSwapChainImplementation(w, h, fDisplayParams); wgpu::SwapChainDescriptor swapChainDesc; swapChainDesc.implementation = reinterpret_cast(&fSwapChainImplementation); fSwapChain = fDevice.CreateSwapChain(&swapChainDesc); if (!fSwapChain) { fContext.reset(); return; } fSwapChain.Configure(fSwapChainFormat, kUsage, fWidth, fHeight); } void DawnWindowContext::setDisplayParams(const DisplayParams& params) { fDisplayParams = params; } wgpu::Device DawnWindowContext::createDevice(dawn_native::BackendType type) { fInstance->DiscoverDefaultAdapters(); DawnProcTable backendProcs = dawn_native::GetProcs(); dawnProcSetProcs(&backendProcs); std::vector adapters = fInstance->GetAdapters(); for (dawn_native::Adapter adapter : adapters) { if (adapter.GetBackendType() == type) { return adapter.CreateDevice(); } } return nullptr; } } //namespace sk_app