diff --git a/src/renderer/wg_engine/tvgWgRenderData.h b/src/renderer/wg_engine/tvgWgRenderData.h index 1ae393e6..84ea8aaf 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.h +++ b/src/renderer/wg_engine/tvgWgRenderData.h @@ -86,6 +86,7 @@ struct WgRenderSettings struct WgRenderDataPaint { WgBindGroupPaint bindGroupPaint{}; + RenderRegion viewport{}; float opacity{}; virtual ~WgRenderDataPaint() {}; diff --git a/src/renderer/wg_engine/tvgWgRenderTarget.cpp b/src/renderer/wg_engine/tvgWgRenderTarget.cpp index bc834cff..a936be47 100644 --- a/src/renderer/wg_engine/tvgWgRenderTarget.cpp +++ b/src/renderer/wg_engine/tvgWgRenderTarget.cpp @@ -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) diff --git a/src/renderer/wg_engine/tvgWgRenderTarget.h b/src/renderer/wg_engine/tvgWgRenderTarget.h index 875e13a0..65dd6d4e 100644 --- a/src/renderer/wg_engine/tvgWgRenderTarget.h +++ b/src/renderer/wg_engine/tvgWgRenderTarget.h @@ -38,6 +38,7 @@ public: WGPUTextureView texViewStencil{}; WgBindGroupTextureStorageRgba bindGroupTexStorageRgba; WgBindGroupTextureStorageBgra bindGroupTexStorageBgra; + uint32_t samples{}; uint32_t width{}; uint32_t height{}; uint32_t workgroupsCountX{}; diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index f13a306a..e36e4a44 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -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; diff --git a/src/renderer/wg_engine/tvgWgRenderer.h b/src/renderer/wg_engine/tvgWgRenderer.h index f7ec78fe..4784a816 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.h +++ b/src/renderer/wg_engine/tvgWgRenderer.h @@ -80,6 +80,7 @@ private: WgContext mContext; WgPipelines mPipelines; Surface mTargetSurface; + RenderRegion mViewport{}; BlendMethod mBlendMethod{}; // current blend method