From: subhransu mohanty Date: Tue, 13 Nov 2018 02:36:34 +0000 (+0900) Subject: lottie: Added renderTree() api to the lottie animation object. X-Git-Tag: submit/tizen/20181129.071502~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b0ff909587d21d1b5326da12faf5b5fa7b83ad21;p=platform%2Fcore%2Fuifw%2Flottie-player.git lottie: Added renderTree() api to the lottie animation object. Change-Id: I137180d0d46036523357d3b7966dc441b57f9d0c --- diff --git a/example/lottieview.cpp b/example/lottieview.cpp index 7072a99..e12653c 100644 --- a/example/lottieview.cpp +++ b/example/lottieview.cpp @@ -159,6 +159,46 @@ void LottieView::update(const std::vector &renderList) evas_object_vg_root_node_set(mVg, root); } +void LottieView::updateTree(const LOTLayerNode * node) +{ + Efl_VG *root = evas_vg_container_add(mVg); + update(node, root); + evas_object_vg_root_node_set(mVg, root); +} + +void LottieView::update(const LOTLayerNode * node, Efl_VG *parent) +{ + // if the layer is invisible return + if (!node->mVisible) return; + + // check if this layer is a container layer + bool hasMatte = false; + if (node->mLayerList.size) { + for (unsigned int i = 0; i < node->mLayerList.size; i++) { + if (hasMatte) { + hasMatte = false; + continue; + } + // if the layer has matte then + // the next layer has to be rendered using this layer + // as matte source + if (node->mLayerList.ptr[i]->mMatte != MatteNone) { + hasMatte = true; + printf("Matte is not supported Yet\n"); + continue; + } + update(node->mLayerList.ptr[i], parent); + } + } + + // check if this layer has drawable + if (node->mNodeList.size) { + for (unsigned int i = 0; i < node->mNodeList.size; i++) { + createVgNode(node->mNodeList.ptr[i], parent); + } + } +} + static void mImageDelCb(void *data, Evas *evas, Evas_Object *obj, void *) { LottieView *lottie = (LottieView *)data; @@ -280,8 +320,8 @@ void LottieView::seek(float pos) evas_object_image_data_update_add(mImage, 0 , 0, surface.width(), surface.height()); } } else { - const std::vector &renderList = mPlayer->renderList(mCurFrame, mw, mh); - update(renderList); + const LOTLayerNode *root = mPlayer->renderTree(mCurFrame, mw, mh); + updateTree(root); } } diff --git a/example/lottieview.h b/example/lottieview.h index 6c3c4ee..cbb0815 100644 --- a/example/lottieview.h +++ b/example/lottieview.h @@ -51,6 +51,8 @@ public: private: void createVgNode(LOTNode *node, Efl_VG *root); void update(const std::vector &); + void updateTree(const LOTLayerNode *); + void update(const LOTLayerNode *, Efl_VG *parent); void restart(); public: int mw; diff --git a/inc/lottieanimation.h b/inc/lottieanimation.h index 08edd48..a569c6d 100644 --- a/inc/lottieanimation.h +++ b/inc/lottieanimation.h @@ -29,6 +29,7 @@ class AnimationImpl; struct LOTNode; +struct LOTLayerNode; namespace lottie { @@ -204,6 +205,18 @@ public: */ const std::vector &renderList(size_t frameNo, size_t width, size_t height) const; + /** + * @brief Returns root layer of the composition updated with + * content of the lottie resource at frame number {frameNo}. + * + * @param[in] frameNo Content corresponds to the frameno needs to be extracted. + * @param[in] width content viewbox width + * @param[in] height content viewbox height + * + * @return Root layer node. + */ + const LOTLayerNode * renderTree(size_t frameNo, size_t width, size_t height) const; + /** * @brief default destructor */ diff --git a/inc/lottiecommon.h b/inc/lottiecommon.h index 48db67e..75ede5d 100644 --- a/inc/lottiecommon.h +++ b/inc/lottiecommon.h @@ -77,6 +77,57 @@ typedef struct LOTGradientStop unsigned char r, g, b, a; } LOTGradientStop; +struct LOTNode; + +typedef enum +{ + MaskModeAdd = 0, + MaskModeSubstract, + MaskModeIntersect, + MaskModeDifference +} LOTMaskMode; + +typedef struct _LOTMask { + struct { + const float *ptPtr; + int ptCount; + const char* elmPtr; + int elmCount; + } mPath; + LOTMaskMode mMode; +}LOTMask; + +typedef enum +{ + MatteNone = 0, + MatteAlpha, + MatteAlphaInv, + MatteLuma, + MatteLumaInv +} LOTMatteType; + +typedef struct LOTLayerNode { + + struct { + LOTMask *ptr; + unsigned int size; + }mMaskList; + + struct { + LOTLayerNode **ptr; + unsigned int size; + }mLayerList; + + struct { + LOTNode **ptr; + unsigned int size; + }mNodeList; + + LOTMatteType mMatte; + int mVisible; + +}LOTLayerNode; + typedef struct LOTNode { #define ChangeFlagNone 0x0000 diff --git a/src/lottie/lottieanimation.cpp b/src/lottie/lottieanimation.cpp index 2e9cd17..7fdb861 100644 --- a/src/lottie/lottieanimation.cpp +++ b/src/lottie/lottieanimation.cpp @@ -22,6 +22,8 @@ public: const std::vector & renderList(size_t frameNo, const VSize &size); + const LOTLayerNode * + renderTree(size_t frameNo, const VSize &size); private: std::string mFilePath; std::shared_ptr mModel; @@ -37,6 +39,14 @@ const std::vector &AnimationImpl::renderList(size_t frameNo, const VS return mCompItem->renderList(); } +const LOTLayerNode *AnimationImpl::renderTree(size_t frameNo, const VSize &size) +{ + if (update(frameNo, size)) { + mCompItem->buildRenderTree(); + } + return mCompItem->renderTree(); +} + bool AnimationImpl::update(size_t frameNo, const VSize &size) { frameNo += mModel->startFrame(); @@ -232,6 +242,12 @@ Animation::renderList(size_t frameNo, size_t width, size_t height) const return d->renderList(frameNo, VSize(width, height)); } +const LOTLayerNode * +Animation::renderTree(size_t frameNo, size_t width, size_t height) const +{ + return d->renderTree(frameNo, VSize(width, height)); +} + std::future Animation::render(size_t frameNo, Surface surface) { return render_scheduler.render(d.get(), frameNo, std::move(surface)); diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index 009b3ba..648c120 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -106,6 +106,16 @@ const std::vector &LOTCompItem::renderList() const return mRenderList; } +void LOTCompItem::buildRenderTree() +{ + mRootLayer->buildLayerNode(); +} + +const LOTLayerNode * LOTCompItem::renderTree() const +{ + return mRootLayer->layerNode(); +} + bool LOTCompItem::render(const lottie::Surface &surface) { VBitmap bitmap((uchar *)surface.buffer(), surface.width(), surface.height(), @@ -159,6 +169,45 @@ VRle LOTMaskItem::rle() return mRle; } +void LOTLayerItem::buildLayerNode() +{ + if (!mLayerCNode) { + mLayerCNode = std::make_unique(); + mLayerCNode->mMaskList.ptr = nullptr; + mLayerCNode->mMaskList.size = 0; + mLayerCNode->mLayerList.ptr = nullptr; + mLayerCNode->mLayerList.size = 0; + mLayerCNode->mNodeList.ptr = nullptr; + mLayerCNode->mNodeList.size = 0; + mLayerCNode->mMatte = MatteNone; + mLayerCNode->mVisible = 0; + } + mLayerCNode->mVisible = visible(); + // update matte + if (hasMatte()) { + switch (mLayerData->mMatteType) { + case MatteType::Alpha: + mLayerCNode->mMatte = MatteAlpha; + break; + case MatteType::AlphaInv: + mLayerCNode->mMatte = MatteAlphaInv; + break; + case MatteType::Luma: + mLayerCNode->mMatte = MatteLuma; + break; + case MatteType::LumaInv: + mLayerCNode->mMatte = MatteLumaInv; + break; + default: + mLayerCNode->mMatte = MatteNone; + break; + } + } + if (hasMask()) { + //TODO populate mask property + } +} + void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle &inheritMatte, LOTLayerItem *matteSource) { VRle matteRle; @@ -351,6 +400,23 @@ void LOTCompLayerItem::updateStaticProperty() } } +void LOTCompLayerItem::buildLayerNode() +{ + LOTLayerItem::buildLayerNode(); + if (mLayers.size() != mLayersCNode.size()) { + for (const auto &layer : mLayers) { + layer->buildLayerNode(); + mLayersCNode.push_back(layer->layerNode()); + } + layerNode()->mLayerList.ptr = mLayersCNode.data(); + layerNode()->mLayerList.size = mLayersCNode.size(); + } else { + for (const auto &layer : mLayers) { + layer->buildLayerNode(); + } + } +} + void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle &inheritMatte, LOTLayerItem *matteSource) { VRle matteRle; @@ -443,6 +509,23 @@ void LOTSolidLayerItem::updateContent() } } +void LOTSolidLayerItem::buildLayerNode() +{ + LOTLayerItem::buildLayerNode(); + + mDrawableList.clear(); + renderList(mDrawableList); + + mCNodeList.clear(); + for (auto &i : mDrawableList) { + LOTDrawable *lotDrawable = static_cast(i); + lotDrawable->sync(); + mCNodeList.push_back(lotDrawable->mCNode.get()); + } + layerNode()->mNodeList.ptr = mCNodeList.data(); + layerNode()->mNodeList.size = mCNodeList.size(); +} + void LOTSolidLayerItem::renderList(std::vector &list) { if (!visible()) return; @@ -535,6 +618,23 @@ void LOTShapeLayerItem::updateContent() } } +void LOTShapeLayerItem::buildLayerNode() +{ + LOTLayerItem::buildLayerNode(); + + mDrawableList.clear(); + renderList(mDrawableList); + + mCNodeList.clear(); + for (auto &i : mDrawableList) { + LOTDrawable *lotDrawable = static_cast(i); + lotDrawable->sync(); + mCNodeList.push_back(lotDrawable->mCNode.get()); + } + layerNode()->mNodeList.ptr = mCNodeList.data(); + layerNode()->mNodeList.size = mCNodeList.size(); +} + void LOTShapeLayerItem::renderList(std::vector &list) { if (!visible()) return; diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index 4f14597..a92dd8d 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -38,6 +38,8 @@ public: VSize size() const; const std::vector& renderList()const; void buildRenderList(); + void buildRenderTree(); + const LOTLayerNode * renderTree()const; bool render(const lottie::Surface &surface); private: VMatrix mScaleMatrix; @@ -68,7 +70,8 @@ public: virtual void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource); bool hasMatte() { if (mLayerData->mMatteType == MatteType::None) return false; return true; } bool visible() const; - + virtual void buildLayerNode(); + LOTLayerNode * layerNode() const {return mLayerCNode.get();} protected: virtual void updateContent() = 0; inline VMatrix combinedMatrix() const {return mCombinedMatrix;} @@ -80,6 +83,7 @@ protected: VRle maskRle(const VRect &clipRect); bool hasMask() const {return !mMasks.empty();} protected: + std::unique_ptr mLayerCNode; std::vector mDrawableList; std::vector> mMasks; LOTLayerData *mLayerData{nullptr}; @@ -99,9 +103,11 @@ public: void renderList(std::vector &list)final; void updateStaticProperty() final; void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource) final; + void buildLayerNode() final; protected: void updateContent() final; private: + std::vector mLayersCNode; std::vector> mLayers; int mLastFrame; }; @@ -110,10 +116,12 @@ class LOTSolidLayerItem: public LOTLayerItem { public: LOTSolidLayerItem(LOTLayerData *layerData); + void buildLayerNode() final; protected: void updateContent() final; void renderList(std::vector &list) final; private: + std::vector mCNodeList; std::unique_ptr mRenderNode; }; @@ -125,8 +133,10 @@ public: LOTShapeLayerItem(LOTLayerData *layerData); static std::unique_ptr createContentItem(LOTData *contentData); void renderList(std::vector &list)final; + void buildLayerNode() final; protected: void updateContent() final; + std::vector mCNodeList; std::unique_ptr mRoot; };