lottie: refactor the lottie scene graph processing. 23/187423/1
authorsubhransu mohanty <sub.mohanty@samsung.com>
Thu, 23 Aug 2018 02:12:13 +0000 (11:12 +0900)
committersubhransu mohanty <sub.mohanty@samsung.com>
Thu, 23 Aug 2018 06:28:33 +0000 (15:28 +0900)
Change-Id: I739aa19abaf7f141b556b67083df4461945461d9

src/lottie/lottieitem.cpp
src/lottie/lottieitem.h
src/vector/vdrawable.cpp

index 1960242..23810d9 100644 (file)
@@ -457,7 +457,10 @@ LOTShapeLayerItem::LOTShapeLayerItem(LOTLayerData *layerData)
 {
     mRoot = std::make_unique<LOTContentGroupItem>(nullptr);
     mRoot->addChildren(layerData);
-    mRoot->processPaintOperation();
+
+    std::vector<LOTPathDataItem *> list;
+    mRoot->processPathItems(list);
+
     if (layerData->hasPathOperator()) mRoot->processTrimOperation();
 }
 
@@ -576,44 +579,26 @@ void LOTContentGroupItem::renderList(std::vector<VDrawable *> &list)
     }
 }
 
-void LOTContentGroupItem::processPaintOperation()
-{
-    std::vector<LOTPaintDataItem *> list;
-    paintOperationHelper(list);
-}
-
-void LOTContentGroupItem::paintOperationHelper(
-    std::vector<LOTPaintDataItem *> &list)
+void LOTContentGroupItem::processPathItems(
+    std::vector<LOTPathDataItem *> &list)
 {
     int curOpCount = list.size();
-    for (auto i = mContents.rbegin(); i != mContents.rend(); ++i) {
-        auto child = (*i).get();
-        if (auto pathNode = dynamic_cast<LOTPathDataItem *>(child)) {
-            // the node is a path data node add the paint operation list to it.
-            pathNode->addPaintOperation(list, curOpCount);
-        } else if (auto paintNode = dynamic_cast<LOTPaintDataItem *>(child)) {
-            // add it to the paint operation list
-            list.push_back(paintNode);
+    for (auto &i : mContents) {
+        if (auto pathNode = dynamic_cast<LOTPathDataItem *>(i.get())) {
+            // add it to the list
+            list.push_back(pathNode);
+        } else if (auto paintNode = dynamic_cast<LOTPaintDataItem *>(i.get())) {
+            // the node is a paint data node update the path list of the paint item.
+            paintNode->addPathItems(list);
         } else if (auto groupNode =
-                       dynamic_cast<LOTContentGroupItem *>(child)) {
+                       dynamic_cast<LOTContentGroupItem *>(i.get())) {
             // update the groups node with current list
-            groupNode->paintOperationHelper(list);
+            groupNode->processPathItems(list);
         }
     }
     list.erase(list.begin() + curOpCount, list.end());
 }
 
-void LOTPathDataItem::addPaintOperation(std::vector<LOTPaintDataItem *> &list,
-                                        int externalCount)
-{
-    for (auto paintItem : list) {
-        bool sameGroup = (externalCount-- > 0) ? false : true;
-        mNodeList.push_back(std::make_unique<LOTDrawable>());
-        mRenderList.push_back(
-            LOTRenderNode(this, paintItem, mNodeList.back().get(), sameGroup));
-    }
-}
-
 void LOTContentGroupItem::processTrimOperation()
 {
     std::vector<LOTTrimItem *> list;
@@ -682,30 +667,6 @@ void LOTPathDataItem::update(int frameNo, const VMatrix &parentMatrix,
         mFinalPath.transform(parentMatrix);
         mPathChanged = true;
     }
-
-    // 2. update the rendernode list
-    for (const auto &i : mRenderList) {
-        i.drawable->mFlag = VDrawable::DirtyState::None;
-        i.paintNodeRef->updateRenderNode(i.pathNodeRef, i.drawable,
-                                         i.sameGroup);
-        if (mPathChanged)
-            i.drawable->mFlag |= VDrawable::DirtyState::Path;
-
-        if (i.drawable->mFlag & VDrawable::DirtyState::Path)
-            i.drawable->mPath = mFinalPath;
-    }
-}
-
-void LOTPathDataItem::renderList(std::vector<VDrawable *> &list)
-{
-    for (const auto &i : mRenderList) {
-        list.push_back(i.drawable);
-    }
-}
-
-VPath LOTPathDataItem::path() const
-{
-    return mFinalPath;
 }
 
 LOTRectItem::LOTRectItem(LOTRectData *data)
@@ -790,23 +751,61 @@ void LOTPolystarItem::updatePath(VPath& path, int frameNo)
  * PaintData Node handling
  *
  */
+LOTPaintDataItem::LOTPaintDataItem(bool staticContent):mDrawable(std::make_unique<LOTDrawable>()),
+                                                       mStaticContent(staticContent){}
 
 void LOTPaintDataItem::update(int frameNo, const VMatrix &parentMatrix,
                               float parentAlpha, const DirtyFlag &flag)
 {
-    mContentChanged = false;
+    mRenderNodeUpdate = true;
     mParentAlpha = parentAlpha;
     mParentMatrix = parentMatrix;
     mFlag = flag;
     mFrameNo = frameNo;
-    // 1. update the local content if needed
-    // if (!(mInit && mStaticContent)) {
-    mInit = true;
+
     updateContent(frameNo);
-    mContentChanged = true;
-    // }
 }
 
+void LOTPaintDataItem::updateRenderNode()
+{
+    bool dirty = false;
+    for (auto &i : mPathItems) {
+        if (i->dirty()) {
+            dirty = true;
+            break;
+        }
+    }
+
+    if (dirty) {
+        mPath.reset();
+
+        for (auto &i : mPathItems) {
+            mPath.addPath(i->path());
+        }
+        mDrawable->setPath(mPath);
+    } else {
+        if (mDrawable->mFlag & VDrawable::DirtyState::Path)
+            mDrawable->mPath = mPath;
+    }
+}
+
+void LOTPaintDataItem::renderList(std::vector<VDrawable *> &list)
+{
+    if (mRenderNodeUpdate) {
+        updateRenderNode();
+        LOTPaintDataItem::updateRenderNode();
+        mRenderNodeUpdate = false;
+    }
+    list.push_back(mDrawable.get());
+}
+
+
+void LOTPaintDataItem::addPathItems(std::vector<LOTPathDataItem *> &list)
+{
+    mPathItems = list;
+}
+
+
 LOTFillItem::LOTFillItem(LOTFillData *data)
     : LOTPaintDataItem(data->isStatic()), mData(data)
 {
@@ -820,15 +819,14 @@ void LOTFillItem::updateContent(int frameNo)
     mFillRule = mData->fillRule();
 }
 
-void LOTFillItem::updateRenderNode(LOTPathDataItem *pathNode,
-                                   VDrawable *drawable, bool sameParent)
+void LOTFillItem::updateRenderNode()
 {
     VColor color = mColor;
 
     color.setAlpha(color.a * parentAlpha());
     VBrush brush(color);
-    drawable->setBrush(brush);
-    drawable->setFillRule(mFillRule);
+    mDrawable->setBrush(brush);
+    mDrawable->setFillRule(mFillRule);
 }
 
 LOTGFillItem::LOTGFillItem(LOTGFillData *data)
@@ -843,11 +841,10 @@ void LOTGFillItem::updateContent(int frameNo)
     mFillRule = mData->fillRule();
 }
 
-void LOTGFillItem::updateRenderNode(LOTPathDataItem */*pathNode*/,
-                                    VDrawable *drawable, bool /*sameParent*/)
+void LOTGFillItem::updateRenderNode()
 {
-    drawable->setBrush(VBrush(mGradient.get()));
-    drawable->setFillRule(mFillRule);
+    mDrawable->setBrush(VBrush(mGradient.get()));
+    mDrawable->setFillRule(mFillRule);
 }
 
 LOTStrokeItem::LOTStrokeItem(LOTStrokeData *data)
@@ -882,21 +879,20 @@ static float getScale(const VMatrix &matrix)
     return std::sqrt(final.x() * final.x() + final.y() * final.y());
 }
 
-void LOTStrokeItem::updateRenderNode(LOTPathDataItem *pathNode,
-                                     VDrawable *drawable, bool sameParent)
+void LOTStrokeItem::updateRenderNode()
 {
     VColor color = mColor;
 
     color.setAlpha(color.a * parentAlpha());
     VBrush brush(color);
-    drawable->setBrush(brush);
+    mDrawable->setBrush(brush);
     float scale = getScale(mParentMatrix);
-    drawable->setStrokeInfo(mCap, mJoin, mMiterLimit,
+    mDrawable->setStrokeInfo(mCap, mJoin, mMiterLimit,
                             mWidth * scale);
     if (mDashArraySize) {
         for (int i = 0 ; i < mDashArraySize ; i++)
             mDashArray[i] *= scale;
-        drawable->setDashInfo(mDashArray, mDashArraySize);
+        mDrawable->setDashInfo(mDashArray, mDashArraySize);
     }
 }
 
@@ -919,17 +915,16 @@ void LOTGStrokeItem::updateContent(int frameNo)
     }
 }
 
-void LOTGStrokeItem::updateRenderNode(LOTPathDataItem */*pathNode*/,
-                                      VDrawable *drawable, bool /*sameParent*/)
+void LOTGStrokeItem::updateRenderNode()
 {
     float scale = getScale(mParentMatrix);
-    drawable->setBrush(VBrush(mGradient.get()));
-    drawable->setStrokeInfo(mCap, mJoin, mMiterLimit,
+    mDrawable->setBrush(VBrush(mGradient.get()));
+    mDrawable->setStrokeInfo(mCap, mJoin, mMiterLimit,
                             mWidth * scale);
     if (mDashArraySize) {
         for (int i = 0 ; i < mDashArraySize ; i++)
             mDashArray[i] *= scale;
-        drawable->setDashInfo(mDashArray, mDashArraySize);
+        mDrawable->setDashInfo(mDashArray, mDashArraySize);
     }
 }
 
index 90630a8..0af1183 100644 (file)
@@ -192,6 +192,7 @@ public:
    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
    void processPaintOperation();
    void processTrimOperation();
+   void processPathItems(std::vector<LOTPathDataItem *> &list);
    void renderList(std::vector<VDrawable *> &list) final;
 private:
    void paintOperationHelper(std::vector<LOTPaintDataItem *> &list);
@@ -206,18 +207,16 @@ public:
    LOTPathDataItem(bool staticPath):mInit(false), mStaticPath(staticPath){}
    void addPaintOperation(std::vector<LOTPaintDataItem *> &list, int externalCount);
    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
-   VPath path() const;
    void addTrimOperation(std::vector<LOTTrimItem *> &list);
-   void renderList(std::vector<VDrawable *> &list) final;
+   bool dirty() const {return mPathChanged;}
+   const VPath &path()const {return mFinalPath;}
 private:
    std::vector<LOTTrimItem *>              mTrimNodeRefs;
-   std::vector<LOTRenderNode>              mRenderList;
-   std::vector<std::unique_ptr<VDrawable>> mNodeList;
    bool                                    mInit;
    bool                                    mStaticPath;
-   VPath                                  mLocalPath;
-   VPath                                  mFinalPath;
-   bool                                    mPathChanged;
+   VPath                                   mLocalPath;
+   VPath                                   mFinalPath;
+   bool                                    mPathChanged{true};
 protected:
    virtual void updatePath(VPath& path, int frameNo) = 0;
    virtual bool hasChanged(int frameNo) = 0;
@@ -362,21 +361,24 @@ private:
 class LOTPaintDataItem : public LOTContentItem
 {
 public:
-   LOTPaintDataItem(bool staticContent):mInit(false), mStaticContent(staticContent){}
+   LOTPaintDataItem(bool staticContent);
+   void addPathItems(std::vector<LOTPathDataItem *> &list);
    virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag);
-   virtual void updateRenderNode(LOTPathDataItem *pathNode, VDrawable *renderer, bool sameParent) = 0;
+   void renderList(std::vector<VDrawable *> &list) final;
 protected:
    virtual void updateContent(int frameNo) = 0;
+   virtual void updateRenderNode();
    inline float parentAlpha() const {return mParentAlpha;}
-   inline bool  contentChanged() const{return mContentChanged;}
 public:
-   float         mParentAlpha;
-   VMatrix      mParentMatrix;
-   DirtyFlag     mFlag;
-   int           mFrameNo;
-   bool          mInit;
-   bool          mStaticContent;
-   bool          mContentChanged;
+   float                            mParentAlpha;
+   VMatrix                          mParentMatrix;
+   VPath                            mPath;
+   DirtyFlag                        mFlag;
+   int                              mFrameNo;
+   std::vector<LOTPathDataItem *>   mPathItems;
+   std::unique_ptr<VDrawable>       mDrawable;
+   bool                             mStaticContent;
+   bool                             mRenderNodeUpdate{true};
 };
 
 class LOTFillItem : public LOTPaintDataItem
@@ -385,7 +387,7 @@ public:
    LOTFillItem(LOTFillData *data);
 protected:
    void updateContent(int frameNo) final;
-   void updateRenderNode(LOTPathDataItem *pathNode, VDrawable *renderer, bool sameParent) final;
+   void updateRenderNode() final;
 private:
    LOTFillData             *mData;
    VColor                  mColor;
@@ -398,7 +400,7 @@ public:
    LOTGFillItem(LOTGFillData *data);
 protected:
    void updateContent(int frameNo) final;
-   void updateRenderNode(LOTPathDataItem *pathNode, VDrawable *renderer, bool sameParent) final;
+   void updateRenderNode() final;
 private:
    LOTGFillData                 *mData;
    std::unique_ptr<VGradient>    mGradient;
@@ -411,7 +413,7 @@ public:
    LOTStrokeItem(LOTStrokeData *data);
 protected:
    void updateContent(int frameNo) final;
-   void updateRenderNode(LOTPathDataItem *pathNode, VDrawable *renderer, bool sameParent) final;
+   void updateRenderNode() final;
 private:
    LOTStrokeData             *mData;
    CapStyle                  mCap;
@@ -429,7 +431,7 @@ public:
    LOTGStrokeItem(LOTGStrokeData *data);
 protected:
    void updateContent(int frameNo) final;
-   void updateRenderNode(LOTPathDataItem *pathNode, VDrawable *renderer, bool sameParent) final;
+   void updateRenderNode() final;
 private:
    LOTGStrokeData               *mData;
    std::unique_ptr<VGradient>    mGradient;
index 450952b..eda7352 100644 (file)
@@ -70,3 +70,9 @@ void VDrawable::setDashInfo(float *array, uint size)
     }
     mFlag |= DirtyState::Path;
 }
+
+void VDrawable::setPath(const VPath &path)
+{
+    mPath = path;
+    mFlag |= DirtyState::Path;
+}