wg_engine: Viewport support

[issues 1479: Viewport](#1479)

Supports viewport settings and rectangular clip path.
Scissors cliping used as a way to clip viewport
This commit is contained in:
Sergii Liebodkin 2024-07-10 15:44:43 +00:00 committed by Hermet Park
parent d6d4839f1a
commit 3223f17f9c
5 changed files with 16 additions and 4 deletions

View file

@ -86,6 +86,7 @@ struct WgRenderSettings
struct WgRenderDataPaint
{
WgBindGroupPaint bindGroupPaint{};
RenderRegion viewport{};
float opacity{};
virtual ~WgRenderDataPaint() {};

View file

@ -30,6 +30,7 @@
{
release(context);
// store target storage size
this->samples = samples;
width = w * samples;
height = h * samples;
workgroupsCountX = (width + WG_COMPUTE_WORKGROUP_SIZE_X - 1) / WG_COMPUTE_WORKGROUP_SIZE_X; // workgroup size x == 8
@ -100,6 +101,8 @@ void WgRenderStorage::renderPicture(WgContext& context, WgRenderDataPicture* ren
assert(renderData);
assert(mRenderPassEncoder);
uint8_t blend = (uint8_t)blendType;
auto& vp = renderData->viewport;
wgpuRenderPassEncoderSetScissorRect(mRenderPassEncoder, vp.x * samples, vp.y * samples, vp.w * samples, vp.h * samples);
wgpuRenderPassEncoderSetStencilReference(mRenderPassEncoder, 0);
mPipelines->image[blend].use(mRenderPassEncoder, mBindGroupCanvas, renderData->bindGroupPaint, renderData->bindGroupPicture);
renderData->meshData.drawImage(context, mRenderPassEncoder);
@ -112,7 +115,8 @@ void WgRenderStorage::drawShape(WgContext& context, WgRenderDataShape* renderDat
assert(mRenderPassEncoder);
assert(renderData->meshGroupShapes.meshes.count == renderData->meshGroupShapesBBox.meshes.count);
if (renderData->renderSettingsShape.skip) return;
// draw shape geometry
auto& vp = renderData->viewport;
wgpuRenderPassEncoderSetScissorRect(mRenderPassEncoder, vp.x * samples, vp.y * samples, vp.w * samples, vp.h * samples);
wgpuRenderPassEncoderSetStencilReference(mRenderPassEncoder, 0);
// setup fill rule
if (renderData->fillRule == FillRule::Winding)
@ -141,6 +145,8 @@ void WgRenderStorage::drawStroke(WgContext& context, WgRenderDataShape* renderDa
assert(mRenderPassEncoder);
assert(renderData->meshGroupStrokes.meshes.count == renderData->meshGroupStrokesBBox.meshes.count);
if (renderData->renderSettingsStroke.skip) return;
auto& vp = renderData->viewport;
wgpuRenderPassEncoderSetScissorRect(mRenderPassEncoder, vp.x * samples, vp.y * samples, vp.w * samples, vp.h * samples);
// draw stroke geometry
uint8_t blend = (uint8_t)blendType;
// draw strokes to stencil (first pass)

View file

@ -38,6 +38,7 @@ public:
WGPUTextureView texViewStencil{};
WgBindGroupTextureStorageRgba bindGroupTexStorageRgba;
WgBindGroupTextureStorageBgra bindGroupTexStorageBgra;
uint32_t samples{};
uint32_t width{};
uint32_t height{};
uint32_t workgroupsCountX{};

View file

@ -113,6 +113,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const
}
// setup fill settings
renderDataShape->viewport = mViewport;
renderDataShape->opacity = opacity;
renderDataShape->renderSettingsShape.update(mContext, rshape.fill, rshape.color, flags);
if (rshape.stroke)
@ -136,6 +137,7 @@ RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderD
renderDataPicture = new WgRenderDataPicture();
// update paint settings
renderDataPicture->viewport = mViewport;
renderDataPicture->opacity = opacity;
if (flags & (RenderUpdateFlag::Transform | RenderUpdateFlag::Blend)) {
WgShaderTypeMat4x4f modelMat(transform);
@ -261,17 +263,18 @@ RenderRegion WgRenderer::region(TVG_UNUSED RenderData data)
RenderRegion WgRenderer::viewport() {
return { 0, 0, INT32_MAX, INT32_MAX };
return mViewport;
}
bool WgRenderer::viewport(TVG_UNUSED const RenderRegion& vp)
bool WgRenderer::viewport(const RenderRegion& vp)
{
mViewport = vp;
return true;
}
bool WgRenderer::blend(TVG_UNUSED BlendMethod method)
bool WgRenderer::blend(BlendMethod method)
{
mBlendMethod = method;
return false;

View file

@ -80,6 +80,7 @@ private:
WgContext mContext;
WgPipelines mPipelines;
Surface mTargetSurface;
RenderRegion mViewport{};
BlendMethod mBlendMethod{}; // current blend method