lottie: ++scene rendering optimization

Apply LottieRenderPooler to RenderContext propagators.
This commit is contained in:
Hermet Park 2024-07-15 18:50:48 +09:00
parent 9f5a83f067
commit dcf051346c
4 changed files with 69 additions and 37 deletions

View file

@ -65,33 +65,27 @@ struct RenderContext
float roundness = 0.0f; float roundness = 0.0f;
bool fragmenting = false; //render context has been fragmented by filling bool fragmenting = false; //render context has been fragmented by filling
bool reqFragment = false; //requirement to fragment the render context bool reqFragment = false; //requirement to fragment the render context
bool ownPropagator = true; //this rendering context shares the propagator
RenderContext() RenderContext(Shape* propagator)
{ {
propagator = Shape::gen().release(); P(propagator)->reset();
PP(propagator)->ref();
this->propagator = propagator;
} }
~RenderContext() ~RenderContext()
{ {
if (ownPropagator) delete(propagator); PP(propagator)->unref();
free(transform); free(transform);
} }
RenderContext(const RenderContext& rhs, bool mergeable = false) RenderContext(const RenderContext& rhs, Shape* propagator, bool mergeable = false)
{ {
if (mergeable) { if (mergeable) merging = rhs.merging;
this->ownPropagator = false; PP(propagator)->ref();
propagator = rhs.propagator; this->propagator = propagator;
merging = rhs.merging; this->repeaters = rhs.repeaters;
} else { this->roundness = rhs.roundness;
propagator = static_cast<Shape*>(rhs.propagator->duplicate());
}
for (auto repeater = rhs.repeaters.begin(); repeater < rhs.repeaters.end(); ++repeater) {
repeaters.push(*repeater);
}
roundness = rhs.roundness;
} }
}; };
@ -277,7 +271,8 @@ static void _updateGroup(LottieGroup* parent, LottieObject** child, float frameN
if (group->mergeable()) _draw(parent, nullptr, ctx); if (group->mergeable()) _draw(parent, nullptr, ctx);
Inlist<RenderContext> contexts; Inlist<RenderContext> contexts;
contexts.back(new RenderContext(*ctx, group->mergeable())); auto propagator = group->mergeable() ? ctx->propagator : static_cast<Shape*>(PP(ctx->propagator)->duplicate(group->pooling()));
contexts.back(new RenderContext(*ctx, propagator, group->mergeable()));
_updateChildren(group, frameNo, contexts, exps); _updateChildren(group, frameNo, contexts, exps);
@ -303,12 +298,12 @@ static void _updateStroke(LottieStroke* stroke, float frameNo, RenderContext* ct
} }
static bool _fragmented(LottieObject** child, Inlist<RenderContext>& contexts, RenderContext* ctx) static bool _fragmented(LottieGroup* parent, LottieObject** child, Inlist<RenderContext>& contexts, RenderContext* ctx)
{ {
if (!ctx->reqFragment) return false; if (!ctx->reqFragment) return false;
if (ctx->fragmenting) return true; if (ctx->fragmenting) return true;
contexts.back(new RenderContext(*ctx)); contexts.back(new RenderContext(*ctx, static_cast<Shape*>(PP(ctx->propagator)->duplicate(parent->pooling()))));
auto fragment = contexts.tail; auto fragment = contexts.tail;
fragment->begin = child - 1; fragment->begin = child - 1;
ctx->fragmenting = true; ctx->fragmenting = true;
@ -317,9 +312,9 @@ static bool _fragmented(LottieObject** child, Inlist<RenderContext>& contexts, R
} }
static void _updateSolidStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps) static void _updateSolidStroke(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
{ {
if (_fragmented(child, contexts, ctx)) return; if (_fragmented(parent, child, contexts, ctx)) return;
auto stroke = static_cast<LottieSolidStroke*>(*child); auto stroke = static_cast<LottieSolidStroke*>(*child);
@ -330,9 +325,9 @@ static void _updateSolidStroke(TVG_UNUSED LottieGroup* parent, LottieObject** ch
} }
static void _updateGradientStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps) static void _updateGradientStroke(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
{ {
if (_fragmented(child, contexts, ctx)) return; if (_fragmented(parent, child, contexts, ctx)) return;
auto stroke = static_cast<LottieGradientStroke*>(*child); auto stroke = static_cast<LottieGradientStroke*>(*child);
@ -342,9 +337,9 @@ static void _updateGradientStroke(TVG_UNUSED LottieGroup* parent, LottieObject**
} }
static void _updateSolidFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps) static void _updateSolidFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
{ {
if (_fragmented(child, contexts, ctx)) return; if (_fragmented(parent, child, contexts, ctx)) return;
auto fill = static_cast<LottieSolidFill*>(*child); auto fill = static_cast<LottieSolidFill*>(*child);
@ -357,9 +352,9 @@ static void _updateSolidFill(TVG_UNUSED LottieGroup* parent, LottieObject** chil
} }
static void _updateGradientFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps) static void _updateGradientFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
{ {
if (_fragmented(child, contexts, ctx)) return; if (_fragmented(parent, child, contexts, ctx)) return;
auto fill = static_cast<LottieGradientFill*>(*child); auto fill = static_cast<LottieGradientFill*>(*child);
@ -1313,7 +1308,7 @@ static void _updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* lay
default: { default: {
if (!layer->children.empty()) { if (!layer->children.empty()) {
Inlist<RenderContext> contexts; Inlist<RenderContext> contexts;
contexts.back(new RenderContext); contexts.back(new RenderContext(layer->pooling()));
_updateChildren(layer, frameNo, contexts, exps); _updateChildren(layer, frameNo, contexts, exps);
contexts.free(); contexts.free();
} }

View file

@ -351,6 +351,26 @@ bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transforme
} }
void Paint::Impl::reset()
{
if (compData) {
if (P(compData->target)->unref() == 0) delete(compData->target);
free(compData);
compData = nullptr;
}
tvg::identity(&tr.m);
tr.degree = 0.0f;
tr.scale = 1.0f;
tr.overriding = false;
blendMethod = BlendMethod::Normal;
renderFlag = RenderUpdateFlag::None;
ctxFlag = ContextFlag::Invalid;
opacity = 255;
paint->id = 0;
}
/************************************************************************/ /************************************************************************/
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/

View file

@ -50,13 +50,12 @@ namespace tvg
Paint* paint = nullptr; Paint* paint = nullptr;
Composite* compData = nullptr; Composite* compData = nullptr;
RenderMethod* renderer = nullptr; RenderMethod* renderer = nullptr;
BlendMethod blendMethod = BlendMethod::Normal; //uint8_t
struct { struct {
Matrix m; //input matrix Matrix m; //input matrix
Matrix cm; //multipled parents matrix Matrix cm; //multipled parents matrix
float degree = 0.0f; //rotation degree float degree; //rotation degree
float scale = 1.0f; //scale factor float scale; //scale factor
bool overriding = false; //user transform? bool overriding; //user transform?
void update() void update()
{ {
@ -72,14 +71,15 @@ namespace tvg
tvg::rotate(&m, degree); tvg::rotate(&m, degree);
} }
} tr; } tr;
uint8_t renderFlag = RenderUpdateFlag::None; BlendMethod blendMethod;
uint8_t ctxFlag = ContextFlag::Invalid; uint8_t renderFlag;
uint8_t opacity = 255; uint8_t ctxFlag;
uint8_t opacity;
uint8_t refCnt = 0; //reference count uint8_t refCnt = 0; //reference count
Impl(Paint* pnt) : paint(pnt) Impl(Paint* pnt) : paint(pnt)
{ {
identity(&tr.m); reset();
} }
~Impl() ~Impl()
@ -156,6 +156,7 @@ namespace tvg
RenderData update(RenderMethod* renderer, const Matrix& pm, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); RenderData update(RenderMethod* renderer, const Matrix& pm, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false);
bool render(RenderMethod* renderer); bool render(RenderMethod* renderer);
Paint* duplicate(Paint* ret = nullptr); Paint* duplicate(Paint* ret = nullptr);
void reset();
}; };
} }

View file

@ -379,6 +379,22 @@ struct Shape::Impl
return shape; return shape;
} }
void reset()
{
PP(shape)->reset();
rs.path.cmds.clear();
rs.path.pts.clear();
rs.color[3] = 0;
rs.rule = FillRule::Winding;
delete(rs.stroke);
rs.stroke = nullptr;
delete(rs.fill);
rs.fill = nullptr;
}
Iterator* iterator() Iterator* iterator()
{ {
return nullptr; return nullptr;