mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-24 07:08:58 +00:00
wg_engine: Introduce the stroke clipper
Issue: https://github.com/thorvg/thorvg/issues/3063
This commit is contained in:
parent
173822b1d9
commit
889710ecee
3 changed files with 26 additions and 16 deletions
|
@ -660,6 +660,26 @@ void WgCompositor::blendScene(WgContext& context, WgRenderStorage* scene, WgComp
|
|||
}
|
||||
|
||||
|
||||
void WgCompositor::markupClipPath(WgContext& context, WgRenderDataShape* renderData)
|
||||
{
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
||||
// markup stencil
|
||||
if (renderData->meshGroupStrokes.meshes.count > 0) {
|
||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 255);
|
||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.direct);
|
||||
ARRAY_FOREACH(p, renderData->meshGroupStrokes.meshes)
|
||||
(*p)->draw(context, renderPassEncoder);
|
||||
} else {
|
||||
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd;
|
||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
||||
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
|
||||
(*p)->drawFan(context, renderPassEncoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
|
||||
{
|
||||
assert(paint);
|
||||
|
@ -669,17 +689,11 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
|
|||
wgpuRenderPassEncoderSetScissorRect(renderPassEncoder, 0, 0, width, height);
|
||||
// get render data
|
||||
WgRenderDataShape* renderData0 = (WgRenderDataShape*)paint->clips[0];
|
||||
// set transformations
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
||||
// markup stencil
|
||||
WGPURenderPipeline stencilPipeline = (renderData0->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd;
|
||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
|
||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
||||
ARRAY_FOREACH(p, renderData0->meshGroupShapes.meshes)
|
||||
(*p)->drawFan(context, renderPassEncoder);
|
||||
markupClipPath(context, renderData0);
|
||||
// copy stencil to depth
|
||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 0, bindGroupViewMat, 0, nullptr);
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData0->bindGroupPaint, 0, nullptr);
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 2, bindGroupOpacities[128], 0, nullptr);
|
||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipelines.copy_stencil_to_depth);
|
||||
|
@ -689,12 +703,7 @@ void WgCompositor::renderClipPath(WgContext& context, WgRenderDataPaint* paint)
|
|||
// get render data
|
||||
WgRenderDataShape* renderData = (WgRenderDataShape*)(*p);
|
||||
// markup stencil
|
||||
WGPURenderPipeline stencilPipeline = (renderData->fillRule == FillRule::NonZero) ? pipelines.nonzero : pipelines.evenodd;
|
||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, stencilPipeline);
|
||||
ARRAY_FOREACH(p, renderData->meshGroupShapes.meshes)
|
||||
(*p)->drawFan(context, renderPassEncoder);
|
||||
markupClipPath(context, renderData);
|
||||
// copy stencil to depth (clear stencil)
|
||||
wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, 0);
|
||||
wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, 1, renderData->bindGroupPaint, 0, nullptr);
|
||||
|
|
|
@ -68,7 +68,6 @@ private:
|
|||
void copyTexture(const WgRenderStorage* dst, const WgRenderStorage* src);
|
||||
void copyTexture(const WgRenderStorage* dst, const WgRenderStorage* src, const RenderRegion& region);
|
||||
|
||||
|
||||
// shapes
|
||||
void drawShape(WgContext& context, WgRenderDataShape* renderData);
|
||||
void blendShape(WgContext& context, WgRenderDataShape* renderData, BlendMethod blendMethod);
|
||||
|
@ -88,6 +87,8 @@ private:
|
|||
void drawScene(WgContext& context, WgRenderStorage* scene, WgCompose* compose);
|
||||
void blendScene(WgContext& context, WgRenderStorage* src, WgCompose* compose);
|
||||
|
||||
// the renderer prioritizes clipping with the stroke over the shape's fill
|
||||
void markupClipPath(WgContext& context, WgRenderDataShape* renderData);
|
||||
void renderClipPath(WgContext& context, WgRenderDataPaint* paint);
|
||||
void clearClipPath(WgContext& context, WgRenderDataPaint* paint);
|
||||
|
||||
|
|
|
@ -376,7 +376,7 @@ void WgRenderDataShape::updateMeshes(WgContext& context, const RenderShape &rsha
|
|||
|
||||
pbuff->decodePath(rshape, true, [&](const WgVertexBuffer& path_buff) {
|
||||
appendShape(context, path_buff);
|
||||
if (rshape.stroke) proceedStrokes(context, rshape.stroke, path_buff, pool);
|
||||
if ((rshape.stroke) && (rshape.stroke->width > 0)) proceedStrokes(context, rshape.stroke, path_buff, pool);
|
||||
}, rshape.trimpath());
|
||||
|
||||
// update shapes bbox (with empty path handling)
|
||||
|
|
Loading…
Add table
Reference in a new issue