lottie: revert "lottie: more precise culling for inverse mattes"

This reverts commit 7ef3352efa.

For mattes of type 'InvAlpha' or 'InvLuma', the matted layer
can still be visible regardless of the matte's opacity (unlike
'Alpha' and 'Luma' masks, which cut out the entire layer when
opacity = 0). The previously introduced optimization incorrectly
assumed that with opacity = 255, the image would not be visible.

@Issue: https://github.com/thorvg/thorvg/issues/3375
@Issue: https://github.com/thorvg/thorvg/issues/3380
@Issue: https://github.com/thorvg/thorvg/issues/3381
@Issue: https://github.com/thorvg/thorvg/issues/3382
This commit is contained in:
Mira Grudzinska 2025-04-06 20:31:00 +02:00 committed by Hermet Park
parent 595769257e
commit b304448ef7
2 changed files with 21 additions and 23 deletions

View file

@ -190,7 +190,7 @@ void LottieBuilder::updateTransform(LottieGroup* parent, LottieObject** child, f
}
void LottieBuilder::updateGroup(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& pcontexts, RenderContext* ctx, uint8_t skip)
void LottieBuilder::updateGroup(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& pcontexts, RenderContext* ctx)
{
auto group = static_cast<LottieGroup*>(*child);
@ -207,7 +207,7 @@ void LottieBuilder::updateGroup(LottieGroup* parent, LottieObject** child, float
auto propagator = group->mergeable() ? ctx->propagator : static_cast<Shape*>(PAINT(ctx->propagator)->duplicate(group->pooling()));
contexts.back(new RenderContext(*ctx, propagator, group->mergeable()));
updateChildren(group, frameNo, contexts, skip);
updateChildren(group, frameNo, contexts);
}
@ -770,7 +770,7 @@ void LottieBuilder::updateTrimpath(TVG_UNUSED LottieGroup* parent, LottieObject*
}
void LottieBuilder::updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts, uint8_t skip)
void LottieBuilder::updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts)
{
contexts.head->begin = parent->children.end() - 1;
@ -782,7 +782,7 @@ void LottieBuilder::updateChildren(LottieGroup* parent, float frameNo, Inlist<Re
//Here switch-case statements are more performant than virtual methods.
switch ((*child)->type) {
case LottieObject::Group: {
updateGroup(parent, child, frameNo, contexts, ctx, skip);
updateGroup(parent, child, frameNo, contexts, ctx);
break;
}
case LottieObject::Transform: {
@ -841,14 +841,14 @@ void LottieBuilder::updateChildren(LottieGroup* parent, float frameNo, Inlist<Re
}
//stop processing for those invisible contents
if (stop || ctx->propagator->opacity() == skip) break;
if (stop || ctx->propagator->opacity() == 0) break;
}
delete(ctx);
}
}
void LottieBuilder::updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo, uint8_t skip)
void LottieBuilder::updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo)
{
if (precomp->children.empty()) return;
@ -856,7 +856,7 @@ void LottieBuilder::updatePrecomp(LottieComposition* comp, LottieLayer* precomp,
ARRAY_REVERSE_FOREACH(c, precomp->children) {
auto child = static_cast<LottieLayer*>(*c);
if (!child->matteSrc) updateLayer(comp, precomp->scene, child, frameNo, skip);
if (!child->matteSrc) updateLayer(comp, precomp->scene, child, frameNo);
}
//clip the layer viewport
@ -866,13 +866,13 @@ void LottieBuilder::updatePrecomp(LottieComposition* comp, LottieLayer* precomp,
}
void LottieBuilder::updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo, Tween& tween, uint8_t skip)
void LottieBuilder::updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo, Tween& tween)
{
//record & recover the tweening frame number before remapping
auto record = tween.frameNo;
tween.frameNo = precomp->remap(comp, record, exps);
updatePrecomp(comp, precomp, frameNo, skip);
updatePrecomp(comp, precomp, frameNo);
tween.frameNo = record;
}
@ -1247,9 +1247,7 @@ bool LottieBuilder::updateMatte(LottieComposition* comp, float frameNo, Scene* s
auto target = layer->matteTarget;
if (!target) return true;
auto skip = (layer->matteType == MaskMethod::InvAlpha || layer->matteType == MaskMethod::InvLuma) ? 255 : 0;
updateLayer(comp, scene, target, frameNo, skip);
updateLayer(comp, scene, target, frameNo);
if (target->scene) {
layer->scene->mask(target->scene, layer->matteType);
@ -1370,7 +1368,7 @@ void LottieBuilder::updateEffect(LottieLayer* layer, float frameNo)
}
void LottieBuilder::updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo, uint8_t skip)
void LottieBuilder::updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo)
{
layer->scene = nullptr;
@ -1380,7 +1378,7 @@ void LottieBuilder::updateLayer(LottieComposition* comp, Scene* scene, LottieLay
updateTransform(layer, frameNo);
//full transparent scene. no need to perform
if (layer->type != LottieLayer::Null && layer->cache.opacity == skip) return;
if (layer->type != LottieLayer::Null && layer->cache.opacity == 0) return;
//Prepare render data
layer->scene = Scene::gen();
@ -1395,8 +1393,8 @@ void LottieBuilder::updateLayer(LottieComposition* comp, Scene* scene, LottieLay
switch (layer->type) {
case LottieLayer::Precomp: {
if (!tweening()) updatePrecomp(comp, layer, frameNo, skip);
else updatePrecomp(comp, layer, frameNo, tween, skip);
if (!tweening()) updatePrecomp(comp, layer, frameNo);
else updatePrecomp(comp, layer, frameNo, tween);
break;
}
case LottieLayer::Solid: {
@ -1415,7 +1413,7 @@ void LottieBuilder::updateLayer(LottieComposition* comp, Scene* scene, LottieLay
if (!layer->children.empty()) {
Inlist<RenderContext> contexts;
contexts.back(new RenderContext(layer->pooling()));
updateChildren(layer, frameNo, contexts, skip);
updateChildren(layer, frameNo, contexts);
contexts.free();
}
break;
@ -1556,7 +1554,7 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo)
ARRAY_REVERSE_FOREACH(child, root->children) {
auto layer = static_cast<LottieLayer*>(*child);
if (!layer->matteSrc) updateLayer(comp, root->scene, layer, frameNo, 0);
if (!layer->matteSrc) updateLayer(comp, root->scene, layer, frameNo);
}
return true;

View file

@ -148,17 +148,17 @@ private:
void updateStrokeEffect(LottieLayer* layer, LottieFxStroke* effect, float frameNo);
void updateEffect(LottieLayer* layer, float frameNo);
void updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo, uint8_t skip);
void updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo);
bool updateMatte(LottieComposition* comp, float frameNo, Scene* scene, LottieLayer* layer);
void updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo, uint8_t skip);
void updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo, Tween& tween, uint8_t skip);
void updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo);
void updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo, Tween& tween);
void updateSolid(LottieLayer* layer);
void updateImage(LottieGroup* layer);
void updateText(LottieLayer* layer, float frameNo);
void updateMasks(LottieLayer* layer, float frameNo);
void updateTransform(LottieLayer* layer, float frameNo);
void updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts, uint8_t skip);
void updateGroup(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& pcontexts, RenderContext* ctx, uint8_t skip);
void updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts);
void updateGroup(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& pcontexts, RenderContext* ctx);
void updateTransform(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
bool updateSolidFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);
bool updateSolidStroke(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx);