lottie: ++optimization with a caching effect.

reuse clippers if they are available.

Binary: +132
This commit is contained in:
Hermet Park 2023-10-25 18:14:38 +09:00
parent f223f2f6ac
commit fe259d0414
4 changed files with 38 additions and 25 deletions

View file

@ -815,23 +815,28 @@ static void _updatePrecomp(LottieLayer* precomp, float frameNo, bool caching)
//clip the layer viewport //clip the layer viewport
if (precomp->w > 0 && precomp->h > 0) { 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<float>(precomp->w), static_cast<float>(precomp->h));
}
auto clipper = precomp->cache.clipper;
clipper->transform(precomp->cache.matrix);
//TODO: remove the intermediate scene.... //TODO: remove the intermediate scene....
auto cscene = Scene::gen(); auto cscene = Scene::gen();
auto clipper = Shape::gen(); cscene->composite(cast<Shape>(clipper), CompositeMethod::ClipPath);
clipper->appendRect(0, 0, static_cast<float>(precomp->w), static_cast<float>(precomp->h));
clipper->transform(precomp->cache.matrix);
cscene->composite(std::move(clipper), CompositeMethod::ClipPath);
cscene->push(cast<Scene>(precomp->scene)); cscene->push(cast<Scene>(precomp->scene));
precomp->scene = cscene.release(); precomp->scene = cscene.release();
} }
} }
static void _updateSolid(LottieLayer* layer, float frameNo) static void _updateSolid(LottieLayer* layer)
{ {
auto shape = Shape::gen(); auto shape = Shape::gen();
shape->appendRect(0, 0, static_cast<float>(layer->w), static_cast<float>(layer->h)); shape->appendRect(0, 0, static_cast<float>(layer->w), static_cast<float>(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)); layer->scene->push(std::move(shape));
} }
@ -946,7 +951,7 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, b
break; break;
} }
case LottieLayer::Solid: { case LottieLayer::Solid: {
_updateSolid(layer, frameNo); _updateSolid(layer);
break; break;
} }
default: { default: {

View file

@ -316,7 +316,8 @@ unique_ptr<Paint> LottieLoader::paint()
bool LottieLoader::frame(float no) 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(); this->done();

View file

@ -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() void LottieLayer::prepare()
{ {
if (transform) statical &= transform->statical; if (transform) statical &= transform->statical;

View file

@ -485,22 +485,7 @@ struct LottieLayer : LottieGroup
{ {
enum Type : uint8_t {Precomp = 0, Solid, Image, Null, Shape, Text}; enum Type : uint8_t {Precomp = 0, Solid, Image, Null, Shape, Text};
~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);
delete(cache.scene);
}
uint8_t opacity(float frameNo) uint8_t opacity(float frameNo)
{ {
@ -539,7 +524,10 @@ struct LottieLayer : LottieGroup
float frameNo = -1.0f; float frameNo = -1.0f;
Matrix matrix; Matrix matrix;
uint8_t opacity; uint8_t opacity;
Paint* scene = nullptr; //tvg statc render ddata
//tvg render data
Paint* scene = nullptr;
tvg::Shape* clipper = nullptr;
} cache; } cache;
Type type = Null; Type type = Null;