sw_engine renderer: fix a broken composition bug

tvg sw_engine tries to skip composition as far as its doable,
it tries composition only if the translucent shape with stroking is there.

There has been a condition bug that composition is applied unnecessarily
even if stroking is disabled. This resulted in broken blending
at gradient filling since it applied alpha values multiple times.

Issues:
https://github.com/Samsung/thorvg/issues/445
This commit is contained in:
Hermet Park 2021-06-29 14:23:38 +09:00 committed by Hermet Park
parent feb71ff36c
commit c31156e737

View file

@ -71,7 +71,8 @@ struct SwShapeTask : SwTask
/* Valid filling & stroking each increases the value by 1. /* Valid filling & stroking each increases the value by 1.
This value is referenced for compositing shape & stroking. */ This value is referenced for compositing shape & stroking. */
uint32_t addStroking = 0; bool stroking = false;
bool filling = false;
//Valid Stroking? //Valid Stroking?
uint8_t strokeAlpha = 0; uint8_t strokeAlpha = 0;
@ -102,7 +103,7 @@ struct SwShapeTask : SwTask
Also, it shouldn't be dash style. */ Also, it shouldn't be dash style. */
auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2 && sdata->strokeDash(nullptr) == 0) ? false : true; auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2 && sdata->strokeDash(nullptr) == 0) ? false : true;
if (!shapeGenRle(&shape, sdata, antiAlias, clips.count > 0 ? true : false)) goto err; if (!shapeGenRle(&shape, sdata, antiAlias, clips.count > 0 ? true : false)) goto err;
++addStroking; filling = true;
} }
} }
} }
@ -114,7 +115,7 @@ struct SwShapeTask : SwTask
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false; auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
if (ctable) shapeResetFill(&shape); if (ctable) shapeResetFill(&shape);
if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err; if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
++addStroking; filling = true;
} else { } else {
shapeDelFill(&shape); shapeDelFill(&shape);
} }
@ -125,7 +126,7 @@ struct SwShapeTask : SwTask
if (validStroke) { if (validStroke) {
shapeResetStroke(&shape, sdata, transform); shapeResetStroke(&shape, sdata, transform);
if (!shapeGenStrokeRle(&shape, sdata, transform, clipRegion, bbox, mpool, tid)) goto err; if (!shapeGenStrokeRle(&shape, sdata, transform, clipRegion, bbox, mpool, tid)) goto err;
++addStroking; stroking = true;
if (auto fill = sdata->strokeFill()) { if (auto fill = sdata->strokeFill()) {
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false; auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
@ -159,7 +160,7 @@ struct SwShapeTask : SwTask
shapeReset(&shape); shapeReset(&shape);
end: end:
shapeDelOutline(&shape, mpool, tid); shapeDelOutline(&shape, mpool, tid);
if (addStroking > 1 && opacity < 255) cmpStroking = true; if (stroking && filling && opacity < 255) cmpStroking = true;
else cmpStroking = false; else cmpStroking = false;
} }