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
This commit is contained in:
Sergii Liebodkin 2024-06-17 11:10:02 +03:00 committed by Hermet Park
parent 846ae09151
commit f97c16f94c
4 changed files with 9 additions and 0 deletions

View file

@ -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);
}
};

View file

@ -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);

View file

@ -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)

View file

@ -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);