diff --git a/src/lib/tvgLoadModule.h b/src/lib/tvgLoadModule.h index 5f39a3e0..29ceba3f 100644 --- a/src/lib/tvgLoadModule.h +++ b/src/lib/tvgLoadModule.h @@ -44,9 +44,11 @@ public: virtual bool resize(Paint* paint, float w, float h) { return false; } virtual bool animatable() { return false; } //true if this loader supports animation. + virtual void sync() {}; //finish immediately if any async update jobs. virtual bool read() = 0; virtual bool close() = 0; + virtual unique_ptr bitmap() { return nullptr; } virtual unique_ptr paint() { return nullptr; } }; diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index edb71e68..d445c72c 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -109,7 +109,8 @@ struct Picture::Impl } if (paint) return RenderUpdateFlag::None; } - } + } else loader->sync(); + if (!surface) { if ((surface = loader->bitmap().release())) { loader->close(); diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 3ca4b1b1..be3a0975 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -377,25 +377,19 @@ bool LottieBuilder::update(LottieComposition* comp, int32_t frameNo) } -unique_ptr LottieBuilder::build(LottieComposition* comp) +void LottieBuilder::build(LottieComposition* comp) { - if (comp->scene) { - TVGERR("LOTTIE", "LottieBuilder::build() is requested multiple times?"); - return unique_ptr(comp->scene); - } + if (comp->scene) return; - auto scene = Scene::gen(); - if (!scene) return nullptr; - comp->scene = scene.get(); + comp->scene = Scene::gen().release(); + if (!comp->scene) return; //TODO: Process repeater objects? - if (!update(comp, 0)) return nullptr; + if (!update(comp, 0)) return; //viewport clip auto clip = Shape::gen(); clip->appendRect(0, 0, static_cast(comp->w), static_cast(comp->h)); - scene->composite(std::move(clip), CompositeMethod::ClipPath); - - return scene; + comp->scene->composite(std::move(clip), CompositeMethod::ClipPath); } \ No newline at end of file diff --git a/src/loaders/lottie/tvgLottieBuilder.h b/src/loaders/lottie/tvgLottieBuilder.h index 03e7d9fa..9e26c080 100644 --- a/src/loaders/lottie/tvgLottieBuilder.h +++ b/src/loaders/lottie/tvgLottieBuilder.h @@ -30,7 +30,7 @@ struct LottieComposition; struct LottieBuilder { bool update(LottieComposition* comp, int32_t frameNo); - unique_ptr build(LottieComposition* comp); + void build(LottieComposition* comp); }; #endif //_TVG_LOTTIE_BUILDER_H \ No newline at end of file diff --git a/src/loaders/lottie/tvgLottieLoader.cpp b/src/loaders/lottie/tvgLottieLoader.cpp index f188369f..561e5d50 100644 --- a/src/loaders/lottie/tvgLottieLoader.cpp +++ b/src/loaders/lottie/tvgLottieLoader.cpp @@ -75,12 +75,16 @@ void LottieLoader::clear() void LottieLoader::run(unsigned tid) { - LottieParser parser(content); - parser.parse(); - - comp = parser.comp; - - root = builder->build(comp); + //update frame + if (comp && comp->scene) { + builder->update(comp, frameNo); + //initial loading + } else { + LottieParser parser(content); + parser.parse(); + comp = parser.comp; + builder->build(comp); + } } @@ -143,6 +147,8 @@ bool LottieLoader::header() p = e; continue; } + //TODO: need a duration time in advance. + //width if (!strncmp(p, "\"w\":", 4)) { p += 4; @@ -251,7 +257,7 @@ bool LottieLoader::read() if (!content || size == 0) return false; //the loading has been already completed in header() - if (root) return true; + if (comp) return true; TaskScheduler::request(this); @@ -273,7 +279,7 @@ unique_ptr LottieLoader::paint() { this->done(); - return std::move(root); + return cast(comp->scene); } @@ -287,7 +293,9 @@ bool LottieLoader::frame(uint32_t frameNo) this->frameNo = frameNo; - return builder->update(comp, frameNo); + TaskScheduler::request(this); + + return true; } @@ -302,8 +310,6 @@ uint32_t LottieLoader::totalFrame() uint32_t LottieLoader::curFrame() { - this->done(); - return frameNo; } @@ -314,4 +320,10 @@ float LottieLoader::duration() if (!comp) return 0; return comp->duration(); +} + + +void LottieLoader::sync() +{ + this->done(); } \ No newline at end of file diff --git a/src/loaders/lottie/tvgLottieLoader.h b/src/loaders/lottie/tvgLottieLoader.h index 152471bd..f529bab4 100644 --- a/src/loaders/lottie/tvgLottieLoader.h +++ b/src/loaders/lottie/tvgLottieLoader.h @@ -41,8 +41,6 @@ public: LottieBuilder* builder = nullptr; LottieComposition* comp = nullptr; - unique_ptr root; //current motion frame - bool copy = false; //"content" is owned by this loader LottieLoader(); @@ -62,6 +60,7 @@ public: uint32_t totalFrame() override; uint32_t curFrame() override; float duration() override; + void sync() override; private: bool header();