mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
lottie: ++scene rendering optimization
Apply LottieRenderPooler to RenderContext propagators.
This commit is contained in:
parent
9f5a83f067
commit
dcf051346c
4 changed files with 69 additions and 37 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue