From dcf051346cad56c2d4deecf7bfb21fd9b2dc944f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 15 Jul 2024 18:50:48 +0900 Subject: [PATCH] lottie: ++scene rendering optimization Apply LottieRenderPooler to RenderContext propagators. --- src/loaders/lottie/tvgLottieBuilder.cpp | 53 +++++++++++-------------- src/renderer/tvgPaint.cpp | 20 ++++++++++ src/renderer/tvgPaint.h | 17 ++++---- src/renderer/tvgShape.h | 16 ++++++++ 4 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 8d030ca3..45f0a0ba 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -65,33 +65,27 @@ struct RenderContext float roundness = 0.0f; bool fragmenting = false; //render context has been fragmented by filling 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() { - if (ownPropagator) delete(propagator); + PP(propagator)->unref(); free(transform); } - RenderContext(const RenderContext& rhs, bool mergeable = false) + RenderContext(const RenderContext& rhs, Shape* propagator, bool mergeable = false) { - if (mergeable) { - this->ownPropagator = false; - propagator = rhs.propagator; - merging = rhs.merging; - } else { - propagator = static_cast(rhs.propagator->duplicate()); - } - - for (auto repeater = rhs.repeaters.begin(); repeater < rhs.repeaters.end(); ++repeater) { - repeaters.push(*repeater); - } - roundness = rhs.roundness; + if (mergeable) merging = rhs.merging; + PP(propagator)->ref(); + this->propagator = propagator; + this->repeaters = rhs.repeaters; + this->roundness = rhs.roundness; } }; @@ -277,7 +271,8 @@ static void _updateGroup(LottieGroup* parent, LottieObject** child, float frameN if (group->mergeable()) _draw(parent, nullptr, ctx); Inlist contexts; - contexts.back(new RenderContext(*ctx, group->mergeable())); + auto propagator = group->mergeable() ? ctx->propagator : static_cast(PP(ctx->propagator)->duplicate(group->pooling())); + contexts.back(new RenderContext(*ctx, propagator, group->mergeable())); _updateChildren(group, frameNo, contexts, exps); @@ -303,12 +298,12 @@ static void _updateStroke(LottieStroke* stroke, float frameNo, RenderContext* ct } -static bool _fragmented(LottieObject** child, Inlist& contexts, RenderContext* ctx) +static bool _fragmented(LottieGroup* parent, LottieObject** child, Inlist& contexts, RenderContext* ctx) { if (!ctx->reqFragment) return false; if (ctx->fragmenting) return true; - contexts.back(new RenderContext(*ctx)); + contexts.back(new RenderContext(*ctx, static_cast(PP(ctx->propagator)->duplicate(parent->pooling())))); auto fragment = contexts.tail; fragment->begin = child - 1; ctx->fragmenting = true; @@ -317,9 +312,9 @@ static bool _fragmented(LottieObject** child, Inlist& contexts, R } -static void _updateSolidStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +static void _updateSolidStroke(LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) { - if (_fragmented(child, contexts, ctx)) return; + if (_fragmented(parent, child, contexts, ctx)) return; auto stroke = static_cast(*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& contexts, RenderContext* ctx, LottieExpressions* exps) +static void _updateGradientStroke(LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) { - if (_fragmented(child, contexts, ctx)) return; + if (_fragmented(parent, child, contexts, ctx)) return; auto stroke = static_cast(*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& contexts, RenderContext* ctx, LottieExpressions* exps) +static void _updateSolidFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) { - if (_fragmented(child, contexts, ctx)) return; + if (_fragmented(parent, child, contexts, ctx)) return; auto fill = static_cast(*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& contexts, RenderContext* ctx, LottieExpressions* exps) +static void _updateGradientFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) { - if (_fragmented(child, contexts, ctx)) return; + if (_fragmented(parent, child, contexts, ctx)) return; auto fill = static_cast(*child); @@ -1313,7 +1308,7 @@ static void _updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* lay default: { if (!layer->children.empty()) { Inlist contexts; - contexts.back(new RenderContext); + contexts.back(new RenderContext(layer->pooling())); _updateChildren(layer, frameNo, contexts, exps); contexts.free(); } diff --git a/src/renderer/tvgPaint.cpp b/src/renderer/tvgPaint.cpp index 6537cd0d..37309820 100644 --- a/src/renderer/tvgPaint.cpp +++ b/src/renderer/tvgPaint.cpp @@ -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 */ /************************************************************************/ diff --git a/src/renderer/tvgPaint.h b/src/renderer/tvgPaint.h index 15308c7a..6c3ec6f7 100644 --- a/src/renderer/tvgPaint.h +++ b/src/renderer/tvgPaint.h @@ -50,13 +50,12 @@ namespace tvg Paint* paint = nullptr; Composite* compData = nullptr; RenderMethod* renderer = nullptr; - BlendMethod blendMethod = BlendMethod::Normal; //uint8_t struct { Matrix m; //input matrix Matrix cm; //multipled parents matrix - float degree = 0.0f; //rotation degree - float scale = 1.0f; //scale factor - bool overriding = false; //user transform? + float degree; //rotation degree + float scale; //scale factor + bool overriding; //user transform? void update() { @@ -72,14 +71,15 @@ namespace tvg tvg::rotate(&m, degree); } } tr; - uint8_t renderFlag = RenderUpdateFlag::None; - uint8_t ctxFlag = ContextFlag::Invalid; - uint8_t opacity = 255; + BlendMethod blendMethod; + uint8_t renderFlag; + uint8_t ctxFlag; + uint8_t opacity; uint8_t refCnt = 0; //reference count Impl(Paint* pnt) : paint(pnt) { - identity(&tr.m); + reset(); } ~Impl() @@ -156,6 +156,7 @@ namespace tvg RenderData update(RenderMethod* renderer, const Matrix& pm, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); bool render(RenderMethod* renderer); Paint* duplicate(Paint* ret = nullptr); + void reset(); }; } diff --git a/src/renderer/tvgShape.h b/src/renderer/tvgShape.h index 90779115..13fc3c02 100644 --- a/src/renderer/tvgShape.h +++ b/src/renderer/tvgShape.h @@ -379,6 +379,22 @@ struct Shape::Impl 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() { return nullptr;