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 _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 _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;
frameNo = precomp->remap(frameNo, exps);
frameNo = precomp->remap(comp, frameNo, exps);
for (auto c = precomp->children.end() - 1; c >= precomp->children.begin(); --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....
@ -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;
if (!target) return true;
_updateLayer(root, target, frameNo, exps);
_updateLayer(comp, scene, target, frameNo, exps);
if (target->scene) {
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;
@ -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 (!_updateMatte(root, layer, frameNo, exps)) return;
if (!_updateMatte(comp, frameNo, scene, layer, exps)) return;
_updateMaskings(layer, frameNo, exps);
switch (layer->type) {
case LottieLayer::Precomp: {
_updatePrecomp(layer, frameNo, exps);
_updatePrecomp(comp, layer, frameNo, exps);
break;
}
case LottieLayer::Solid: {
@ -1320,7 +1320,7 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, L
layer->scene->blend(layer->blendMethod);
//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;
frameNo += comp->startFrame;
if (frameNo < comp->startFrame) frameNo = comp->startFrame;
if (frameNo >= comp->endFrame) frameNo = (comp->endFrame - 1);
frameNo += comp->root->inFrame;
if (frameNo <comp->root->inFrame) frameNo = comp->root->inFrame;
if (frameNo >= comp->root->outFrame) frameNo = (comp->root->outFrame - 1);
//update children layers
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) {
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;
@ -1455,7 +1455,6 @@ void LottieBuilder::build(LottieComposition* comp)
if (!comp) return;
comp->root->scene = Scene::gen().release();
if (!comp->root->scene) return;
_buildComposition(comp, comp->root);
@ -1463,6 +1462,6 @@ void LottieBuilder::build(LottieComposition* comp)
//viewport clip
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);
}

View file

@ -645,11 +645,11 @@ static jerry_value_t _layer(const jerry_call_info_t* info, const jerry_value_t a
//layer index
if (jerry_value_is_number(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);
//layer name
} else {
layer = comp->layerById(_idByName(args[0]));
layer = comp->root->layerById(_idByName(args[0]));
}
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)
{
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();

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) {
frameNo = comp->frameAtTime(timeRemap(frameNo, exp));

View file

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

View file

@ -965,7 +965,7 @@ LottieObject* LottieParser::parseAsset()
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("p")) data = getString();
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;
layer->comp = comp;
layer->comp = precomp;
context.layer = layer;
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;
root->comp = comp;
precomp->type = LottieLayer::Precomp;
precomp->comp = root;
enterArray();
while (nextArrayValue()) {
root->children.push(parseLayer());
precomp->children.push(parseLayer(precomp));
}
root->prepare();
return root;
precomp->prepare();
return precomp;
}
@ -1396,16 +1396,19 @@ bool LottieParser::parse()
Array<LottieGlyph*> glyphs;
auto startFrame = 0.0f;
auto endFrame = 0.0f;
while (auto key = nextObjectKey()) {
if (KEY_AS("v")) comp->version = getStringCopy();
else if (KEY_AS("fr")) comp->frameRate = getFloat();
else if (KEY_AS("ip")) comp->startFrame = getFloat();
else if (KEY_AS("op")) comp->endFrame = getFloat();
else if (KEY_AS("ip")) startFrame = getFloat();
else if (KEY_AS("op")) endFrame = getFloat();
else if (KEY_AS("w")) comp->w = getFloat();
else if (KEY_AS("h")) comp->h = getFloat();
else if (KEY_AS("nm")) comp->name = getStringCopy();
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("chars")) parseChars(glyphs);
else if (KEY_AS("markers")) parseMarkers();
@ -1417,8 +1420,8 @@ bool LottieParser::parse()
return false;
}
comp->root->inFrame = comp->startFrame;
comp->root->outFrame = comp->endFrame;
comp->root->inFrame = startFrame;
comp->root->outFrame = endFrame;
postProcess(glyphs);

View file

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