From 126265feb9c8f3b847de957e56ce652d390b7da6 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 10 Apr 2025 14:59:00 +0900 Subject: [PATCH] lottie/expressions: tiny optimization reuse the user callback data by the reference count. --- src/loaders/lottie/tvgLottieExpressions.cpp | 72 ++++++++++++--------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/src/loaders/lottie/tvgLottieExpressions.cpp b/src/loaders/lottie/tvgLottieExpressions.cpp index 20579760..ebe0ae81 100644 --- a/src/loaders/lottie/tvgLottieExpressions.cpp +++ b/src/loaders/lottie/tvgLottieExpressions.cpp @@ -37,6 +37,7 @@ struct ExpContent LottieExpression* exp; LottieObject* obj; float frameNo; + size_t refCnt; }; static jerry_value_t _content(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt); @@ -58,12 +59,20 @@ static const char* EXP_EFFECT= "effect"; static LottieExpressions* exps = nullptr; //singleton instance engine -static ExpContent* _expcontent(LottieExpression* exp, float frameNo, LottieObject* obj) +static ExpContent* _expcontent(LottieExpression* exp, float frameNo, void* obj, size_t refCnt = 1) { auto data = (ExpContent*)malloc(sizeof(ExpContent)); data->exp = exp; data->frameNo = frameNo; - data->obj = obj; + data->obj = (LottieObject*)obj; + data->refCnt = refCnt; + return data; +} + + +static inline ExpContent* _expcontent(ExpContent* data) +{ + ++data->refCnt; return data; } @@ -89,7 +98,9 @@ static jerry_value_t _point2d(const Point& pt) static void contentFree(void *native_p, struct jerry_object_native_info_t *info_p) { - free(native_p); + if (--static_cast(native_p)->refCnt == 0) { + free(native_p); + } } static jerry_object_native_info_t freeCb {contentFree, 0, 0}; @@ -346,9 +357,11 @@ static void _buildLayer(jerry_value_t context, float frameNo, LottieLayer* layer jerry_value_free(toComp); //content("name"), #look for the named property from a layer + auto data = _expcontent(exp, frameNo, layer, 1); + auto content = jerry_function_external(_content); jerry_object_set_sz(context, EXP_CONTENT, content); - jerry_object_set_native_ptr(content, &freeCb, _expcontent(exp, frameNo, layer)); + jerry_object_set_native_ptr(content, &freeCb, data); jerry_value_free(content); } @@ -735,7 +748,7 @@ static jerry_value_t _propertyGroup(const jerry_call_info_t* info, const jerry_v //intermediate group if (level == 1) { auto group = jerry_function_external(_property); - jerry_object_set_native_ptr(group, &freeCb, _expcontent(data->exp, data->frameNo, data->obj)); + jerry_object_set_native_ptr(group, &freeCb, _expcontent(data)); jerry_object_set_sz(group, "", group); return group; } @@ -1088,12 +1101,23 @@ static void _buildProperty(float frameNo, jerry_value_t context, LottieExpressio jerry_object_set_native_ptr(speedAtTime, nullptr, exp); jerry_value_free(speedAtTime); - auto wiggle = jerry_function_external(_wiggle); - jerry_object_set_sz(context, "wiggle", wiggle); - jerry_object_set_native_ptr(wiggle, &freeCb, _expcontent(exp, frameNo, exp->object)); - jerry_value_free(wiggle); + { + auto data = _expcontent(exp, frameNo, exp->object, 2); - //temporalWiggle(freq, amp, octaves=1, amp_mult=.5, t=time) + auto wiggle = jerry_function_external(_wiggle); + jerry_object_set_sz(context, "wiggle", wiggle); + jerry_object_set_native_ptr(wiggle, &freeCb, data); + jerry_value_free(wiggle); + + //temporalWiggle(freq, amp, octaves=1, amp_mult=.5, t=time) + + auto propertyGroup = jerry_function_external(_propertyGroup); + jerry_object_set_native_ptr(propertyGroup, &freeCb, data); + jerry_object_set_sz(context, "propertyGroup", propertyGroup); + jerry_value_free(propertyGroup); + + //propertyIndex + } //smooth(width=.2, samples=5, t=time) auto loopIn = jerry_function_external(_loopIn); @@ -1132,20 +1156,17 @@ static void _buildProperty(float frameNo, jerry_value_t context, LottieExpressio jerry_object_set_sz(context, "numKeys", numKeys); jerry_value_free(numKeys); - auto propertyGroup = jerry_function_external(_propertyGroup); - jerry_object_set_native_ptr(propertyGroup, &freeCb, _expcontent(exp, frameNo, exp->object)); - jerry_object_set_sz(context, "propertyGroup", propertyGroup); - jerry_value_free(propertyGroup); - - //propertyIndex - //name - //content("name"), #look for the named property from a layer - auto content = jerry_function_external(_content); - jerry_object_set_sz(context, EXP_CONTENT, content); - jerry_object_set_native_ptr(content, &freeCb, _expcontent(exp, frameNo, exp->layer)); - jerry_value_free(content); + { + auto data = _expcontent(exp, frameNo, exp->layer, 1); + + //content("name"), #look for the named property from a layer + auto content = jerry_function_external(_content); + jerry_object_set_sz(context, EXP_CONTENT, content); + jerry_object_set_native_ptr(content, &freeCb, data); + jerry_value_free(content); + } //expansions per types if (exp->property->type == LottieProperty::Type::PathSet) _buildPath(context, exp); @@ -1272,11 +1293,6 @@ void LottieExpressions::buildGlobal(LottieExpression* exp) void LottieExpressions::buildComp(jerry_value_t context, float frameNo, LottieLayer* comp, LottieExpression* exp) { - auto data = static_cast(jerry_object_get_native_ptr(context, &freeCb)); - data->exp = exp; - data->frameNo = frameNo; - data->obj = comp; - //layer(index) / layer(name) / layer(otherLayer, reIndex) auto layer = jerry_function_external(_layer); jerry_object_set_sz(context, "layer", layer); @@ -1340,13 +1356,11 @@ jerry_value_t LottieExpressions::buildGlobal() //comp(name) comp = jerry_function_external(_comp); - jerry_object_set_native_ptr(comp, &freeCb, _expcontent(nullptr, 0.0f, nullptr)); jerry_object_set_sz(global, "comp", comp); //footage(name) thisComp = jerry_object(); - jerry_object_set_native_ptr(thisComp, &freeCb, _expcontent(nullptr, 0.0f, nullptr)); jerry_object_set_sz(global, "thisComp", thisComp); thisLayer = jerry_object();