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); bindGroupRadial.initialize(context.device, context.queue, radialGradient);
fillType = WgRenderSettingsType::Radial; fillType = WgRenderSettingsType::Radial;
} }
skip = false;
} else if ((flags & (RenderUpdateFlag::Color)) && !fill) { } else if ((flags & (RenderUpdateFlag::Color)) && !fill) {
WgShaderTypeSolidColor solidColor(color); WgShaderTypeSolidColor solidColor(color);
bindGroupSolid.initialize(context.device, context.queue, solidColor); bindGroupSolid.initialize(context.device, context.queue, solidColor);
fillType = WgRenderSettingsType::Solid; fillType = WgRenderSettingsType::Solid;
skip = (color[3] == 0);
} }
}; };

View file

@ -77,6 +77,7 @@ struct WgRenderSettings
WgBindGroupLinearGradient bindGroupLinear{}; WgBindGroupLinearGradient bindGroupLinear{};
WgBindGroupRadialGradient bindGroupRadial{}; WgBindGroupRadialGradient bindGroupRadial{};
WgRenderSettingsType fillType{}; WgRenderSettingsType fillType{};
bool skip{};
void update(WgContext& context, const Fill* fill, const uint8_t* color, const RenderUpdateFlag flags); void update(WgContext& context, const Fill* fill, const uint8_t* color, const RenderUpdateFlag flags);
void release(WgContext& context); void release(WgContext& context);
@ -85,6 +86,7 @@ struct WgRenderSettings
struct WgRenderDataPaint struct WgRenderDataPaint
{ {
WgBindGroupPaint bindGroupPaint{}; WgBindGroupPaint bindGroupPaint{};
float opacity{};
virtual ~WgRenderDataPaint() {}; virtual ~WgRenderDataPaint() {};
virtual void release(WgContext& context); virtual void release(WgContext& context);

View file

@ -111,6 +111,7 @@ void WgRenderStorage::drawShape(WgContext& context, WgRenderDataShape* renderDat
assert(renderData); assert(renderData);
assert(mRenderPassEncoder); assert(mRenderPassEncoder);
assert(renderData->meshGroupShapes.meshes.count == renderData->meshGroupShapesBBox.meshes.count); assert(renderData->meshGroupShapes.meshes.count == renderData->meshGroupShapesBBox.meshes.count);
if (renderData->renderSettingsShape.skip) return;
// draw shape geometry // draw shape geometry
wgpuRenderPassEncoderSetStencilReference(mRenderPassEncoder, 0); wgpuRenderPassEncoderSetStencilReference(mRenderPassEncoder, 0);
// setup fill rule // setup fill rule
@ -139,6 +140,7 @@ void WgRenderStorage::drawStroke(WgContext& context, WgRenderDataShape* renderDa
assert(renderData); assert(renderData);
assert(mRenderPassEncoder); assert(mRenderPassEncoder);
assert(renderData->meshGroupStrokes.meshes.count == renderData->meshGroupStrokesBBox.meshes.count); assert(renderData->meshGroupStrokes.meshes.count == renderData->meshGroupStrokesBBox.meshes.count);
if (renderData->renderSettingsStroke.skip) return;
// draw stroke geometry // draw stroke geometry
uint8_t blend = (uint8_t)blendType; uint8_t blend = (uint8_t)blendType;
// draw strokes to stencil (first pass) // draw strokes to stencil (first pass)

View file

@ -89,6 +89,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const
} }
// setup fill settings // setup fill settings
renderDataShape->opacity = opacity;
renderDataShape->renderSettingsShape.update(mContext, rshape.fill, rshape.color, flags); renderDataShape->renderSettingsShape.update(mContext, rshape.fill, rshape.color, flags);
if (rshape.stroke) if (rshape.stroke)
renderDataShape->renderSettingsStroke.update(mContext, rshape.stroke->fill, rshape.stroke->color, flags); 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(); renderDataPicture = new WgRenderDataPicture();
// update paint settings // update paint settings
renderDataPicture->opacity = opacity;
if (flags & (RenderUpdateFlag::Transform | RenderUpdateFlag::Blend)) { if (flags & (RenderUpdateFlag::Transform | RenderUpdateFlag::Blend)) {
WgShaderTypeMat4x4f modelMat(transform); WgShaderTypeMat4x4f modelMat(transform);
WgShaderTypeBlendSettings blendSettings(surface->cs, opacity); WgShaderTypeBlendSettings blendSettings(surface->cs, opacity);
@ -150,6 +152,7 @@ bool WgRenderer::preRender()
bool WgRenderer::renderShape(RenderData data) bool WgRenderer::renderShape(RenderData data)
{ {
// get current render storage // get current render storage
if (((WgRenderDataShape*)data)->opacity == 0) return 0;
WgPipelineBlendType blendType = WgPipelines::blendMethodToBlendType(mBlendMethod); WgPipelineBlendType blendType = WgPipelines::blendMethodToBlendType(mBlendMethod);
WgRenderStorage* renderStorage = mRenderStorageStack.last(); WgRenderStorage* renderStorage = mRenderStorageStack.last();
assert(renderStorage); assert(renderStorage);