diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 20c806bd..1ccc2161 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -815,23 +815,28 @@ static void _updatePrecomp(LottieLayer* precomp, float frameNo, bool caching) //clip the layer viewport if (precomp->w > 0 && precomp->h > 0) { + if (!precomp->cache.clipper) { + precomp->cache.clipper = Shape::gen().release(); + PP(precomp->cache.clipper)->ref(); + precomp->cache.clipper->appendRect(0, 0, static_cast(precomp->w), static_cast(precomp->h)); + } + auto clipper = precomp->cache.clipper; + clipper->transform(precomp->cache.matrix); + //TODO: remove the intermediate scene.... auto cscene = Scene::gen(); - auto clipper = Shape::gen(); - clipper->appendRect(0, 0, static_cast(precomp->w), static_cast(precomp->h)); - clipper->transform(precomp->cache.matrix); - cscene->composite(std::move(clipper), CompositeMethod::ClipPath); + cscene->composite(cast(clipper), CompositeMethod::ClipPath); cscene->push(cast(precomp->scene)); precomp->scene = cscene.release(); } } -static void _updateSolid(LottieLayer* layer, float frameNo) +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->opacity(frameNo)); + shape->fill(layer->color.rgb[0], layer->color.rgb[1], layer->color.rgb[2], layer->cache.opacity); layer->scene->push(std::move(shape)); } @@ -946,7 +951,7 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, b break; } case LottieLayer::Solid: { - _updateSolid(layer, frameNo); + _updateSolid(layer); break; } default: { diff --git a/src/loaders/lottie/tvgLottieLoader.cpp b/src/loaders/lottie/tvgLottieLoader.cpp index dcfdd53d..549c9968 100644 --- a/src/loaders/lottie/tvgLottieLoader.cpp +++ b/src/loaders/lottie/tvgLottieLoader.cpp @@ -316,7 +316,8 @@ unique_ptr LottieLoader::paint() bool LottieLoader::frame(float no) { - if (mathEqual(this->frameNo, no)) return false; + //no meaing to update if frame diff is less then 1ms + if (fabsf(this->frameNo - no) < 0.001f) return false; this->done(); diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 662b4418..b71f843d 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -142,6 +142,25 @@ void LottieGroup::prepare(LottieObject::Type type) } +LottieLayer::~LottieLayer() +{ + if (refId) { + //No need to free assets children because the Composition owns them. + children.clear(); + free(refId); + } + + for (auto m = masks.data; m < masks.end(); ++m) { + delete(*m); + } + + delete(matte.target); + delete(transform); + + if (cache.scene && PP(cache.scene)->unref() == 0) delete(cache.scene); + if (cache.clipper && PP(cache.clipper)->unref() == 0) delete(cache.clipper); +} + void LottieLayer::prepare() { if (transform) statical &= transform->statical; diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index 36255d7b..503560f2 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -485,22 +485,7 @@ struct LottieLayer : LottieGroup { enum Type : uint8_t {Precomp = 0, Solid, Image, Null, Shape, Text}; - ~LottieLayer() - { - if (refId) { - //No need to free assets children because the Composition owns them. - children.clear(); - free(refId); - } - - for (auto m = masks.data; m < masks.end(); ++m) { - delete(*m); - } - - delete(matte.target); - delete(transform); - delete(cache.scene); - } + ~LottieLayer(); uint8_t opacity(float frameNo) { @@ -539,7 +524,10 @@ struct LottieLayer : LottieGroup float frameNo = -1.0f; Matrix matrix; uint8_t opacity; - Paint* scene = nullptr; //tvg statc render ddata + + //tvg render data + Paint* scene = nullptr; + tvg::Shape* clipper = nullptr; } cache; Type type = Null;