From 43a5bf2fce19b78cebe7962d19d7ac4b8bf9be3f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 11 Jul 2024 12:49:20 +0900 Subject: [PATCH] lottie: ++ scene composing optimization retain resuable layer solid paint during animation. --- src/loaders/lottie/tvgLottieBuilder.cpp | 6 ++---- src/loaders/lottie/tvgLottieModel.cpp | 14 +++++++++++++- src/loaders/lottie/tvgLottieModel.h | 4 ++-- src/loaders/lottie/tvgLottieParser.cpp | 5 +++-- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index dd80f754..081ab793 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -1020,10 +1020,8 @@ static void _updatePrecomp(LottieLayer* precomp, float frameNo, LottieExpression static void _updateSolid(LottieLayer* layer) { - auto shape = Shape::gen(); - shape->appendRect(0, 0, static_cast(layer->w), static_cast(layer->h)); - shape->fill(layer->color.rgb[0], layer->color.rgb[1], layer->color.rgb[2], layer->cache.opacity); - layer->scene->push(std::move(shape)); + layer->solidFill->opacity(layer->cache.opacity); + layer->scene->push(cast(layer->solidFill)); } diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index bc1c9ecd..55723f1e 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -331,13 +331,16 @@ LottieLayer::~LottieLayer() delete(*m); } + //Remove tvg render paints + if (solidFill && PP(solidFill)->unref() == 0) delete(solidFill); if (clipper && PP(clipper)->unref() == 0) delete(clipper); delete(transform); free(name); } -void LottieLayer::prepare() + +void LottieLayer::prepare(RGB24* color) { /* if layer is hidden, only useful data is its transform matrix. so force it to be a Null Layer and release all resource. */ @@ -347,6 +350,15 @@ void LottieLayer::prepare() children.reset(); return; } + + //prepare solid fill in advance if it is a layer type. + if (color && type == LottieLayer::Solid) { + solidFill = Shape::gen().release(); + solidFill->appendRect(0, 0, static_cast(w), static_cast(h)); + solidFill->fill(color->rgb[0], color->rgb[1], color->rgb[2]); + PP(solidFill)->ref(); + } + LottieGroup::prepare(LottieObject::Layer); } diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index 79b97348..11b824ed 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -582,7 +582,7 @@ struct LottieLayer : LottieGroup bool mergeable() override { return false; } - void prepare(); + void prepare(RGB24* color = nullptr); float remap(float frameNo, LottieExpressions* exp); char* name = nullptr; @@ -591,9 +591,9 @@ struct LottieLayer : LottieGroup LottieComposition* comp = nullptr; LottieTransform* transform = nullptr; Array masks; - RGB24 color; //used by Solid layer LottieLayer* matteTarget = nullptr; + tvg::Shape* solidFill = nullptr; tvg::Shape* clipper = nullptr; float timeStretch = 1.0f; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index bd157376..13f37198 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -1241,6 +1241,7 @@ LottieLayer* LottieParser::parseLayer() context.layer = layer; auto ddd = false; + RGB24 color; enterObject(); @@ -1269,7 +1270,7 @@ LottieLayer* LottieParser::parseLayer() else if (KEY_AS("tm")) parseTimeRemap(layer); else if (KEY_AS("w") || KEY_AS("sw")) getLayerSize(layer->w); else if (KEY_AS("h") || KEY_AS("sh")) getLayerSize(layer->h); - else if (KEY_AS("sc")) layer->color = getColor(getString()); + else if (KEY_AS("sc")) color = getColor(getString()); else if (KEY_AS("tt")) layer->matteType = getMatteType(); else if (KEY_AS("tp")) layer->mid = getInt(); else if (KEY_AS("masksProperties")) parseMasks(layer); @@ -1285,7 +1286,7 @@ LottieLayer* LottieParser::parseLayer() else skip(key); } - layer->prepare(); + layer->prepare(&color); return layer; }