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
This commit is contained in:
Sergii Liebodkin 2024-11-28 07:05:17 +00:00 committed by Hermet Park
parent cf05128a96
commit 13b976ee80
3 changed files with 81 additions and 41 deletions

View file

@ -27,6 +27,53 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh
{
// pipelines (external handle, do not release)
pipelines.initialize(context);
// 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]);
}
// create render targets handles
resize(context, width, height);
}
void WgCompositor::release(WgContext& 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 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;
@ -39,42 +86,11 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh
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);
}
void WgCompositor::release(WgContext& context)
{
// composition and blend geometries
meshData.release(context);
// release intermediate render storages
storageDstCopy.release(context);
// 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);
}

View file

@ -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 });

View file

@ -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 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
// 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;
}