From f97c16f94c34641c330557509e854712a280c4ba Mon Sep 17 00:00:00 2001 From: Sergii Liebodkin Date: Mon, 17 Jun 2024 11:10:02 +0300 Subject: [PATCH] wg_engine: skip shapes with zero opacity values Skip shapes rendering, if opacity is 0 and if fill color for shape and strokes also equal to 0 This behavior is used in sw renderer and fix visual artifacts in referenced animations. Also this rule fix composition results in case of AlphaMask and InvAlphaMask methods --- src/renderer/wg_engine/tvgWgRenderData.cpp | 2 ++ src/renderer/wg_engine/tvgWgRenderData.h | 2 ++ src/renderer/wg_engine/tvgWgRenderTarget.cpp | 2 ++ src/renderer/wg_engine/tvgWgRenderer.cpp | 3 +++ 4 files changed, 9 insertions(+) diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index 1bdd4650..db433f8b 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -236,10 +236,12 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_ bindGroupRadial.initialize(context.device, context.queue, radialGradient); fillType = WgRenderSettingsType::Radial; } + skip = false; } else if ((flags & (RenderUpdateFlag::Color)) && !fill) { WgShaderTypeSolidColor solidColor(color); bindGroupSolid.initialize(context.device, context.queue, solidColor); fillType = WgRenderSettingsType::Solid; + skip = (color[3] == 0); } }; diff --git a/src/renderer/wg_engine/tvgWgRenderData.h b/src/renderer/wg_engine/tvgWgRenderData.h index 1329b5ab..eb80bd88 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.h +++ b/src/renderer/wg_engine/tvgWgRenderData.h @@ -77,6 +77,7 @@ struct WgRenderSettings WgBindGroupLinearGradient bindGroupLinear{}; WgBindGroupRadialGradient bindGroupRadial{}; WgRenderSettingsType fillType{}; + bool skip{}; void update(WgContext& context, const Fill* fill, const uint8_t* color, const RenderUpdateFlag flags); void release(WgContext& context); @@ -85,6 +86,7 @@ struct WgRenderSettings struct WgRenderDataPaint { WgBindGroupPaint bindGroupPaint{}; + float opacity{}; virtual ~WgRenderDataPaint() {}; virtual void release(WgContext& context); diff --git a/src/renderer/wg_engine/tvgWgRenderTarget.cpp b/src/renderer/wg_engine/tvgWgRenderTarget.cpp index 5642abff..f39dae0b 100644 --- a/src/renderer/wg_engine/tvgWgRenderTarget.cpp +++ b/src/renderer/wg_engine/tvgWgRenderTarget.cpp @@ -111,6 +111,7 @@ void WgRenderStorage::drawShape(WgContext& context, WgRenderDataShape* renderDat assert(renderData); assert(mRenderPassEncoder); assert(renderData->meshGroupShapes.meshes.count == renderData->meshGroupShapesBBox.meshes.count); + if (renderData->renderSettingsShape.skip) return; // draw shape geometry wgpuRenderPassEncoderSetStencilReference(mRenderPassEncoder, 0); // setup fill rule @@ -139,6 +140,7 @@ void WgRenderStorage::drawStroke(WgContext& context, WgRenderDataShape* renderDa assert(renderData); assert(mRenderPassEncoder); assert(renderData->meshGroupStrokes.meshes.count == renderData->meshGroupStrokesBBox.meshes.count); + if (renderData->renderSettingsStroke.skip) return; // draw stroke geometry uint8_t blend = (uint8_t)blendType; // draw strokes to stencil (first pass) diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index e9cb030f..b59327e6 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -89,6 +89,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const } // setup fill settings + renderDataShape->opacity = opacity; renderDataShape->renderSettingsShape.update(mContext, rshape.fill, rshape.color, flags); if (rshape.stroke) renderDataShape->renderSettingsStroke.update(mContext, rshape.stroke->fill, rshape.stroke->color, flags); @@ -111,6 +112,7 @@ RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderD renderDataPicture = new WgRenderDataPicture(); // update paint settings + renderDataPicture->opacity = opacity; if (flags & (RenderUpdateFlag::Transform | RenderUpdateFlag::Blend)) { WgShaderTypeMat4x4f modelMat(transform); WgShaderTypeBlendSettings blendSettings(surface->cs, opacity); @@ -150,6 +152,7 @@ bool WgRenderer::preRender() bool WgRenderer::renderShape(RenderData data) { // get current render storage + if (((WgRenderDataShape*)data)->opacity == 0) return 0; WgPipelineBlendType blendType = WgPipelines::blendMethodToBlendType(mBlendMethod); WgRenderStorage* renderStorage = mRenderStorageStack.last(); assert(renderStorage);