lottie: code refactoring

- removed unnecessary variables.
- migrated the composition methods to the precomp layer.
This commit is contained in:
Hermet Park 2024-07-22 21:50:10 +09:00 committed by Hermet Park
parent 828f8e0767
commit 3804bbec57
6 changed files with 54 additions and 60 deletions

View file

@ -97,7 +97,7 @@ struct RenderContext
static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts, LottieExpressions* exps); static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts, LottieExpressions* exps);
static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps); static void _updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo, LottieExpressions* exps);
static bool _buildComposition(LottieComposition* comp, LottieLayer* parent); static bool _buildComposition(LottieComposition* comp, LottieLayer* parent);
static bool _draw(LottieGroup* parent, LottieShape* shape, RenderContext* ctx); static bool _draw(LottieGroup* parent, LottieShape* shape, RenderContext* ctx);
@ -1035,15 +1035,15 @@ static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderCon
} }
static void _updatePrecomp(LottieLayer* precomp, float frameNo, LottieExpressions* exps) static void _updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo, LottieExpressions* exps)
{ {
if (precomp->children.empty()) return; if (precomp->children.empty()) return;
frameNo = precomp->remap(frameNo, exps); frameNo = precomp->remap(comp, frameNo, exps);
for (auto c = precomp->children.end() - 1; c >= precomp->children.begin(); --c) { for (auto c = precomp->children.end() - 1; c >= precomp->children.begin(); --c) {
auto child = static_cast<LottieLayer*>(*c); auto child = static_cast<LottieLayer*>(*c);
if (!child->matteSrc) _updateLayer(precomp, child, frameNo, exps); if (!child->matteSrc) _updateLayer(comp, precomp->scene, child, frameNo, exps);
} }
//TODO: remove the intermediate scene.... //TODO: remove the intermediate scene....
@ -1244,12 +1244,12 @@ static void _updateMaskings(LottieLayer* layer, float frameNo, LottieExpressions
} }
static bool _updateMatte(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps) static bool _updateMatte(LottieComposition* comp, float frameNo, Scene* scene, LottieLayer* layer, LottieExpressions* exps)
{ {
auto target = layer->matteTarget; auto target = layer->matteTarget;
if (!target) return true; if (!target) return true;
_updateLayer(root, target, frameNo, exps); _updateLayer(comp, scene, target, frameNo, exps);
if (target->scene) { if (target->scene) {
layer->scene->composite(cast(target->scene), layer->matteType); layer->scene->composite(cast(target->scene), layer->matteType);
@ -1263,7 +1263,7 @@ static bool _updateMatte(LottieLayer* root, LottieLayer* layer, float frameNo, L
} }
static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps) static void _updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo, LottieExpressions* exps)
{ {
layer->scene = nullptr; layer->scene = nullptr;
@ -1285,13 +1285,13 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, L
if (layer->matteTarget && layer->masks.count > 0) TVGERR("LOTTIE", "FIXME: Matte + Masking??"); if (layer->matteTarget && layer->masks.count > 0) TVGERR("LOTTIE", "FIXME: Matte + Masking??");
if (!_updateMatte(root, layer, frameNo, exps)) return; if (!_updateMatte(comp, frameNo, scene, layer, exps)) return;
_updateMaskings(layer, frameNo, exps); _updateMaskings(layer, frameNo, exps);
switch (layer->type) { switch (layer->type) {
case LottieLayer::Precomp: { case LottieLayer::Precomp: {
_updatePrecomp(layer, frameNo, exps); _updatePrecomp(comp, layer, frameNo, exps);
break; break;
} }
case LottieLayer::Solid: { case LottieLayer::Solid: {
@ -1320,7 +1320,7 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, L
layer->scene->blend(layer->blendMethod); layer->scene->blend(layer->blendMethod);
//the given matte source was composited by the target earlier. //the given matte source was composited by the target earlier.
if (!layer->matteSrc) root->scene->push(cast(layer->scene)); if (!layer->matteSrc) scene->push(cast(layer->scene));
} }
@ -1431,9 +1431,9 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo)
{ {
if (comp->root->children.empty()) return false; if (comp->root->children.empty()) return false;
frameNo += comp->startFrame; frameNo += comp->root->inFrame;
if (frameNo < comp->startFrame) frameNo = comp->startFrame; if (frameNo <comp->root->inFrame) frameNo = comp->root->inFrame;
if (frameNo >= comp->endFrame) frameNo = (comp->endFrame - 1); if (frameNo >= comp->root->outFrame) frameNo = (comp->root->outFrame - 1);
//update children layers //update children layers
auto root = comp->root; auto root = comp->root;
@ -1443,7 +1443,7 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo)
for (auto child = root->children.end() - 1; child >= root->children.begin(); --child) { for (auto child = root->children.end() - 1; child >= root->children.begin(); --child) {
auto layer = static_cast<LottieLayer*>(*child); auto layer = static_cast<LottieLayer*>(*child);
if (!layer->matteSrc) _updateLayer(root, layer, frameNo, exps); if (!layer->matteSrc) _updateLayer(comp, root->scene, layer, frameNo, exps);
} }
return true; return true;
@ -1455,7 +1455,6 @@ void LottieBuilder::build(LottieComposition* comp)
if (!comp) return; if (!comp) return;
comp->root->scene = Scene::gen().release(); comp->root->scene = Scene::gen().release();
if (!comp->root->scene) return;
_buildComposition(comp, comp->root); _buildComposition(comp, comp->root);
@ -1463,6 +1462,6 @@ void LottieBuilder::build(LottieComposition* comp)
//viewport clip //viewport clip
auto clip = Shape::gen(); auto clip = Shape::gen();
clip->appendRect(0, 0, static_cast<float>(comp->w), static_cast<float>(comp->h)); clip->appendRect(0, 0, comp->w, comp->h);
comp->root->scene->composite(std::move(clip), CompositeMethod::ClipPath); comp->root->scene->composite(std::move(clip), CompositeMethod::ClipPath);
} }

View file

@ -645,11 +645,11 @@ static jerry_value_t _layer(const jerry_call_info_t* info, const jerry_value_t a
//layer index //layer index
if (jerry_value_is_number(args[0])) { if (jerry_value_is_number(args[0])) {
auto idx = (uint16_t)jerry_value_as_int32(args[0]); auto idx = (uint16_t)jerry_value_as_int32(args[0]);
layer = comp->layerByIdx(idx); layer = comp->root->layerByIdx(idx);
jerry_value_free(idx); jerry_value_free(idx);
//layer name //layer name
} else { } else {
layer = comp->layerById(_idByName(args[0])); layer = comp->root->layerById(_idByName(args[0]));
} }
if (!layer) return jerry_undefined(); if (!layer) return jerry_undefined();
@ -1043,7 +1043,7 @@ static void _buildProperty(float frameNo, jerry_value_t context, LottieExpressio
static jerry_value_t _comp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) static jerry_value_t _comp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
{ {
auto comp = static_cast<LottieComposition*>(jerry_object_get_native_ptr(info->function, nullptr)); auto comp = static_cast<LottieComposition*>(jerry_object_get_native_ptr(info->function, nullptr));
auto layer = comp->asset(_idByName(args[0])); auto layer = comp->root->layerById(_idByName(args[0]));
if (!layer) return jerry_undefined(); if (!layer) return jerry_undefined();

View file

@ -413,7 +413,7 @@ void LottieLayer::prepare(RGB24* color)
} }
float LottieLayer::remap(float frameNo, LottieExpressions* exp) float LottieLayer::remap(LottieComposition* comp, float frameNo, LottieExpressions* exp)
{ {
if (timeRemap.frames || timeRemap.value) { if (timeRemap.frames || timeRemap.value) {
frameNo = comp->frameAtTime(timeRemap(frameNo, exp)); frameNo = comp->frameAtTime(timeRemap(frameNo, exp));

View file

@ -587,12 +587,12 @@ struct LottieLayer : LottieGroup, LottieRenderPooler<tvg::Shape>
bool mergeable() override { return false; } bool mergeable() override { return false; }
void prepare(RGB24* color = nullptr); void prepare(RGB24* color = nullptr);
float remap(float frameNo, LottieExpressions* exp); float remap(LottieComposition* comp, float frameNo, LottieExpressions* exp);
char* name = nullptr; char* name = nullptr;
LottieLayer* parent = nullptr; LottieLayer* parent = nullptr;
LottieFloat timeRemap = 0.0f; LottieFloat timeRemap = 0.0f;
LottieComposition* comp = nullptr; LottieLayer* comp = nullptr; //Precompositor, current layer is belonges.
LottieTransform* transform = nullptr; LottieTransform* transform = nullptr;
Array<LottieMask*> masks; Array<LottieMask*> masks;
LottieLayer* matteTarget = nullptr; LottieLayer* matteTarget = nullptr;
@ -619,9 +619,20 @@ struct LottieLayer : LottieGroup, LottieRenderPooler<tvg::Shape>
bool autoOrient = false; bool autoOrient = false;
bool matteSrc = false; bool matteSrc = false;
LottieLayer* layerById(unsigned long id)
{
for (auto child = children.begin(); child < children.end(); ++child) {
if ((*child)->type != LottieObject::Type::Layer) continue;
auto layer = static_cast<LottieLayer*>(*child);
if (layer->id == id) return layer;
}
return nullptr;
}
LottieLayer* layerByIdx(int16_t idx) LottieLayer* layerByIdx(int16_t idx)
{ {
for (auto child = children.begin(); child < children.end(); ++child) { for (auto child = children.begin(); child < children.end(); ++child) {
if ((*child)->type != LottieObject::Type::Layer) continue;
auto layer = static_cast<LottieLayer*>(*child); auto layer = static_cast<LottieLayer*>(*child);
if (layer->idx == idx) return layer; if (layer->idx == idx) return layer;
} }
@ -679,30 +690,12 @@ struct LottieComposition
float timeAtFrame(float frameNo) float timeAtFrame(float frameNo)
{ {
return (frameNo - startFrame) / frameRate; return (frameNo - root->inFrame) / frameRate;
} }
float frameCnt() const float frameCnt() const
{ {
return endFrame - startFrame; return root->outFrame - root->inFrame;
}
LottieLayer* layerById(unsigned long id)
{
for (auto child = root->children.begin(); child < root->children.end(); ++child) {
auto layer = static_cast<LottieLayer*>(*child);
if (layer->id == id) return layer;
}
return nullptr;
}
LottieLayer* layerByIdx(int16_t idx)
{
for (auto child = root->children.begin(); child < root->children.end(); ++child) {
auto layer = static_cast<LottieLayer*>(*child);
if (layer->idx == idx) return layer;
}
return nullptr;
} }
LottieLayer* asset(unsigned long id) LottieLayer* asset(unsigned long id)
@ -718,7 +711,6 @@ struct LottieComposition
char* version = nullptr; char* version = nullptr;
char* name = nullptr; char* name = nullptr;
float w, h; float w, h;
float startFrame, endFrame;
float frameRate; float frameRate;
Array<LottieObject*> assets; Array<LottieObject*> assets;
Array<LottieInterpolator*> interpolators; Array<LottieInterpolator*> interpolators;

View file

@ -965,7 +965,7 @@ LottieObject* LottieParser::parseAsset()
id = _int2str(getInt()); id = _int2str(getInt());
} }
} }
else if (KEY_AS("layers")) obj = parseLayers(); else if (KEY_AS("layers")) obj = parseLayers(comp->root);
else if (KEY_AS("u")) subPath = getString(); else if (KEY_AS("u")) subPath = getString();
else if (KEY_AS("p")) data = getString(); else if (KEY_AS("p")) data = getString();
else if (KEY_AS("w")) width = getFloat(); else if (KEY_AS("w")) width = getFloat();
@ -1236,11 +1236,11 @@ void LottieParser::parseMasks(LottieLayer* layer)
} }
LottieLayer* LottieParser::parseLayer() LottieLayer* LottieParser::parseLayer(LottieLayer* precomp)
{ {
auto layer = new LottieLayer; auto layer = new LottieLayer;
layer->comp = comp; layer->comp = precomp;
context.layer = layer; context.layer = layer;
auto ddd = false; auto ddd = false;
@ -1295,20 +1295,20 @@ LottieLayer* LottieParser::parseLayer()
} }
LottieLayer* LottieParser::parseLayers() LottieLayer* LottieParser::parseLayers(LottieLayer* root)
{ {
auto root = new LottieLayer; auto precomp = new LottieLayer;
root->type = LottieLayer::Precomp; precomp->type = LottieLayer::Precomp;
root->comp = comp; precomp->comp = root;
enterArray(); enterArray();
while (nextArrayValue()) { while (nextArrayValue()) {
root->children.push(parseLayer()); precomp->children.push(parseLayer(precomp));
} }
root->prepare(); precomp->prepare();
return root; return precomp;
} }
@ -1396,16 +1396,19 @@ bool LottieParser::parse()
Array<LottieGlyph*> glyphs; Array<LottieGlyph*> glyphs;
auto startFrame = 0.0f;
auto endFrame = 0.0f;
while (auto key = nextObjectKey()) { while (auto key = nextObjectKey()) {
if (KEY_AS("v")) comp->version = getStringCopy(); if (KEY_AS("v")) comp->version = getStringCopy();
else if (KEY_AS("fr")) comp->frameRate = getFloat(); else if (KEY_AS("fr")) comp->frameRate = getFloat();
else if (KEY_AS("ip")) comp->startFrame = getFloat(); else if (KEY_AS("ip")) startFrame = getFloat();
else if (KEY_AS("op")) comp->endFrame = getFloat(); else if (KEY_AS("op")) endFrame = getFloat();
else if (KEY_AS("w")) comp->w = getFloat(); else if (KEY_AS("w")) comp->w = getFloat();
else if (KEY_AS("h")) comp->h = getFloat(); else if (KEY_AS("h")) comp->h = getFloat();
else if (KEY_AS("nm")) comp->name = getStringCopy(); else if (KEY_AS("nm")) comp->name = getStringCopy();
else if (KEY_AS("assets")) parseAssets(); else if (KEY_AS("assets")) parseAssets();
else if (KEY_AS("layers")) comp->root = parseLayers(); else if (KEY_AS("layers")) comp->root = parseLayers(comp->root);
else if (KEY_AS("fonts")) parseFonts(); else if (KEY_AS("fonts")) parseFonts();
else if (KEY_AS("chars")) parseChars(glyphs); else if (KEY_AS("chars")) parseChars(glyphs);
else if (KEY_AS("markers")) parseMarkers(); else if (KEY_AS("markers")) parseMarkers();
@ -1417,8 +1420,8 @@ bool LottieParser::parse()
return false; return false;
} }
comp->root->inFrame = comp->startFrame; comp->root->inFrame = startFrame;
comp->root->outFrame = comp->endFrame; comp->root->outFrame = endFrame;
postProcess(glyphs); postProcess(glyphs);

View file

@ -74,7 +74,7 @@ private:
LottieObject* parseObject(); LottieObject* parseObject();
LottieObject* parseAsset(); LottieObject* parseAsset();
LottieImage* parseImage(const char* data, const char* subPath, bool embedded, float width, float height); LottieImage* parseImage(const char* data, const char* subPath, bool embedded, float width, float height);
LottieLayer* parseLayer(); LottieLayer* parseLayer(LottieLayer* precomp);
LottieObject* parseGroup(); LottieObject* parseGroup();
LottieRect* parseRect(); LottieRect* parseRect();
LottieEllipse* parseEllipse(); LottieEllipse* parseEllipse();
@ -86,7 +86,7 @@ private:
LottiePolyStar* parsePolyStar(); LottiePolyStar* parsePolyStar();
LottieRoundedCorner* parseRoundedCorner(); LottieRoundedCorner* parseRoundedCorner();
LottieGradientFill* parseGradientFill(); LottieGradientFill* parseGradientFill();
LottieLayer* parseLayers(); LottieLayer* parseLayers(LottieLayer* root);
LottieMask* parseMask(); LottieMask* parseMask();
LottieTrimpath* parseTrimpath(); LottieTrimpath* parseTrimpath();
LottieRepeater* parseRepeater(); LottieRepeater* parseRepeater();