From: subhransu mohanty Date: Thu, 6 Sep 2018 11:18:40 +0000 (+0900) Subject: lottie: refactor lottie interface X-Git-Tag: submit/tizen/20180917.042405~24 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0f5edac6d1595e0fecd8d48bb7d2e5353fe9121f;p=platform%2Fcore%2Fuifw%2Flottie-player.git lottie: refactor lottie interface 1. rename namespace player--> animation both cpp and c interface 2. added factory function to create animation object. 3. added render api to c interface. Change-Id: I31c99a66678b20a0c743c564d399172f4182b0d1 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index ceed7e9..3fa20cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig) #install header -install(FILES inc/lotplayer.h inc/lotcommon.h src/binding/c/lotplayer_capi.h DESTINATION include) +install(FILES inc/lottieanimation.h inc/lottieanimation_capi.h inc/lottiecommon.h DESTINATION include) #install lib install( TARGETS lottie-player EXPORT lottie-player-targets diff --git a/example/lottieview.cpp b/example/lottieview.cpp index cb8ce89..5fc234d 100644 --- a/example/lottieview.cpp +++ b/example/lottieview.cpp @@ -1,6 +1,6 @@ #include"lottieview.h" -using namespace lottieplayer; +using namespace lottie; static Eina_Bool animator(void *data , double pos) @@ -119,6 +119,7 @@ void LottieView::initializeBufferObject(Evas *evas) LottieView::LottieView(Evas *evas, bool renderMode, bool asyncRender):mVg(nullptr), mImage(nullptr) { + mPlayer = nullptr; mPalying = false; mReverse = false; mRepeatCount = 0; @@ -127,7 +128,6 @@ LottieView::LottieView(Evas *evas, bool renderMode, bool asyncRender):mVg(nullpt mSpeed = 1; mEvas = evas; - mPlayer = new LOTPlayer(); mRenderMode = renderMode; mAsyncRender = asyncRender; @@ -142,7 +142,6 @@ LottieView::~LottieView() if (mAnimator) ecore_animator_del(mAnimator); if (mVg) evas_object_del(mVg); if (mImage) evas_object_del(mImage); - delete mPlayer; } Evas_Object *LottieView::getImage() { @@ -174,35 +173,40 @@ void LottieView::hide() void LottieView::seek(float pos) { + if (!mPlayer) return; + if (mPalying && mReverse) pos = 1.0 - pos; mPos = pos; + // check if the pos maps to the current frame + if (mCurFrame == mPlayer->frameAtPos(mPos)) return; + + mCurFrame = mPlayer->frameAtPos(mPos); + if (mRenderMode) { - LOTBuffer buf; - evas_object_image_size_get(mImage, &buf.width, &buf.height); + int width , height; + evas_object_image_size_get(mImage, &width, &height); if (mAsyncRender) { if (mRenderTask.valid()) return; mDirty = true; - buf.buffer = (uint32_t *)evas_object_image_data_get(mImage, EINA_TRUE); - buf.bytesPerLine = evas_object_image_stride_get(mImage); - mRenderTask = mPlayer->render(mPos, buf); - mBuffer = buf; + auto buffer = (uint32_t *)evas_object_image_data_get(mImage, EINA_TRUE); + size_t bytesperline = evas_object_image_stride_get(mImage); + lottie::Surface surface(buffer, width, height, bytesperline); + mRenderTask = mPlayer->render(mCurFrame, surface); // to force a redraw - evas_object_image_data_update_add(mImage, 0 , 0, buf.width, buf.height); + evas_object_image_data_update_add(mImage, 0 , 0, surface.width(), surface.height()); } else { - buf.buffer = (uint32_t *)evas_object_image_data_get(mImage, EINA_TRUE); - buf.bytesPerLine = evas_object_image_stride_get(mImage); - bool changed = mPlayer->renderSync(pos, buf); - evas_object_image_data_set(mImage, buf.buffer); - // if the buffer is updated notify the image object - if (changed) { - evas_object_image_data_update_add(mImage, 0 , 0, buf.width, buf.height); - } + auto buffer = (uint32_t *)evas_object_image_data_get(mImage, EINA_TRUE); + size_t bytesperline = evas_object_image_stride_get(mImage); + lottie::Surface surface(buffer, width, height, bytesperline); + mPlayer->renderSync(mCurFrame, surface); + evas_object_image_data_set(mImage, surface.buffer()); + evas_object_image_data_update_add(mImage, 0 , 0, surface.width(), surface.height()); } } else { - const std::vector &renderList = mPlayer->renderList(pos); + const std::vector &renderList = mPlayer->renderList(mCurFrame, mw, mh); update(renderList); } } @@ -214,50 +218,49 @@ float LottieView::getPos() void LottieView::render() { + if (!mPlayer) return; + if (!mDirty) return; mDirty = false; if (mRenderMode) { - if (!mBuffer.buffer) return; - bool changed = false; - if (mRenderTask.valid()) { - changed = mRenderTask.get(); - } - evas_object_image_data_set(mImage, mBuffer.buffer); - // if the buffer is updated notify the image object - if (changed) { - evas_object_image_data_update_add(mImage, 0 , 0, mBuffer.width, mBuffer.height); - } - mBuffer.buffer = nullptr; - } else { - const std::vector &renderList = mPlayer->renderList(mPos); - update(renderList); + if (!mRenderTask.valid()) return; + auto surface = mRenderTask.get(); + evas_object_image_data_set(mImage, surface.buffer()); + evas_object_image_data_update_add(mImage, 0 , 0, surface.width(), surface.height()); } } void LottieView::setFilePath(const char *filePath) { - mPlayer->setFilePath(filePath); - mFrameRate = mPlayer->frameRate(); - mTotalFrame = mPlayer->totalFrame(); + if (mPlayer = Animation::loadFromFile(filePath)) { + mFrameRate = mPlayer->frameRate(); + mTotalFrame = mPlayer->totalFrame(); + } else { + printf("load failed file %s\n", filePath); + } } void LottieView::loadFromData(const char *jsonData, const char *key) { - mPlayer->loadFromData(jsonData, key); - mFrameRate = mPlayer->frameRate(); - mTotalFrame = mPlayer->totalFrame(); + if (mPlayer = Animation::loadFromData(jsonData, key)) { + mFrameRate = mPlayer->frameRate(); + mTotalFrame = mPlayer->totalFrame(); + } else { + printf("load failed from data key : %s\n", key); + } } void LottieView::setSize(int w, int h) { + mw = w; mh = h; + if (mRenderMode) { evas_object_resize(mImage, w, h); evas_object_image_size_set(mImage, w, h); } else { evas_object_resize(mVg, w, h); } - mPlayer->setSize(w, h); } void LottieView::setPos(int x, int y) { @@ -290,9 +293,11 @@ void LottieView::setRepeatMode(LottieView::RepeatMode mode) void LottieView::play() { + if (!mPlayer) return; + mStartPos = mPos; if (mAnimator) ecore_animator_del(mAnimator); - mAnimator = ecore_animator_timeline_add(mPlayer->playTime()/mSpeed, animator, this); + mAnimator = ecore_animator_timeline_add(mPlayer->duration()/mSpeed, animator, this); mReverse = false; mCurCount = mRepeatCount; mPalying = true; @@ -314,6 +319,8 @@ void LottieView::stop() void LottieView::restart() { + if (!mPlayer) return; + mCurCount--; if (mLoop || mRepeatCount) { if (mRepeatMode == LottieView::RepeatMode::Reverse) @@ -323,6 +330,6 @@ void LottieView::restart() mStartPos = 0; if (mAnimator) ecore_animator_del(mAnimator); - mAnimator = ecore_animator_timeline_add(mPlayer->playTime()/mSpeed, animator, this); + mAnimator = ecore_animator_timeline_add(mPlayer->duration()/mSpeed, animator, this); } } diff --git a/example/lottieview.h b/example/lottieview.h index 30098ff..08e98cf 100644 --- a/example/lottieview.h +++ b/example/lottieview.h @@ -14,7 +14,8 @@ #include #include #include -#include"lotplayer.h" +#include "lottieanimation.h" +#include "lottieanimation_capi.h" #include class LottieView { @@ -59,7 +60,8 @@ public: Evas_Object *mVg; int mRepeatCount; LottieView::RepeatMode mRepeatMode; - lottieplayer::LOTPlayer *mPlayer; + std::unique_ptr mPlayer; + size_t mCurFrame{UINT_MAX}; Ecore_Animator *mAnimator{nullptr}; bool mLoop; int mCurCount; @@ -74,7 +76,15 @@ public: float mPos; float mFrameRate; long mTotalFrame; - std::future mRenderTask; - LOTBuffer mBuffer; + std::future mRenderTask; }; + +class LottieViewCApi +{ +public: +private: + Evas *mEvas; + Lottie_Animation *mAnimation; +}; + #endif //LOTTIEVIEW_H diff --git a/inc/lotcommon.h b/inc/lotcommon.h deleted file mode 100644 index aa24423..0000000 --- a/inc/lotcommon.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef _LOT_COMMON_H_ -#define _LOT_COMMON_H_ - -#ifdef _WIN32 -#ifdef LOT_BUILD -#ifdef DLL_EXPORT -#define LOT_EXPORT __declspec(dllexport) -#else -#define LOT_EXPORT -#endif -#else -#define LOT_EXPORT __declspec(dllimport) -#endif -#else -#ifdef __GNUC__ -#if __GNUC__ >= 4 -#define LOT_EXPORT __attribute__((visibility("default"))) -#else -#define LOT_EXPORT -#endif -#else -#define LOT_EXPORT -#endif -#endif - - -/** - * @brief Enumeration for Lottie Player error code. - */ -typedef enum -{ - //TODO: Coding convention?? - LOT_PLAYER_ERROR_NONE = 0, - LOT_PLAYER_ERROR_NOT_PERMITTED, - LOT_PLAYER_ERROR_OUT_OF_MEMORY, - LOT_PLAYER_ERROR_INVALID_PARAMETER, - LOT_PLAYER_ERROR_RESULT_OUT_OF_RANGE, - LOT_PLAYER_ERROR_ALREADY_IN_PROGRESS, - LOT_PLAYER_ERROR_UNKNOWN -} LOTErrorType; - -typedef enum -{ - BrushSolid = 0, - BrushGradient -} LOTBrushType; - -typedef enum -{ - FillEvenOdd = 0, - FillWinding -} LOTFillRule; - -typedef enum -{ - JoinMiter = 0, - JoinBevel, - JoinRound -} LOTJoinStyle; - -typedef enum -{ - CapFlat = 0, - CapSquare, - CapRound -} LOTCapStyle; - -typedef enum -{ - GradientLinear = 0, - GradientRadial -} LOTGradientType; - -typedef struct LOTNode { - -#define ChangeFlagNone 0x0000 -#define ChangeFlagPath 0x0001 -#define ChangeFlagPaint 0x0010 -#define ChangeFlagAll (ChangeFlagPath & ChangeFlagPaint) - - struct { - const float *ptPtr; - int ptCount; - const char* elmPtr; - int elmCount; - } mPath; - - struct { - unsigned char r, g, b, a; - } mColor; - - struct { - bool enable; - int width; - LOTCapStyle cap; - LOTJoinStyle join; - int meterLimit; - float* dashArray; - int dashArraySize; - } mStroke; - - struct { - LOTGradientType type; - struct { - float x, y; - } start, end, center, focal; - float cradius; - float fradius; - } mGradient; - - int mFlag; - LOTBrushType mType; - LOTFillRule mFillRule; -} LOTNode; - -typedef struct LOTBuffer { - uint32_t *buffer; - int width; - int height; - int bytesPerLine; - bool clear; -} LOTBuffer; - -#endif // _LOT_COMMON_H_ diff --git a/inc/lotplayer.h b/inc/lotplayer.h deleted file mode 100644 index a225478..0000000 --- a/inc/lotplayer.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _LOT_PLAYER_H_ -#define _LOT_PLAYER_H_ - -#include -#include - -#include "lotcommon.h" - -//TODO: Hide this. -class LOTPlayerPrivate; -#define _LOT_PLAYER_DECLARE_PRIVATE(A) \ - class A##Private *d; - -namespace lottieplayer { - -class LOT_EXPORT LOTPlayer { -public: - ~LOTPlayer(); - LOTPlayer(); - - bool loadFromData(const char *jsonData, const char *key); - - bool setFilePath(const char *filePath); - - float playTime() const; - - float pos() const; - - float frameRate() const; - - long totalFrame() const; - - const std::vector &renderList(float pos) const; - - // TODO: Consider correct position... - void setSize(int width, int height); - void size(int &width, int &height) const; - std::future render(float pos, LOTBuffer buffer, bool forceRender = false); - bool renderSync(float pos, LOTBuffer buffer, bool forceRender = false); - -private: - _LOT_PLAYER_DECLARE_PRIVATE(LOTPlayer) -}; - -} // namespace lotplayer - -#endif // _LOT_PLAYER_H_ diff --git a/inc/lottieanimation.h b/inc/lottieanimation.h new file mode 100644 index 0000000..ce163b9 --- /dev/null +++ b/inc/lottieanimation.h @@ -0,0 +1,78 @@ +#ifndef _LOTTIE_ANIMATION_H_ +#define _LOTTIE_ANIMATION_H_ + +#include +#include +#include + +#ifdef _WIN32 +#ifdef LOT_BUILD +#ifdef DLL_EXPORT +#define LOT_EXPORT __declspec(dllexport) +#else +#define LOT_EXPORT +#endif +#else +#define LOT_EXPORT __declspec(dllimport) +#endif +#else +#ifdef __GNUC__ +#if __GNUC__ >= 4 +#define LOT_EXPORT __attribute__((visibility("default"))) +#else +#define LOT_EXPORT +#endif +#else +#define LOT_EXPORT +#endif +#endif + +class AnimationImpl; +class LOTNode; + +namespace lottie { + +class LOT_EXPORT Surface { +public: + Surface() = default; + Surface(uint32_t *buffer, size_t width, size_t height, size_t bytesPerLine); + size_t width() const {return mWidth;} + size_t height() const {return mHeight;} + size_t bytesPerLine() const {return mBytesPerLine;} + uint32_t *buffer() const {return mBuffer;} + +private: + uint32_t *mBuffer; + size_t mWidth; + size_t mHeight; + size_t mBytesPerLine; +}; + +class LOT_EXPORT Animation { +public: + + static std::unique_ptr + loadFromFile(const std::string &path); + + static std::unique_ptr + loadFromData(const char *jsonData, const char *key); + + double frameRate() const; + size_t totalFrame() const; + void size(size_t &width, size_t &height) const; + double duration() const; + size_t frameAtPos(double pos); + + std::future render(size_t frameNo, Surface surface); + void renderSync(size_t frameNo, Surface surface); + + ~Animation(); + Animation(); + + const std::vector &renderList(size_t frameNo, size_t width, size_t height) const; +private: + std::unique_ptr d; +}; +} // namespace lotplayer + +#endif // _LOTTIE_ANIMATION_H_ diff --git a/inc/lottieanimation_capi.h b/inc/lottieanimation_capi.h new file mode 100644 index 0000000..2b032a7 --- /dev/null +++ b/inc/lottieanimation_capi.h @@ -0,0 +1,73 @@ +#ifndef _LOTPLAYER_CAPI_H_ +#define _LOTPLAYER_CAPI_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Lottie_Animation_S Lottie_Animation; + +LOT_EXPORT Lottie_Animation *lottie_animation_from_file(const char *file); +LOT_EXPORT Lottie_Animation *lottie_animation_from_data(const char *data, const char *key); +LOT_EXPORT void lottie_animation_destroy(Lottie_Animation *animation); +LOT_EXPORT void lottie_animation_get_size(const Lottie_Animation *animation, size_t *w, size_t *h); +LOT_EXPORT double lottie_animation_get_duration(const Lottie_Animation *animation); +LOT_EXPORT size_t lottie_animation_get_totalframe(const Lottie_Animation *animation); +LOT_EXPORT double lottie_animation_get_framerate(const Lottie_Animation *animation); + + +/* + * Request to update the content of the frame $frame_number in to Animation object. + * frame_number, the content of the animation in that frame number + * width , width of the viewbox + * height , height of the viewbox + * + * PS : user must call lottie_animation_get_node_count and lottie_animation_get_node + * to get the renderlist. + */ +LOT_EXPORT size_t lottie_animation_prepare_frame(Lottie_Animation *animation, + size_t frameNo, + size_t w, size_t h); +LOT_EXPORT size_t lottie_animation_get_node_count(const Lottie_Animation *animation); +LOT_EXPORT const LOTNode* lottie_animation_get_node(Lottie_Animation *animation, size_t idx); + +/* + * Request to render the content of the frame $frame_number to buffer $buffer asynchronously. + * frame_number, the frame number needs to be rendered. + * buffer , surface buffer use for rendering + * width , width of the surface + * height , height of the surface + * bytes_per_line, stride of the surface in bytes. + * + * PS : user must call lottie_animation_render_flush to make sure render is finished. + */ +LOT_EXPORT void +lottie_animation_render_async(Lottie_Animation *animation, + size_t frame_number, + uint32_t *buffer, + size_t width, + size_t height, + size_t bytes_per_line); + + +/* + * Request to finish the current asyn renderer job for this animation object. + * if render is finished then this call returns immidiately + * if not it waits till render job finish and then return. + * user must use lottie_animation_render_async and lottie_animation_render_flush + * together to get the benefit of async rendering. + */ +LOT_EXPORT void +lottie_animation_render_flush(Lottie_Animation *animation); + +#ifdef __cplusplus +} +#endif + +#endif //_LOTPLAYER_CAPI_H_ + diff --git a/inc/lottiecommon.h b/inc/lottiecommon.h new file mode 100644 index 0000000..090b4c2 --- /dev/null +++ b/inc/lottiecommon.h @@ -0,0 +1,117 @@ +#ifndef _LOTTIE_COMMON_H_ +#define _LOTTIE_COMMON_H_ + +#ifdef _WIN32 +#ifdef LOT_BUILD +#ifdef DLL_EXPORT +#define LOT_EXPORT __declspec(dllexport) +#else +#define LOT_EXPORT +#endif +#else +#define LOT_EXPORT __declspec(dllimport) +#endif +#else +#ifdef __GNUC__ +#if __GNUC__ >= 4 +#define LOT_EXPORT __attribute__((visibility("default"))) +#else +#define LOT_EXPORT +#endif +#else +#define LOT_EXPORT +#endif +#endif + + +/** + * @brief Enumeration for Lottie Player error code. + */ +typedef enum +{ + //TODO: Coding convention?? + LOT_PLAYER_ERROR_NONE = 0, + LOT_PLAYER_ERROR_NOT_PERMITTED, + LOT_PLAYER_ERROR_OUT_OF_MEMORY, + LOT_PLAYER_ERROR_INVALID_PARAMETER, + LOT_PLAYER_ERROR_RESULT_OUT_OF_RANGE, + LOT_PLAYER_ERROR_ALREADY_IN_PROGRESS, + LOT_PLAYER_ERROR_UNKNOWN +} LOTErrorType; + +typedef enum +{ + BrushSolid = 0, + BrushGradient +} LOTBrushType; + +typedef enum +{ + FillEvenOdd = 0, + FillWinding +} LOTFillRule; + +typedef enum +{ + JoinMiter = 0, + JoinBevel, + JoinRound +} LOTJoinStyle; + +typedef enum +{ + CapFlat = 0, + CapSquare, + CapRound +} LOTCapStyle; + +typedef enum +{ + GradientLinear = 0, + GradientRadial +} LOTGradientType; + +typedef struct LOTNode { + +#define ChangeFlagNone 0x0000 +#define ChangeFlagPath 0x0001 +#define ChangeFlagPaint 0x0010 +#define ChangeFlagAll (ChangeFlagPath & ChangeFlagPaint) + + struct { + const float *ptPtr; + int ptCount; + const char* elmPtr; + int elmCount; + } mPath; + + struct { + unsigned char r, g, b, a; + } mColor; + + struct { + bool enable; + int width; + LOTCapStyle cap; + LOTJoinStyle join; + int meterLimit; + float* dashArray; + int dashArraySize; + } mStroke; + + struct { + LOTGradientType type; + struct { + float x, y; + } start, end, center, focal; + float cradius; + float fradius; + } mGradient; + + int mFlag; + LOTBrushType mType; + LOTFillRule mFillRule; +} LOTNode; + + +#endif // _LOTTIE_COMMON_H_ diff --git a/inc/meson.build b/inc/meson.build index aa65f1f..332029f 100644 --- a/inc/meson.build +++ b/inc/meson.build @@ -1 +1,3 @@ -install_headers(['lotplayer.h', 'lotcommon.h']) +install_headers(['lottieanimation.h', + 'lotcommon.h', + 'lottieanimation_capi.h']) diff --git a/src/binding/c/lotplayer_capi.h b/src/binding/c/lotplayer_capi.h deleted file mode 100644 index 5c374d1..0000000 --- a/src/binding/c/lotplayer_capi.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _LOTPLAYER_CAPI_H_ -#define _LOTPLAYER_CAPI_H_ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct lotplayer_s LOTPlayer; - -LOT_EXPORT LOTPlayer *lotplayer_create(void); -LOT_EXPORT int lotplayer_destroy(LOTPlayer *player); -LOT_EXPORT int lotplayer_set_file(LOTPlayer *player, const char *file); -LOT_EXPORT int lotplayer_set_data(LOTPlayer *player, const char *data, const char *key); -LOT_EXPORT int lotplayer_set_size(LOTPlayer *player, int w, int h); -LOT_EXPORT int lotplayer_get_size(const LOTPlayer *player, int* w, int* h); -LOT_EXPORT float lotplayer_get_playtime(const LOTPlayer *player); -LOT_EXPORT long lotplayer_get_totalframe(const LOTPlayer *player); -LOT_EXPORT float lotplayer_get_framerate(const LOTPlayer *player); -LOT_EXPORT float lotplayer_get_pos(const LOTPlayer *player); -LOT_EXPORT size_t lotplayer_get_node_count(const LOTPlayer *player, float pos); -LOT_EXPORT const LOTNode* lotplayer_get_node(LOTPlayer *player, float pos, size_t idx); - -#ifdef __cplusplus -} -#endif - -#endif //_LOTPLAYER_CAPI_H_ - diff --git a/src/binding/c/lottieanimation_c.cpp b/src/binding/c/lottieanimation_c.cpp new file mode 100644 index 0000000..fa2f9f4 --- /dev/null +++ b/src/binding/c/lottieanimation_c.cpp @@ -0,0 +1,123 @@ +#include "lottieanimation.h" +#include "vdebug.h" + +using namespace lottie; + +extern "C" { + +struct Lottie_Animation_S +{ + std::unique_ptr mAnimation; + size_t mCurFrame; + LOTNode **mNodeArray; + size_t mArraySize{0}; + std::future mRenderTask; +}; + +LOT_EXPORT Lottie_Animation_S *lottie_animation_from_file(const char *file) +{ + if (auto animation = Animation::loadFromFile(file) ) { + Lottie_Animation_S *handle = new Lottie_Animation_S(); + handle->mAnimation = std::move(animation); + return handle; + } else { + return nullptr; + } +} + +Lottie_Animation_S *lottie_animation_from_data(const char *data, const char *key) +{ + if (auto animation = Animation::loadFromData(data, key) ) { + Lottie_Animation_S *handle = new Lottie_Animation_S(); + handle->mAnimation = std::move(animation); + return handle; + } else { + return nullptr; + } +} + +LOT_EXPORT void lottie_animation_destroy(Lottie_Animation_S *animation) +{ + if (animation) + delete animation; +} + +LOT_EXPORT void lottie_animation_get_size(const Lottie_Animation_S *animation, size_t *w, size_t *h) +{ + if (!animation) return; + + animation->mAnimation->size(*w, *h); +} + +LOT_EXPORT double lottie_animation_get_duration(const Lottie_Animation_S *animation) +{ + if (!animation) return 0; + + return animation->mAnimation->duration(); +} + +LOT_EXPORT size_t lottie_animation_get_totalframe(const Lottie_Animation_S *animation) +{ + if (!animation) return 0; + + return animation->mAnimation->totalFrame(); +} + + +LOT_EXPORT double lottie_animation_get_framerate(const Lottie_Animation_S *animation) +{ + if (!animation) return 0; + + return animation->mAnimation->frameRate(); +} + +LOT_EXPORT void lottie_animation_prepare_frame(Lottie_Animation_S *animation, size_t frameNo, size_t w, size_t h) +{ + if (!animation) return; + + auto list = animation->mAnimation->renderList(frameNo, w, h); + animation->mNodeArray = list.data(); + animation->mArraySize = list.size(); +} + +LOT_EXPORT size_t lottie_animation_get_node_count(const Lottie_Animation_S *animation) +{ + if (!animation) return 0; + + return animation->mArraySize; +} + +LOT_EXPORT const LOTNode* lottie_animation_get_node(const Lottie_Animation_S *animation, size_t idx) +{ + if (!animation) return nullptr; + + if (idx >= animation->mArraySize) return nullptr; + + return animation->mNodeArray[idx]; +} + +LOT_EXPORT void +lottie_animation_render_async(Lottie_Animation_S *animation, + size_t frame_number, + uint32_t *buffer, + size_t width, + size_t height, + size_t bytes_per_line) +{ + if (!animation) return; + + lottie::Surface surface(buffer, width, height, bytes_per_line); + animation->mRenderTask = animation->mAnimation->render(frame_number, surface); +} + +LOT_EXPORT void +lottie_animation_render_flush(Lottie_Animation_S *animation) +{ + if (!animation) return; + + if (animation->mRenderTask.valid()) { + animation->mRenderTask.get(); + } +} + +} diff --git a/src/binding/c/lottieplayer_c.cpp b/src/binding/c/lottieplayer_c.cpp deleted file mode 100644 index 96ffeb2..0000000 --- a/src/binding/c/lottieplayer_c.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include "vdebug.h" - -using namespace lottieplayer; - -extern "C" { - -LOT_EXPORT LOTPlayer *lotplayer_create(void) -{ - LOTPlayer* p = new LOTPlayer(); - if (!p) { - vCritical << "Failed to initialize lotplayer"; - } - return p; -} - -LOT_EXPORT int lotplayer_destroy(LOTPlayer *player) -{ - if (!player) return LOT_PLAYER_ERROR_INVALID_PARAMETER; - delete(player); - - return LOT_PLAYER_ERROR_NONE; -} - -LOT_EXPORT int lotplayer_set_data(LOTPlayer *player, const char *data, const char *key) -{ - if (!player) return LOT_PLAYER_ERROR_INVALID_PARAMETER; - bool ret = player->loadFromData(data, key); - - if (!ret) return -1; - - return LOT_PLAYER_ERROR_NONE; -} - -LOT_EXPORT int lotplayer_set_file(LOTPlayer *player, const char *file) -{ - if (!player) return LOT_PLAYER_ERROR_INVALID_PARAMETER; - bool ret = player->setFilePath(file); - - if (!ret) return -1; - - return LOT_PLAYER_ERROR_NONE; -} - -LOT_EXPORT int lotplayer_set_size(LOTPlayer *player, int w, int h) -{ - if (!player) return LOT_PLAYER_ERROR_INVALID_PARAMETER; - - player->setSize(w, h); - - return LOT_PLAYER_ERROR_NONE; -} - -LOT_EXPORT int lotplayer_get_size(const LOTPlayer *player, int* w, int* h) -{ - if (!player) return LOT_PLAYER_ERROR_INVALID_PARAMETER; - - player->size(*w, *h); - - return LOT_PLAYER_ERROR_NONE; -} - -LOT_EXPORT float lotplayer_get_pos(const LOTPlayer *player) -{ - if (!player) { - vWarning << "Invalid parameter player = nullptr"; - return -1.0f; - } - - return player->pos(); -} - -LOT_EXPORT size_t lotplayer_get_node_count(const LOTPlayer *player, float pos) -{ - if (!player) return LOT_PLAYER_ERROR_NONE; - - return player->renderList(pos).size(); -} - -LOT_EXPORT float lotplayer_get_playtime(const LOTPlayer *player) -{ - if (!player) { - vWarning << "Invalid parameter player = nullptr"; - return 0.0f; - } - - return player->playTime(); -} - -LOT_EXPORT long lotplayer_get_totalframe(const LOTPlayer *player) -{ - if (!player) { - vWarning << "Invalid parameter player = nullptr"; - return 0; - } - - return player->totalFrame(); -} - -LOT_EXPORT float lotplayer_get_framerate(const LOTPlayer *player) -{ - if (!player) { - vWarning << "Invalid parameter player = nullptr"; - return 0.0f; - } - - return player->frameRate(); -} - -LOT_EXPORT const LOTNode* lotplayer_get_node(LOTPlayer *player, float pos, size_t idx) -{ - if (!player) { - vWarning << "Invalid parameter player = nullptr"; - return nullptr; - } - - if (idx >= player->renderList(pos).size()) { - vWarning << "Invalid parameter idx? (0 ~ " << player->renderList(pos).size() << "), given idx = " << idx; - return nullptr; - } - - return player->renderList(pos)[idx]; -} - -} diff --git a/src/binding/c/meson.build b/src/binding/c/meson.build index 646983b..3c297fc 100644 --- a/src/binding/c/meson.build +++ b/src/binding/c/meson.build @@ -1,6 +1,4 @@ -install_headers(['lotplayer_capi.h']) - -source_file = files('lottieplayer_c.cpp') +source_file = files('lottieanimation_c.cpp') binding_c_dep = declare_dependency( include_directories : include_directories('.'), diff --git a/src/lottie/CMakeLists.txt b/src/lottie/CMakeLists.txt index d6c006d..4fb944a 100644 --- a/src/lottie/CMakeLists.txt +++ b/src/lottie/CMakeLists.txt @@ -5,10 +5,10 @@ target_sources(lottie-player "${CMAKE_CURRENT_LIST_DIR}/lottieloader.cpp" "${CMAKE_CURRENT_LIST_DIR}/lottiemodel.cpp" "${CMAKE_CURRENT_LIST_DIR}/lottieparser.cpp" - "${CMAKE_CURRENT_LIST_DIR}/lottieplayer.cpp" + "${CMAKE_CURRENT_LIST_DIR}/lottieanimation.cpp" ) target_include_directories(lottie-player PRIVATE "${CMAKE_CURRENT_LIST_DIR}" - ) \ No newline at end of file + ) diff --git a/src/lottie/lottieanimation.cpp b/src/lottie/lottieanimation.cpp new file mode 100644 index 0000000..6d900ed --- /dev/null +++ b/src/lottie/lottieanimation.cpp @@ -0,0 +1,294 @@ +#include "lottieanimation.h" + +#include "lottieitem.h" +#include "lottieloader.h" +#include "lottiemodel.h" + +#include + +using namespace lottie; + +class AnimationImpl { + +public: + void init(const std::shared_ptr &model); + bool update(size_t frameNo, const VSize &size); + VSize size() const; + double duration() const; + double frameRate() const; + size_t totalFrame() const; + size_t frameAtPos(double pos) const; + const std::vector &renderList(size_t frameNo, const VSize &size); + Surface render(size_t frameNo, const Surface &surface); + +private: + std::string mFilePath; + std::shared_ptr mModel; + std::unique_ptr mCompItem; + std::atomic mRenderInProgress; +}; + +double AnimationImpl::frameRate() const +{ + return mModel->frameRate(); +} + +size_t AnimationImpl::totalFrame() const +{ + return mModel->frameDuration(); +} + +size_t AnimationImpl::frameAtPos(double pos) const +{ + if (pos < 0) pos = 0; + if (pos > 1) pos = 1; + + if (mModel->isStatic()) return 0; + + return mModel->startFrame() + pos * mModel->frameDuration(); +} + +VSize AnimationImpl::size() const +{ + return mCompItem->size(); +} + +const std::vector &AnimationImpl::renderList(size_t frameNo, const VSize &size) +{ + update(frameNo, size); + return mCompItem->renderList(); +} + +double AnimationImpl::duration() const +{ + if (mModel->isStatic()) return 0; + return double(mModel->frameDuration()) / double(mModel->frameRate()); +} + +bool AnimationImpl::update(size_t frameNo, const VSize &size) +{ + if (frameNo > mModel->frameDuration()) + frameNo = mModel->frameDuration(); + + mCompItem->resize(size); + return mCompItem->update(frameNo); +} + +Surface AnimationImpl::render(size_t frameNo, const Surface &surface) +{ + bool renderInProgress = mRenderInProgress.load(); + if (renderInProgress) + { + vCritical << "Already Rendering Scheduled for this Animation"; + return surface; + } + + mRenderInProgress.store(true); + update(frameNo, VSize(surface.width(), surface.height())); + mCompItem->render(surface); + mRenderInProgress.store(false); + + return surface; +} + +void AnimationImpl::init(const std::shared_ptr &model) +{ + mModel = model; + mCompItem = std::make_unique(mModel.get()); + mRenderInProgress = false; +} + +/* + * Implement a task stealing schduler to perform render task + * As each player draws into its own buffer we can delegate this + * task to a slave thread. The scheduler creates a threadpool depending + * on the number of cores available in the system and does a simple fair + * scheduling by assigning the task in a round-robin fashion. Each thread + * in the threadpool has its own queue. once it finishes all the task on its + * own queue it goes through rest of the queue and looks for task if it founds + * one it steals the task from it and executes. if it couldn't find one then it + * just waits for new task on its own queue. + */ +struct RenderTask { + RenderTask() { receiver = sender.get_future(); } + std::promise sender; + std::future receiver; + AnimationImpl *playerImpl; + size_t frameNo; + Surface surface; +}; + +#include +class RenderTaskScheduler { + const unsigned _count{std::thread::hardware_concurrency()}; + std::vector _threads; + std::vector> _q{_count}; + std::atomic _index{0}; + + void run(unsigned i) + { + while (true) { + RenderTask *task = nullptr; + + for (unsigned n = 0; n != _count * 32; ++n) { + if (_q[(i + n) % _count].try_pop(task)) break; + } + if (!task && !_q[i].pop(task)) break; + + auto result = task->playerImpl->render(task->frameNo, task->surface); + task->sender.set_value(result); + delete task; + } + } + +public: + RenderTaskScheduler() + { + for (unsigned n = 0; n != _count; ++n) { + _threads.emplace_back([&, n] { run(n); }); + } + } + + ~RenderTaskScheduler() + { + for (auto &e : _q) e.done(); + + for (auto &e : _threads) e.join(); + } + + std::future async(RenderTask *task) + { + auto receiver = std::move(task->receiver); + auto i = _index++; + + for (unsigned n = 0; n != _count; ++n) { + if (_q[(i + n) % _count].try_push(task)) return receiver; + } + + _q[i % _count].push(task); + + return receiver; + } + + std::future render(AnimationImpl *impl, size_t frameNo, + Surface &&surface) + { + RenderTask *task = new RenderTask(); + task->playerImpl = impl; + task->frameNo = frameNo; + task->surface = std::move(surface); + return async(task); + } +}; +static RenderTaskScheduler render_scheduler; + +/** + * \breif Brief abput the Api. + * Description about the setFilePath Api + * @param path add the details + */ +std::unique_ptr +Animation::loadFromData(const char *jsonData, const char *key) +{ + if (!jsonData) { + vWarning << "jason data is empty"; + return nullptr; + } + + LottieLoader loader; + if (loader.loadFromData(jsonData, key)) { + auto animation = std::make_unique(); + animation->d->init(loader.model()); + return animation; + } + return nullptr; +} + +std::unique_ptr +Animation::loadFromFile(const std::string &path) +{ + if (path.empty()) { + vWarning << "File path is empty"; + return nullptr; + } + + LottieLoader loader; + if (loader.load(path)) { + auto animation = std::make_unique(); + animation->d->init(loader.model()); + return animation; + } + return nullptr; +} + +void Animation::size(size_t &width, size_t &height) const +{ + VSize sz = d->size(); + + width = sz.width(); + height = sz.height(); +} + +double Animation::duration() const +{ + return d->duration(); +} + +double Animation::frameRate() const +{ + return d->frameRate(); +} + +size_t Animation::totalFrame() const +{ + return d->totalFrame(); +} + +size_t Animation::frameAtPos(double pos) +{ + return d->frameAtPos(pos); +} + +const std::vector & +Animation::renderList(size_t frameNo, size_t width, size_t height) const +{ + return d->renderList(frameNo, VSize(width, height)); +} + +std::future Animation::render(size_t frameNo, Surface surface) +{ + return render_scheduler.render(d.get(), frameNo, std::move(surface)); +} + +void Animation::renderSync(size_t frameNo, Surface surface) +{ + d->render(frameNo, surface); +} + +Animation::Animation(): d(std::make_unique()) {} + +/* + * this is only to supress build fail + * because unique_ptr expects the destructor in the same translation unit. + */ +Animation::~Animation(){} + +Surface::Surface(uint32_t *buffer, + size_t width, size_t height, size_t bytesPerLine) + :mBuffer(buffer), + mWidth(width), + mHeight(height), + mBytesPerLine(bytesPerLine) {} + + +void initLogging() +{ +#if defined(__ARM_NEON__) + set_log_level(LogLevel::OFF); +#else + initialize(GuaranteedLogger(), "/tmp/", "lotti-player", 1); + set_log_level(LogLevel::INFO); +#endif +} + +V_CONSTRUCTOR_FUNCTION(initLogging) diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index c113ea9..d63a176 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -107,10 +107,10 @@ const std::vector &LOTCompItem::renderList() const return mRenderList; } -bool LOTCompItem::render(const LOTBuffer &buffer) +bool LOTCompItem::render(const lottie::Surface &surface) { - VBitmap bitmap((uchar *)buffer.buffer, buffer.width, buffer.height, - buffer.bytesPerLine, VBitmap::Format::ARGB32_Premultiplied, + VBitmap bitmap((uchar *)surface.buffer(), surface.width(), surface.height(), + surface.bytesPerLine(), VBitmap::Format::ARGB32_Premultiplied, nullptr, nullptr); /* schedule all preprocess task for this frame at once. diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index 322592c..3ee7e0a 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -9,7 +9,8 @@ #include"vpath.h" #include"vpoint.h" #include"vpathmesure.h" -#include"lotcommon.h" +#include"lottiecommon.h" +#include"lottieanimation.h" #include"vpainter.h" #include"vdrawable.h" @@ -37,7 +38,7 @@ public: VSize size() const; const std::vector& renderList()const; void buildRenderList(); - bool render(const LOTBuffer &buffer); + bool render(const lottie::Surface &surface); private: VMatrix mScaleMatrix; VSize mViewSize; diff --git a/src/lottie/lottieloader.cpp b/src/lottie/lottieloader.cpp index 289876f..bdbbc71 100644 --- a/src/lottie/lottieloader.cpp +++ b/src/lottie/lottieloader.cpp @@ -15,7 +15,7 @@ public: return CACHE; } std::shared_ptr find(const std::string &key); - void add(std::string &key, std::shared_ptr value); + void add(const std::string &key, std::shared_ptr value); private: LottieFileCache() = default; @@ -33,12 +33,12 @@ std::shared_ptr LottieFileCache::find(const std::string &key) } } -void LottieFileCache::add(std::string &key, std::shared_ptr value) +void LottieFileCache::add(const std::string &key, std::shared_ptr value) { mHash[key] = std::move(value); } -bool LottieLoader::load(std::string &path) +bool LottieLoader::load(const std::string &path) { LottieFileCache &fileCache = LottieFileCache::get(); diff --git a/src/lottie/lottieloader.h b/src/lottie/lottieloader.h index 32ec5aa..da6bb35 100644 --- a/src/lottie/lottieloader.h +++ b/src/lottie/lottieloader.h @@ -8,7 +8,7 @@ class LOTModel; class LottieLoader { public: - bool load(std::string &filePath); + bool load(const std::string &filePath); bool loadFromData(const char *jsonData, const char *key); std::shared_ptr model(); private: diff --git a/src/lottie/lottiemodel.h b/src/lottie/lottiemodel.h index 26053f0..3d0183f 100644 --- a/src/lottie/lottiemodel.h +++ b/src/lottie/lottiemodel.h @@ -625,9 +625,9 @@ class LOTModel { public: bool isStatic() const{return mRoot->isStatic();} - int frameDuration() {return mRoot->frameDuration();} - int frameRate() {return mRoot->frameRate();} - int startFrame() {return mRoot->startFrame();} + size_t frameDuration() {return mRoot->frameDuration();} + size_t frameRate() {return mRoot->frameRate();} + size_t startFrame() {return mRoot->startFrame();} public: std::shared_ptr mRoot; }; diff --git a/src/lottie/lottieplayer.cpp b/src/lottie/lottieplayer.cpp deleted file mode 100644 index 551f56a..0000000 --- a/src/lottie/lottieplayer.cpp +++ /dev/null @@ -1,339 +0,0 @@ -#include - -#include "lottieitem.h" -#include "lottieloader.h" -#include "lottiemodel.h" - -#include - -using namespace lottieplayer; - -class LOTPlayerPrivate { - -public: - LOTPlayerPrivate(); - bool update(float pos); - bool setFilePath(std::string path); - bool loadFromData(const char *jsonData, - const char *key); - void setSize(const VSize &sz); - void setPos(float pos); - VSize size() const; - float playTime() const; - float pos(); - float frameRate() const; - long totalFrame() const; - const std::vector &renderList(float pos); - bool render(float pos, const LOTBuffer &buffer, bool forceRender); - -private: - std::string mFilePath; - std::shared_ptr mModel; - std::unique_ptr mCompItem; - VSize mSize; - std::atomic mRenderInProgress; - float mPos = 0.0; -}; - -float LOTPlayerPrivate::frameRate() const -{ - if (!mModel) { - vWarning << "Model Data is not existed yet, please setFilePath() first."; - return 0.0f; - } - - return mModel->frameRate(); -} - -long LOTPlayerPrivate::totalFrame() const -{ - if (!mModel) { - vWarning << "Model Data is not existed yet, please setFilePath() first."; - return 0.0f; - } - - return mModel->frameDuration(); -} - -void LOTPlayerPrivate::setSize(const VSize &sz) -{ - mSize = sz; -} - -VSize LOTPlayerPrivate::size() const -{ - if (!mCompItem) { - return mSize; - } else { - return mCompItem->size(); - } -} - -const std::vector &LOTPlayerPrivate::renderList(float pos) -{ - if (!mCompItem) { - static std::vector empty; - return empty; - } - - update(pos); - - return mCompItem->renderList(); -} - -float LOTPlayerPrivate::playTime() const -{ - if (!mModel || mModel->isStatic()) return 0; - return float(mModel->frameDuration()) / float(mModel->frameRate()); -} - -float LOTPlayerPrivate::pos() -{ - return mPos; -} - -void LOTPlayerPrivate::setPos(float pos) -{ - if (pos > 1.0) pos = 1.0; - if (pos < 0) pos = 0; - mPos = pos; -} - -bool LOTPlayerPrivate::update(float vPos) -{ - if (!mCompItem) return false; - - mCompItem->resize(mSize); - setPos(vPos); - - int frameNumber; - if (mModel->isStatic()) frameNumber = 0; - else frameNumber = mModel->startFrame() + pos() * mModel->frameDuration(); - - return mCompItem->update(frameNumber); -} - -bool LOTPlayerPrivate::render(float pos, const LOTBuffer &buffer, bool forceRender) -{ - if (!mCompItem) return false; - - bool renderInProgress = mRenderInProgress.load(); - if (renderInProgress) - { - vCritical << "Already Rendering Scheduled for this Player"; - } - - bool result = true; - - if (update(pos) || forceRender) - { - mRenderInProgress.store(true); - result = mCompItem->render(buffer); - mRenderInProgress.store(false); - } - - return result; -} - -LOTPlayerPrivate::LOTPlayerPrivate() : mRenderInProgress(false) {} - -bool LOTPlayerPrivate::setFilePath(std::string path) -{ - if (path.empty()) { - vWarning << "File path is empty"; - return false; - } - - LottieLoader loader; - if (loader.load(path)) { - mModel = loader.model(); - mCompItem = std::make_unique(mModel.get()); - return true; - } - return false; -} - -bool LOTPlayerPrivate::loadFromData(const char *jsonData, const char *key) -{ - if (!jsonData) { - vWarning << "jason data is empty"; - return false; - } - - LottieLoader loader; - if (loader.loadFromData(jsonData, key)) { - mModel = loader.model(); - mCompItem = std::make_unique(mModel.get()); - return true; - } - return false; -} - -/* - * Implement a task stealing schduler to perform render task - * As each player draws into its own buffer we can delegate this - * task to a slave thread. The scheduler creates a threadpool depending - * on the number of cores available in the system and does a simple fair - * scheduling by assigning the task in a round-robin fashion. Each thread - * in the threadpool has its own queue. once it finishes all the task on its - * own queue it goes through rest of the queue and looks for task if it founds - * one it steals the task from it and executes. if it couldn't find one then it - * just waits for new task on its own queue. - */ -struct RenderTask { - RenderTask() { receiver = sender.get_future(); } - std::promise sender; - std::future receiver; - LOTPlayerPrivate * playerImpl; - float pos; - LOTBuffer buffer; - bool forceRender; -}; - -#include -class RenderTaskScheduler { - const unsigned _count{std::thread::hardware_concurrency()}; - std::vector _threads; - std::vector> _q{_count}; - std::atomic _index{0}; - - void run(unsigned i) - { - while (true) { - RenderTask *task = nullptr; - - for (unsigned n = 0; n != _count * 32; ++n) { - if (_q[(i + n) % _count].try_pop(task)) break; - } - if (!task && !_q[i].pop(task)) break; - - bool result = task->playerImpl->render(task->pos, task->buffer, task->forceRender); - task->sender.set_value(result); - delete task; - } - } - -public: - RenderTaskScheduler() - { - for (unsigned n = 0; n != _count; ++n) { - _threads.emplace_back([&, n] { run(n); }); - } - } - - ~RenderTaskScheduler() - { - for (auto &e : _q) e.done(); - - for (auto &e : _threads) e.join(); - } - - std::future async(RenderTask *task) - { - auto receiver = std::move(task->receiver); - auto i = _index++; - - for (unsigned n = 0; n != _count; ++n) { - if (_q[(i + n) % _count].try_push(task)) return receiver; - } - - _q[i % _count].push(task); - - return receiver; - } - - std::future render(LOTPlayerPrivate *impl, float pos, - LOTBuffer &&buffer, bool forceRender) - { - RenderTask *task = new RenderTask(); - task->playerImpl = impl; - task->pos = pos; - task->buffer = std::move(buffer); - task->forceRender = forceRender; - return async(task); - } -}; -static RenderTaskScheduler render_scheduler; - -LOTPlayer::LOTPlayer() : d(new LOTPlayerPrivate()) {} - -LOTPlayer::~LOTPlayer() -{ - delete d; -} - -/** - * \breif Brief abput the Api. - * Description about the setFilePath Api - * @param path add the details - */ - -bool LOTPlayer::loadFromData(const char *jsonData, const char *key) -{ - return d->loadFromData(jsonData, key); -} - -bool LOTPlayer::setFilePath(const char *filePath) -{ - return d->setFilePath(filePath); -} - -void LOTPlayer::setSize(int width, int height) -{ - d->setSize(VSize(width, height)); -} - -void LOTPlayer::size(int &width, int &height) const -{ - VSize sz = d->size(); - - width = sz.width(); - height = sz.height(); -} - -float LOTPlayer::playTime() const -{ - return d->playTime(); -} - -float LOTPlayer::pos() const -{ - return d->pos(); -} - -float LOTPlayer::frameRate() const -{ - return d->frameRate(); -} - -long LOTPlayer::totalFrame() const -{ - return d->totalFrame(); -} - -const std::vector &LOTPlayer::renderList(float pos) const -{ - return d->renderList(pos); -} - -std::future LOTPlayer::render(float pos, LOTBuffer buffer, bool forceRender) -{ - return render_scheduler.render(d, pos, std::move(buffer), forceRender); -} - -bool LOTPlayer::renderSync(float pos, LOTBuffer buffer, bool forceRender) -{ - return d->render(pos, buffer, forceRender); -} - -void initLogging() -{ -#if defined(__ARM_NEON__) - set_log_level(LogLevel::OFF); -#else - initialize(GuaranteedLogger(), "/tmp/", "lotti-player", 1); - set_log_level(LogLevel::INFO); -#endif -} - -V_CONSTRUCTOR_FUNCTION(initLogging) diff --git a/src/lottie/meson.build b/src/lottie/meson.build index ba61f07..1c7275f 100644 --- a/src/lottie/meson.build +++ b/src/lottie/meson.build @@ -2,7 +2,7 @@ source_file = files('lottieparser.cpp') source_file += files('lottieloader.cpp') source_file += files('lottiemodel.cpp') -source_file += files('lottieplayer.cpp') +source_file += files('lottieanimation.cpp') source_file += files('lottieitem.cpp')