From c71ae8595372854fca48debc4fc553b76d4c2f63 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 25 Oct 2023 11:08:42 +0900 Subject: [PATCH] lottie: clean up code no logical changes, only code clean-up --- src/loaders/lottie/tvgLottieBuilder.cpp | 128 +++++++++++++++--------- src/loaders/lottie/tvgLottieModel.cpp | 12 +++ src/loaders/lottie/tvgLottieModel.h | 22 ++-- src/loaders/lottie/tvgLottieParser.cpp | 2 - 4 files changed, 97 insertions(+), 67 deletions(-) diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 27020872..ec6ff9c3 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -85,7 +85,7 @@ struct RenderContext static void _updateChildren(LottieGroup* parent, float frameNo, queue& contexts); static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo); -static bool _buildPrecomp(LottieComposition* comp, LottieGroup* parent); +static bool _buildComposition(LottieComposition* comp, LottieGroup* parent); static void _rotateX(Matrix* m, float degree) { @@ -177,8 +177,9 @@ static void _updateTransform(LottieLayer* layer, float frameNo) } -static void _updateTransform(LottieTransform* transform, float frameNo, RenderContext& ctx) +static void _updateTransform(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto transform = static_cast(*child); if (!transform) return; ctx.merging = nullptr; @@ -198,8 +199,10 @@ static void _updateTransform(LottieTransform* transform, float frameNo, RenderCo } -static void _updateGroup(LottieGroup* parent, LottieGroup* group, float frameNo, RenderContext& ctx) +static void _updateGroup(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& pcontexts, RenderContext& ctx) { + auto group = static_cast(*child); + if (group->children.empty()) return; //Prepare render data @@ -245,7 +248,7 @@ static bool _fragmentedStroking(LottieObject** child, queue& cont } -static void _updateSolidStroke(LottieObject** child, float frameNo, queue& contexts, RenderContext& ctx) +static void _updateSolidStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, queue& contexts, RenderContext& ctx) { if (_fragmentedStroking(child, contexts, ctx)) return; @@ -259,7 +262,7 @@ static void _updateSolidStroke(LottieObject** child, float frameNo, queue& contexts, RenderContext& ctx) +static void _updateGradientStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, queue& contexts, RenderContext& ctx) { if (_fragmentedStroking(child, contexts, ctx)) return; @@ -272,10 +275,12 @@ static void _updateGradientStroke(LottieObject** child, float frameNo, queue& contexts, RenderContext& ctx) { if (ctx.stroking) return; + auto fill = static_cast(*child); + ctx.merging = nullptr; auto color = fill->color(frameNo); @@ -286,10 +291,12 @@ static void _updateFill(LottieSolidFill* fill, float frameNo, RenderContext& ctx } -static Shape* _updateFill(LottieGradientFill* fill, float frameNo, RenderContext& ctx) +static Shape* _updateGradientFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { if (ctx.stroking) return nullptr; + auto fill = static_cast(*child); + ctx.merging = nullptr; //TODO: reuse the fill instance? @@ -363,8 +370,10 @@ static void _repeat(LottieGroup* parent, unique_ptr path, RenderContext& } -static void _updateRect(LottieGroup* parent, LottieRect* rect, float frameNo, RenderContext& ctx) +static void _updateRect(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto rect= static_cast(*child); + auto position = rect->position(frameNo); auto size = rect->size(frameNo); auto roundness = rect->radius(frameNo); @@ -386,8 +395,10 @@ static void _updateRect(LottieGroup* parent, LottieRect* rect, float frameNo, Re } -static void _updateEllipse(LottieGroup* parent, LottieEllipse* ellipse, float frameNo, RenderContext& ctx) +static void _updateEllipse(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto ellipse= static_cast(*child); + auto position = ellipse->position(frameNo); auto size = ellipse->size(frameNo); @@ -402,8 +413,10 @@ static void _updateEllipse(LottieGroup* parent, LottieEllipse* ellipse, float fr } -static void _updatePath(LottieGroup* parent, LottiePath* path, float frameNo, RenderContext& ctx) +static void _updatePath(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto path= static_cast(*child); + if (ctx.repeater) { auto p = Shape::gen(); path->pathset(frameNo, P(p)->rs.path.cmds, P(p)->rs.path.pts); @@ -601,8 +614,10 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr } -static void _updatePolystar(LottieGroup* parent, LottiePolyStar* star, float frameNo, RenderContext& ctx) +static void _updatePolystar(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto star= static_cast(*child); + //Optimize: Can we skip the individual coords transform? Matrix matrix; mathIdentity(&matrix); @@ -626,8 +641,9 @@ static void _updatePolystar(LottieGroup* parent, LottiePolyStar* star, float fra } -static void _updateImage(LottieGroup* parent, LottieImage* image, float frameNo, RenderContext& ctx) +static void _updateImage(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto image = static_cast(*child); auto picture = image->picture; if (!picture) { @@ -649,6 +665,9 @@ static void _updateImage(LottieGroup* parent, LottieImage* image, float frameNo, } TaskScheduler::async(true); + + image->picture = picture; + PP(picture)->ref(); } if (ctx.propagator) { @@ -657,23 +676,23 @@ static void _updateImage(LottieGroup* parent, LottieImage* image, float frameNo, } picture->opacity(PP(ctx.propagator)->opacity); } - - //TODO: remove duplicate. - image->picture = (Picture*)picture->duplicate(); - parent->scene->push(cast(picture)); } -static void _updateRoundedCorner(LottieRoundedCorner* roundedCorner, float frameNo, RenderContext& ctx) +static void _updateRoundedCorner(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto roundedCorner= static_cast(*child); + auto roundness = roundedCorner->radius(frameNo); if (ctx.roundness < roundness) ctx.roundness = roundness; } -static void _updateRepeater(LottieRepeater* repeater, float frameNo, RenderContext& ctx) +static void _updateRepeater(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto repeater= static_cast(*child); + if (!ctx.repeater) ctx.repeater = new RenderRepeater(); ctx.repeater->cnt = static_cast(repeater->copies(frameNo)); ctx.repeater->offset = repeater->offset(frameNo); @@ -690,8 +709,10 @@ static void _updateRepeater(LottieRepeater* repeater, float frameNo, RenderConte } -static void _updateTrimpath(LottieTrimpath* trimpath, float frameNo, RenderContext& ctx) +static void _updateTrimpath(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED queue& contexts, RenderContext& ctx) { + auto trimpath= static_cast(*child); + float begin, end; trimpath->segment(frameNo, begin, end); @@ -717,62 +738,61 @@ static void _updateChildren(LottieGroup* parent, float frameNo, queuereqFragment; for (auto child = ctx.begin; child >= parent->children.data; --child) { - //TODO: Polymorphsim? switch ((*child)->type) { case LottieObject::Group: { - _updateGroup(parent, static_cast(*child), frameNo, ctx); + _updateGroup(parent, child, frameNo, contexts, ctx); break; } case LottieObject::Transform: { - _updateTransform(static_cast(*child), frameNo, ctx); + _updateTransform(parent, child, frameNo, contexts, ctx); break; } case LottieObject::SolidFill: { - _updateFill(static_cast(*child), frameNo, ctx); + _updateSolidFill(parent, child, frameNo, contexts, ctx); break; } case LottieObject::SolidStroke: { - _updateSolidStroke(child, frameNo, contexts, ctx); + _updateSolidStroke(parent, child, frameNo, contexts, ctx); break; } case LottieObject::GradientFill: { - _updateFill(static_cast(*child), frameNo, ctx); + _updateGradientFill(parent, child, frameNo, contexts, ctx); break; } case LottieObject::GradientStroke: { - _updateGradientStroke(child, frameNo, contexts, ctx); + _updateGradientStroke(parent, child, frameNo, contexts, ctx); break; } case LottieObject::Rect: { - _updateRect(parent, static_cast(*child), frameNo, ctx); + _updateRect(parent, child, frameNo, contexts, ctx); break; } case LottieObject::Ellipse: { - _updateEllipse(parent, static_cast(*child), frameNo, ctx); + _updateEllipse(parent, child, frameNo, contexts, ctx); break; } case LottieObject::Path: { - _updatePath(parent, static_cast(*child), frameNo, ctx); + _updatePath(parent, child, frameNo, contexts, ctx); break; } case LottieObject::Polystar: { - _updatePolystar(parent, static_cast(*child), frameNo, ctx); + _updatePolystar(parent, child, frameNo, contexts, ctx); break; } case LottieObject::Image: { - _updateImage(parent, static_cast(*child), frameNo, ctx); + _updateImage(parent, child, frameNo, contexts, ctx); break; } case LottieObject::Trimpath: { - _updateTrimpath(static_cast(*child), frameNo, ctx); + _updateTrimpath(parent, child, frameNo, contexts, ctx); break; } case LottieObject::Repeater: { - _updateRepeater(static_cast(*child), frameNo, ctx); + _updateRepeater(parent, child, frameNo, contexts, ctx); break; } case LottieObject::RoundedCorner: { - _updateRoundedCorner(static_cast(*child), frameNo, ctx); + _updateRoundedCorner(parent, child, frameNo, contexts, ctx); break; } default: break; @@ -855,6 +875,25 @@ static void _updateMaskings(LottieLayer* layer, float frameNo) } +static bool _updateMatte(LottieLayer* root, LottieLayer* layer, float frameNo) +{ + auto target = layer->matte.target; + if (!target) return true; + + _updateLayer(root, target, frameNo); + + if (target->scene) { + layer->scene->composite(cast(target->scene), layer->matte.type); + } else if (layer->matte.type == CompositeMethod::AlphaMask || layer->matte.type == CompositeMethod::LumaMask) { + //matte target is not exist. alpha blending definitely bring an invisible result + delete(layer->scene); + layer->scene = nullptr; + return false; + } + return true; +} + + static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo) { layer->scene = nullptr; @@ -877,17 +916,7 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo) if (layer->matte.target && layer->masks.count > 0) TVGERR("LOTTIE", "FIXME: Matte + Masking??"); - //matte masking layer - if (layer->matte.target) { - _updateLayer(root, layer->matte.target, frameNo); - if (layer->matte.target->scene) layer->scene->composite(cast(layer->matte.target->scene), layer->matte.type); - else if (layer->matte.type == CompositeMethod::AlphaMask || layer->matte.type == CompositeMethod::LumaMask) { - //matte target is not exist. alpha blending definitely bring an invisible result - delete(layer->scene); - layer->scene = nullptr; - return; - } - } + if (!_updateMatte(root, layer, frameNo)) return; _updateMaskings(layer, frameNo); @@ -923,7 +952,7 @@ static void _buildReference(LottieComposition* comp, LottieLayer* layer) if (strcmp(layer->refId, (*asset)->name)) continue; if (layer->type == LottieLayer::Precomp) { auto assetLayer = static_cast(*asset); - if (_buildPrecomp(comp, assetLayer)) { + if (_buildComposition(comp, assetLayer)) { layer->children = assetLayer->children; } } else if (layer->type == LottieLayer::Image) { @@ -993,7 +1022,7 @@ static void _checkFragment(LottieGroup* parent) } -static bool _buildPrecomp(LottieComposition* comp, LottieGroup* parent) +static bool _buildComposition(LottieComposition* comp, LottieGroup* parent) { if (parent->children.count == 0) return false; @@ -1029,7 +1058,6 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo) //Update root layer auto root = comp->root; - if (!root) return false; //Prepare render data if (!root->scene) { @@ -1051,12 +1079,12 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo) void LottieBuilder::build(LottieComposition* comp) { - if (!comp || comp->scene) return; + if (!comp || !comp->root || comp->scene) return; comp->scene = Scene::gen().release(); if (!comp->scene) return; - _buildPrecomp(comp, comp->root); + _buildComposition(comp, comp->root); if (!update(comp, 0)) return; diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 023b20fd..493c0b10 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -20,6 +20,7 @@ * SOFTWARE. */ +#include "tvgPaint.h" #include "tvgFill.h" #include "tvgLottieModel.h" @@ -34,6 +35,17 @@ /* External Class Implementation */ /************************************************************************/ +LottieImage::~LottieImage() +{ + free(b64Data); + free(mimeType); + + if (PP(picture)->unref() == 0) { + delete(picture); + } +} + + void LottieTrimpath::segment(float frameNo, float& start, float& end) { auto s = this->start(frameNo) * 0.01f; diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index ce8ca0ce..97dcf3e5 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -223,7 +223,7 @@ struct LottieObject Image, Trimpath, Repeater, - RoundedCorner, + RoundedCorner }; virtual ~LottieObject() @@ -234,7 +234,7 @@ struct LottieObject char* name = nullptr; Type type; bool statical = true; //no keyframes - bool hidden = false; + bool hidden = false; //remove? }; @@ -358,9 +358,9 @@ struct LottieTransform : LottieObject void prepare() { LottieObject::type = LottieObject::Transform; - if (position.frames || rotation.frames || scale.frames || anchor.frames || opacity.frames) statical = false; - else if (coords && (coords->x.frames || coords->y.frames)) statical = false; - else if (rotationEx && (rotationEx->x.frames || rotationEx->y.frames)) statical = false; + if (position.frames || rotation.frames || scale.frames || anchor.frames || opacity.frames || (coords && (coords->x.frames || coords->y.frames)) || (rotationEx && (rotationEx->x.frames || rotationEx->y.frames))) { + statical = false; + } } LottiePosition position = Point{0.0f, 0.0f}; @@ -434,12 +434,7 @@ struct LottieImage : LottieObject Picture* picture = nullptr; //tvg render data - ~LottieImage() - { - free(b64Data); - free(mimeType); - delete(picture); - } + ~LottieImage(); void prepare() { @@ -517,9 +512,6 @@ struct LottieLayer : LottieGroup void prepare(); float remap(float frameNo); - //Optimize: compact data?? - RGB24 color; - struct { CompositeMethod type = CompositeMethod::None; LottieLayer* target = nullptr; @@ -531,6 +523,7 @@ struct LottieLayer : LottieGroup LottieComposition* comp = nullptr; LottieTransform* transform = nullptr; Array masks; + RGB24 color; //used by Solid layer float timeStretch = 1.0f; uint32_t w = 0, h = 0; @@ -550,7 +543,6 @@ struct LottieLayer : LottieGroup Type type = Null; bool autoOrient = false; - bool roundedCorner = false; bool matteSrc = false; }; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 95d74f28..3a78a43c 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -645,8 +645,6 @@ LottieRoundedCorner* LottieParser::parseRoundedCorner() auto corner = new LottieRoundedCorner; if (!corner) return nullptr; - context->layer->roundedCorner = true; - while (auto key = nextObjectKey()) { if (!strcmp(key, "nm")) corner->name = getStringCopy(); else if (!strcmp(key, "r")) parseProperty(corner->radius);