sw_engine: fix omitted update for zero opacity

ensure the dirty region is updated when opacity becomes zero.

a regression bug of the recent partial rendering.

issue: https://github.com/orgs/thorvg/discussions/3570
This commit is contained in:
Hermet Park 2025-07-09 11:12:36 +09:00 committed by Hermet Park
parent 7e0f394c2c
commit 761259ca59
2 changed files with 16 additions and 6 deletions

View file

@ -59,6 +59,12 @@ struct SwTask : Task
return curBox; return curBox;
} }
void invisible()
{
curBox.reset();
if (!nodirty) dirtyRegion->add(prvBox, curBox);
}
virtual void dispose() = 0; virtual void dispose() = 0;
virtual bool clip(SwRle* target) = 0; virtual bool clip(SwRle* target) = 0;
virtual ~SwTask() {} virtual ~SwTask() {}
@ -103,9 +109,9 @@ struct SwShapeTask : SwTask
void run(unsigned tid) override void run(unsigned tid) override
{ {
//Invisible //invisible
if (opacity == 0 && !clipper) { if (opacity == 0 && !clipper) {
curBox.reset(); if (flags & RenderUpdateFlag::Color) invisible();
return; return;
} }
@ -166,11 +172,10 @@ struct SwShapeTask : SwTask
return; return;
err: err:
curBox.reset();
shapeReset(&shape); shapeReset(&shape);
rleReset(shape.strokeRle); rleReset(shape.strokeRle);
shapeDelOutline(&shape, mpool, tid); shapeDelOutline(&shape, mpool, tid);
if (!nodirty) dirtyRegion->add(prvBox, curBox); invisible();
} }
void dispose() override void dispose() override
@ -193,6 +198,12 @@ struct SwImageTask : SwTask
void run(unsigned tid) override void run(unsigned tid) override
{ {
//invisible
if (opacity == 0) {
if (flags & RenderUpdateFlag::Color) invisible();
return;
}
auto clipBox = curBox; auto clipBox = curBox;
//Convert colorspace if it's not aligned. //Convert colorspace if it's not aligned.
@ -209,9 +220,7 @@ struct SwImageTask : SwTask
if ((flags & (RenderUpdateFlag::Image | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) && (opacity > 0)) { if ((flags & (RenderUpdateFlag::Image | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) && (opacity > 0)) {
imageReset(&image); imageReset(&image);
if (!image.data || image.w == 0 || image.h == 0) goto end; if (!image.data || image.w == 0 || image.h == 0) goto end;
if (!imagePrepare(&image, transform, clipBox, curBox, mpool, tid)) goto end; if (!imagePrepare(&image, transform, clipBox, curBox, mpool, tid)) goto end;
if (clips.count > 0) { if (clips.count > 0) {
if (!imageGenRle(&image, curBox, false)) goto end; if (!imageGenRle(&image, curBox, false)) goto end;
if (image.rle) { if (image.rle) {

View file

@ -37,6 +37,7 @@ using pixel_t = uint32_t;
#define DASH_PATTERN_THRESHOLD 0.001f #define DASH_PATTERN_THRESHOLD 0.001f
//TODO: Separate Color & Opacity for more detailed conditional check
enum RenderUpdateFlag : uint16_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, Clip = 256, All = 0xffff}; enum RenderUpdateFlag : uint16_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, Clip = 256, All = 0xffff};
enum CompositionFlag : uint8_t {Invalid = 0, Opacity = 1, Blending = 2, Masking = 4, PostProcessing = 8}; //Composition Purpose enum CompositionFlag : uint8_t {Invalid = 0, Opacity = 1, Blending = 2, Masking = 4, PostProcessing = 8}; //Composition Purpose