loader lottie: ++optimization.

Aggressive parallelization is implemented to perform updates
on every frame in an asynchronous manner.
This commit is contained in:
Hermet Park 2023-07-28 16:24:26 +09:00 committed by Hermet Park
parent 023b38ad3c
commit 68b8fce501
6 changed files with 35 additions and 27 deletions

View file

@ -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<Surface> bitmap() { return nullptr; }
virtual unique_ptr<Paint> paint() { return nullptr; }
};

View file

@ -109,7 +109,8 @@ struct Picture::Impl
}
if (paint) return RenderUpdateFlag::None;
}
}
} else loader->sync();
if (!surface) {
if ((surface = loader->bitmap().release())) {
loader->close();

View file

@ -377,25 +377,19 @@ bool LottieBuilder::update(LottieComposition* comp, int32_t frameNo)
}
unique_ptr<Scene> LottieBuilder::build(LottieComposition* comp)
void LottieBuilder::build(LottieComposition* comp)
{
if (comp->scene) {
TVGERR("LOTTIE", "LottieBuilder::build() is requested multiple times?");
return unique_ptr<Scene>(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<float>(comp->w), static_cast<float>(comp->h));
scene->composite(std::move(clip), CompositeMethod::ClipPath);
return scene;
comp->scene->composite(std::move(clip), CompositeMethod::ClipPath);
}

View file

@ -30,7 +30,7 @@ struct LottieComposition;
struct LottieBuilder
{
bool update(LottieComposition* comp, int32_t frameNo);
unique_ptr<Scene> build(LottieComposition* comp);
void build(LottieComposition* comp);
};
#endif //_TVG_LOTTIE_BUILDER_H

View file

@ -75,12 +75,16 @@ void LottieLoader::clear()
void LottieLoader::run(unsigned tid)
{
//update frame
if (comp && comp->scene) {
builder->update(comp, frameNo);
//initial loading
} else {
LottieParser parser(content);
parser.parse();
comp = parser.comp;
root = builder->build(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<Paint> LottieLoader::paint()
{
this->done();
return std::move(root);
return cast<Paint>(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;
}
@ -315,3 +321,9 @@ float LottieLoader::duration()
if (!comp) return 0;
return comp->duration();
}
void LottieLoader::sync()
{
this->done();
}

View file

@ -41,8 +41,6 @@ public:
LottieBuilder* builder = nullptr;
LottieComposition* comp = nullptr;
unique_ptr<Scene> 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();