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,57 +27,73 @@ void WgCompositor::initialize(WgContext& context, uint32_t width, uint32_t heigh
{ {
// pipelines (external handle, do not release) // pipelines (external handle, do not release)
pipelines.initialize(context); 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 // initialize opacity pool
for (uint32_t i = 0; i < 256; i++) { for (uint32_t i = 0; i < 256; i++) {
float opacity = i / 255.0f; float opacity = i / 255.0f;
context.allocateBufferUniform(bufferOpacities[i], &opacity, sizeof(float)); context.allocateBufferUniform(bufferOpacities[i], &opacity, sizeof(float));
bindGroupOpacities[i] = context.layouts.createBindGroupBuffer1Un(bufferOpacities[i]); bindGroupOpacities[i] = context.layouts.createBindGroupBuffer1Un(bufferOpacities[i]);
} }
// initialize intermediate render storages // create render targets handles
storageDstCopy.initialize(context, width, height); resize(context, width, height);
// composition and blend geometries
meshData.blitBox(context);
} }
void WgCompositor::release(WgContext& context) void WgCompositor::release(WgContext& context)
{ {
// composition and blend geometries // release render targets habdles
meshData.release(context); resize(context, 0, 0);
// release intermediate render storages
storageDstCopy.release(context);
// release opacity pool // release opacity pool
for (uint32_t i = 0; i < 256; i++) { for (uint32_t i = 0; i < 256; i++) {
context.layouts.releaseBindGroup(bindGroupOpacities[i]); context.layouts.releaseBindGroup(bindGroupOpacities[i]);
context.releaseBuffer(bufferOpacities[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 // release pipelines
pipelines.release(context); 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) RenderRegion WgCompositor::shrinkRenderRegion(RenderRegion& rect)
{ {
// cut viewport to screen dimensions // cut viewport to screen dimensions

View file

@ -65,6 +65,7 @@ private:
public: public:
void initialize(WgContext& context, uint32_t width, uint32_t height); void initialize(WgContext& context, uint32_t width, uint32_t height);
void release(WgContext& context); void release(WgContext& context);
void resize(WgContext& context, uint32_t width, uint32_t height);
// render passes workflow // render passes workflow
void beginRenderPass(WGPUCommandEncoder encoder, WgRenderStorage* target, bool clear, WGPUColor clearColor = { 0.0, 0.0, 0.0, 0.0 }); 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 // render target handle
bool WgRenderer::target(WGPUDevice device, WGPUInstance instance, void* target, uint32_t width, uint32_t height, int type) bool WgRenderer::target(WGPUDevice device, WGPUInstance instance, void* target, uint32_t width, uint32_t height, int type)
{ {
// release existing handles // release all existing handles
release(); if (!instance || !device || !target) {
// release all handles
release();
return true;
}
// can not initialize renderer, give up // 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 // device or instance was changed, need to recreate all instances
mTargetSurface.stride = width; if ((mContext.device != device) || (mContext.instance != instance)) {
mTargetSurface.w = width; // release all handles
mTargetSurface.h = height; release();
// initialize base rendering handles
// initialize rendering context mContext.initialize(instance, device);
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 // initialize render tree instances
mRenderStoragePool.initialize(mContext, width, height); mRenderStoragePool.initialize(mContext, width, height);
mRenderStorageRoot.initialize(mContext, width, height); mRenderStorageRoot.initialize(mContext, width, height);
mCompositor.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) // configure surface (must be called after context creation)
if (type == 0) { if (type == 0) {
surface = (WGPUSurface)target; surface = (WGPUSurface)target;
surfaceConfigure(surface, mContext, width, height); surfaceConfigure(surface, mContext, width, height);
} else targetTexture = (WGPUTexture)target; } else targetTexture = (WGPUTexture)target;
return true; return true;
} }
void WgRenderer::clearTargets() { void WgRenderer::clearTargets()
{
releaseSurfaceTexture(); releaseSurfaceTexture();
if (surface) wgpuSurfaceUnconfigure(surface);
targetTexture = nullptr; targetTexture = nullptr;
surface = nullptr; surface = nullptr;
mTargetSurface.stride = 0;
mTargetSurface.w = 0;
mTargetSurface.h = 0;
} }