From 761259ca59208b52ee010433e3289730eab24681 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 9 Jul 2025 11:12:36 +0900 Subject: [PATCH] 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 --- src/renderer/sw_engine/tvgSwRenderer.cpp | 21 +++++++++++++++------ src/renderer/tvgRender.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index e4e3d58a..0b0ce849 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -59,6 +59,12 @@ struct SwTask : Task return curBox; } + void invisible() + { + curBox.reset(); + if (!nodirty) dirtyRegion->add(prvBox, curBox); + } + virtual void dispose() = 0; virtual bool clip(SwRle* target) = 0; virtual ~SwTask() {} @@ -103,9 +109,9 @@ struct SwShapeTask : SwTask void run(unsigned tid) override { - //Invisible + //invisible if (opacity == 0 && !clipper) { - curBox.reset(); + if (flags & RenderUpdateFlag::Color) invisible(); return; } @@ -166,11 +172,10 @@ struct SwShapeTask : SwTask return; err: - curBox.reset(); shapeReset(&shape); rleReset(shape.strokeRle); shapeDelOutline(&shape, mpool, tid); - if (!nodirty) dirtyRegion->add(prvBox, curBox); + invisible(); } void dispose() override @@ -193,6 +198,12 @@ struct SwImageTask : SwTask void run(unsigned tid) override { + //invisible + if (opacity == 0) { + if (flags & RenderUpdateFlag::Color) invisible(); + return; + } + auto clipBox = curBox; //Convert colorspace if it's not aligned. @@ -209,9 +220,7 @@ struct SwImageTask : SwTask if ((flags & (RenderUpdateFlag::Image | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) && (opacity > 0)) { imageReset(&image); if (!image.data || image.w == 0 || image.h == 0) goto end; - if (!imagePrepare(&image, transform, clipBox, curBox, mpool, tid)) goto end; - if (clips.count > 0) { if (!imageGenRle(&image, curBox, false)) goto end; if (image.rle) { diff --git a/src/renderer/tvgRender.h b/src/renderer/tvgRender.h index 3b0e8a8d..4eb26a9a 100644 --- a/src/renderer/tvgRender.h +++ b/src/renderer/tvgRender.h @@ -37,6 +37,7 @@ using pixel_t = uint32_t; #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 CompositionFlag : uint8_t {Invalid = 0, Opacity = 1, Blending = 2, Masking = 4, PostProcessing = 8}; //Composition Purpose