From 13b976ee800fd43c97b80125c6737447f733895e Mon Sep 17 00:00:00 2001 From: Sergii Liebodkin Date: Thu, 28 Nov 2024 07:05:17 +0000 Subject: [PATCH] wg_engine: support resizing Added abillity to resize target (surface) In case of resizing only render targets handles recreated Issue: https://github.com/thorvg/thorvg/issues/2985 --- src/renderer/wg_engine/tvgWgCompositor.cpp | 76 +++++++++++++--------- src/renderer/wg_engine/tvgWgCompositor.h | 1 + src/renderer/wg_engine/tvgWgRenderer.cpp | 45 +++++++++---- 3 files changed, 81 insertions(+), 41 deletions(-) diff --git a/src/renderer/wg_engine/tvgWgCompositor.cpp b/src/renderer/wg_engine/tvgWgCompositor.cpp index 6402028e..90510d36 100755 --- a/src/renderer/wg_engine/tvgWgCompositor.cpp +++ b/src/renderer/wg_engine/tvgWgCompositor.cpp @@ -27,57 +27,73 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh { // pipelines (external handle, do not release) pipelines.initialize(context); - // store render target dimensions - this->width = width; - this->height = height; - // allocate global stencil buffer handles - texDepthStencil = context.createTexAttachement(width, height, WGPUTextureFormat_Depth24PlusStencil8, 1); - texViewDepthStencil = context.createTextureView(texDepthStencil); - texDepthStencilMS = context.createTexAttachement(width, height, WGPUTextureFormat_Depth24PlusStencil8, 4); - texViewDepthStencilMS = context.createTextureView(texDepthStencilMS); - // allocate global view matrix handles - WgShaderTypeMat4x4f viewMat(width, height); - context.allocateBufferUniform(bufferViewMat, &viewMat, sizeof(viewMat)); - bindGroupViewMat = context.layouts.createBindGroupBuffer1Un(bufferViewMat); // initialize opacity pool for (uint32_t i = 0; i < 256; i++) { float opacity = i / 255.0f; context.allocateBufferUniform(bufferOpacities[i], &opacity, sizeof(float)); bindGroupOpacities[i] = context.layouts.createBindGroupBuffer1Un(bufferOpacities[i]); } - // initialize intermediate render storages - storageDstCopy.initialize(context, width, height); - // composition and blend geometries - meshData.blitBox(context); + // create render targets handles + resize(context, width, height); } void WgCompositor::release(WgContext& context) { - // composition and blend geometries - meshData.release(context); - // release intermediate render storages - storageDstCopy.release(context); + // release render targets habdles + resize(context, 0, 0); // release opacity pool for (uint32_t i = 0; i < 256; i++) { context.layouts.releaseBindGroup(bindGroupOpacities[i]); context.releaseBuffer(bufferOpacities[i]); } - // release global view matrix handles - context.layouts.releaseBindGroup(bindGroupViewMat); - context.releaseBuffer(bufferViewMat); - // release global stencil buffer handles - context.releaseTextureView(texViewDepthStencilMS); - context.releaseTexture(texDepthStencilMS); - context.releaseTextureView(texViewDepthStencil); - context.releaseTexture(texDepthStencil); - height = 0; - width = 0; // release pipelines pipelines.release(context); } +void WgCompositor::resize(WgContext& context, uint32_t width, uint32_t height) { + // release existig handles + if ((this->width != width) || (this->height != height)) { + // composition and blend geometries + meshData.release(context); + // release intermediate render storages + storageDstCopy.release(context); + // release global view matrix handles + context.layouts.releaseBindGroup(bindGroupViewMat); + context.releaseBuffer(bufferViewMat); + // release global stencil buffer handles + context.releaseTextureView(texViewDepthStencilMS); + context.releaseTexture(texDepthStencilMS); + context.releaseTextureView(texViewDepthStencil); + context.releaseTexture(texDepthStencil); + // store render target dimensions + this->height = height; + this->width = width; + } + + // create render targets handles + if ((width != 0) && (height != 0)) { + // store render target dimensions + this->width = width; + this->height = height; + // allocate global stencil buffer handles + texDepthStencil = context.createTexAttachement(width, height, WGPUTextureFormat_Depth24PlusStencil8, 1); + texViewDepthStencil = context.createTextureView(texDepthStencil); + texDepthStencilMS = context.createTexAttachement(width, height, WGPUTextureFormat_Depth24PlusStencil8, 4); + texViewDepthStencilMS = context.createTextureView(texDepthStencilMS); + // allocate global view matrix handles + WgShaderTypeMat4x4f viewMat(width, height); + context.allocateBufferUniform(bufferViewMat, &viewMat, sizeof(viewMat)); + bindGroupViewMat = context.layouts.createBindGroupBuffer1Un(bufferViewMat); + // initialize intermediate render storages + storageDstCopy.initialize(context, width, height); + // composition and blend geometries + meshData.blitBox(context); + } +} + + RenderRegion WgCompositor::shrinkRenderRegion(RenderRegion& rect) { // cut viewport to screen dimensions diff --git a/src/renderer/wg_engine/tvgWgCompositor.h b/src/renderer/wg_engine/tvgWgCompositor.h index ed98daf3..7a0ac5d3 100755 --- a/src/renderer/wg_engine/tvgWgCompositor.h +++ b/src/renderer/wg_engine/tvgWgCompositor.h @@ -65,6 +65,7 @@ private: public: void initialize(WgContext& context, uint32_t width, uint32_t height); void release(WgContext& context); + void resize(WgContext& context, uint32_t width, uint32_t height); // render passes workflow void beginRenderPass(WGPUCommandEncoder encoder, WgRenderStorage* target, bool clear, WGPUColor clearColor = { 0.0, 0.0, 0.0, 0.0 }); diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index 804f2fbe..6de25995 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -292,38 +292,61 @@ bool WgRenderer::sync() // render target handle bool WgRenderer::target(WGPUDevice device, WGPUInstance instance, void* target, uint32_t width, uint32_t height, int type) { - // release existing handles - release(); + // release all existing handles + if (!instance || !device || !target) { + // release all handles + release(); + return true; + } // can not initialize renderer, give up - if (!instance || !device || !target || !width || !height) return false; + if (!instance || !device || !target || !width || !height) + return false; - // store target properties - mTargetSurface.stride = width; - mTargetSurface.w = width; - mTargetSurface.h = height; - - // initialize rendering context - mContext.initialize(instance, device); + // device or instance was changed, need to recreate all instances + if ((mContext.device != device) || (mContext.instance != instance)) { + // release all handles + release(); + // initialize base rendering handles + mContext.initialize(instance, device); + // release render targets only + } else if (mRenderStorageRoot.texView) { + mRenderStoragePool.release(mContext); + mRenderStorageRoot.release(mContext); + mCompositor.release(mContext); + clearTargets(); + } // initialize render tree instances mRenderStoragePool.initialize(mContext, width, height); mRenderStorageRoot.initialize(mContext, width, height); mCompositor.initialize(mContext, width, height); + // store target properties + mTargetSurface.stride = width; + mTargetSurface.w = width; + mTargetSurface.h = height; + // configure surface (must be called after context creation) if (type == 0) { surface = (WGPUSurface)target; surfaceConfigure(surface, mContext, width, height); } else targetTexture = (WGPUTexture)target; + return true; } -void WgRenderer::clearTargets() { +void WgRenderer::clearTargets() +{ releaseSurfaceTexture(); + if (surface) wgpuSurfaceUnconfigure(surface); targetTexture = nullptr; surface = nullptr; + mTargetSurface.stride = 0; + mTargetSurface.w = 0; + mTargetSurface.h = 0; + }