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

View file

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