rlottie: refactor to reduce lottie item memory footprint
authorsubhransu mohanty <sub.mohanty@samsung.com>
Thu, 10 Oct 2019 04:34:18 +0000 (13:34 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Thu, 10 Oct 2019 21:43:55 +0000 (06:43 +0900)
src/lottie/lottieitem.cpp
src/lottie/lottieitem.h

index c49255d..092f9fc 100644 (file)
@@ -825,7 +825,7 @@ bool LOTStrokeItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
 }
 
 LOTContentGroupItem::LOTContentGroupItem(LOTGroupData *data)
-    : LOTContentItem(ContentType::Group), mData(data)
+    : mData(data)
 {
     addChildren(mData);
 }
@@ -842,7 +842,6 @@ void LOTContentGroupItem::addChildren(LOTGroupData *data)
          ++it ) {
         auto content = LOTShapeLayerItem::createContentItem((*it).get());
         if (content) {
-            content->setParent(this);
             mContents.push_back(std::move(content));
         }
     }
@@ -851,8 +850,8 @@ void LOTContentGroupItem::addChildren(LOTGroupData *data)
 void LOTContentGroupItem::update(int frameNo, const VMatrix &parentMatrix,
                                  float parentAlpha, const DirtyFlag &flag)
 {
-    float     alpha = parentAlpha;
     DirtyFlag newFlag = flag;
+    float alpha;
 
     if (mData && mData->mTransform) {
         VMatrix m = mData->mTransform->matrix(frameNo);
@@ -865,12 +864,13 @@ void LOTContentGroupItem::update(int frameNo, const VMatrix &parentMatrix,
 
         mMatrix = m;
 
-        alpha *= mData->mTransform->opacity(frameNo);
+        alpha = parentAlpha * mData->mTransform->opacity(frameNo);
         if (!vCompare(alpha, parentAlpha)) {
             newFlag |= DirtyFlagBit::Alpha;
         }
     } else {
         mMatrix = parentMatrix;
+        alpha = parentAlpha;
     }
 
     for (const auto &content : mContents) {
@@ -912,7 +912,9 @@ void LOTContentGroupItem::processPaintItems(
         auto content = (*i).get();
         switch (content->type()) {
         case ContentType::Path: {
-            list.push_back(static_cast<LOTPathDataItem *>(content));
+            auto pathItem = static_cast<LOTPathDataItem *>(content);
+            pathItem->setParent(this);
+            list.push_back(pathItem);
             break;
         }
         case ContentType::Paint: {
@@ -1083,19 +1085,15 @@ void LOTPolystarItem::updatePath(VPath &path, int frameNo)
  *
  */
 LOTPaintDataItem::LOTPaintDataItem(bool staticContent)
-    : LOTContentItem(ContentType::Paint), mStaticContent(staticContent)
+    : mStaticContent(staticContent)
 {
 }
 
-void LOTPaintDataItem::update(int   frameNo, const VMatrix & /*parentMatrix*/,
-                              float parentAlpha, const DirtyFlag &flag)
+void LOTPaintDataItem::update(int   frameNo, const VMatrix & parentMatrix,
+                              float parentAlpha, const DirtyFlag &/*flag*/)
 {
     mRenderNodeUpdate = true;
-    mParentAlpha = parentAlpha;
-    mFlag = flag;
-    mFrameNo = frameNo;
-
-    updateContent(frameNo);
+    updateContent(frameNo, parentMatrix, parentAlpha);
 }
 
 void LOTPaintDataItem::updateRenderNode()
@@ -1125,7 +1123,6 @@ void LOTPaintDataItem::renderList(std::vector<VDrawable *> &list)
 {
     if (mRenderNodeUpdate) {
         updateRenderNode();
-        LOTPaintDataItem::updateRenderNode();
         mRenderNodeUpdate = false;
     }
     list.push_back(&mDrawable);
@@ -1143,16 +1140,10 @@ LOTFillItem::LOTFillItem(LOTFillData *data)
 {
 }
 
-void LOTFillItem::updateContent(int frameNo)
-{
-    mColor = mModel.color(frameNo).toColor(mModel.opacity(frameNo));
-}
-
-void LOTFillItem::updateRenderNode()
+void LOTFillItem::updateContent(int frameNo, const VMatrix &, float alpha)
 {
-    VColor color = mColor;
-
-    color.setAlpha(uchar(color.a * parentAlpha()));
+    auto color = mModel.color(frameNo).toColor(mModel.opacity(frameNo));
+    color.setAlpha(uchar(color.a * alpha));
     VBrush brush(color);
     mDrawable.setBrush(brush);
     mDrawable.setFillRule(mModel.fillRule());
@@ -1163,80 +1154,65 @@ LOTGFillItem::LOTGFillItem(LOTGFillData *data)
 {
 }
 
-void LOTGFillItem::updateContent(int frameNo)
+void LOTGFillItem::updateContent(int frameNo, const VMatrix &matrix, float alpha)
 {
-    mAlpha = mData->opacity(frameNo);
     mData->update(mGradient, frameNo);
-    mGradient->mMatrix = static_cast<LOTContentGroupItem *>(parent())->matrix();
-    mFillRule = mData->fillRule();
-}
-
-void LOTGFillItem::updateRenderNode()
-{
-    mGradient->setAlpha(mAlpha * parentAlpha());
+    mGradient->setAlpha(mData->opacity(frameNo) * alpha);
+    mGradient->mMatrix = matrix;
     mDrawable.setBrush(VBrush(mGradient.get()));
-    mDrawable.setFillRule(mFillRule);
+    mDrawable.setFillRule(mData->fillRule());
 }
 
 LOTStrokeItem::LOTStrokeItem(LOTStrokeData *data)
     : LOTPaintDataItem(data->isStatic()), mModel(data){}
 
-void LOTStrokeItem::updateContent(int frameNo)
-{
-    mColor = mModel.color(frameNo).toColor(mModel.opacity(frameNo));
-    mWidth = mModel.strokeWidth(frameNo);
-    if (mModel.hasDashInfo()) mModel.getDashInfo(frameNo, mDashInfo);
-}
+static thread_local std::vector<float> Dash_Vector;
 
-void LOTStrokeItem::updateRenderNode()
+void LOTStrokeItem::updateContent(int frameNo, const VMatrix &matrix, float alpha)
 {
-    VColor color = mColor;
-
-    color.setAlpha(uchar(color.a * parentAlpha()));
+    VColor color = mModel.color(frameNo).toColor(mModel.opacity(frameNo));;
+    color.setAlpha(uchar(color.a * alpha));
     VBrush brush(color);
     mDrawable.setBrush(brush);
-    float scale =
-        static_cast<LOTContentGroupItem *>(parent())->matrix().scale();
+    float scale = matrix.scale();
     mDrawable.setStrokeInfo(mModel.capStyle(), mModel.joinStyle(),
-                            mModel.miterLimit(), mWidth * scale);
-
-    if (!mDashInfo.empty()) {
-        for (auto &elm : mDashInfo) elm *= scale;
-        mDrawable.setDashInfo(mDashInfo);
+                            mModel.miterLimit(), mModel.strokeWidth(frameNo) * scale);
+
+    if (mModel.hasDashInfo()) {
+        Dash_Vector.clear();
+        mModel.getDashInfo(frameNo, Dash_Vector);
+        if (!Dash_Vector.empty()) {
+            for (auto &elm : Dash_Vector) elm *= scale;
+            mDrawable.setDashInfo(Dash_Vector);
+        }
     }
 }
 
 LOTGStrokeItem::LOTGStrokeItem(LOTGStrokeData *data)
     : LOTPaintDataItem(data->isStatic()), mData(data){}
 
-void LOTGStrokeItem::updateContent(int frameNo)
+void LOTGStrokeItem::updateContent(int frameNo, const VMatrix &matrix, float alpha)
 {
-    mAlpha = mData->opacity(frameNo);
     mData->update(mGradient, frameNo);
-    mGradient->mMatrix = static_cast<LOTContentGroupItem *>(parent())->matrix();
-    mCap = mData->capStyle();
-    mJoin = mData->joinStyle();
-    mMiterLimit = mData->miterLimit();
-    mWidth = mData->width(frameNo);
-
-    if (mData->hasDashInfo()) mData->getDashInfo(frameNo, mDashInfo);
-}
-
-void LOTGStrokeItem::updateRenderNode()
-{
-    float scale = mGradient->mMatrix.scale();
-    mGradient->setAlpha(mAlpha * parentAlpha());
+    mGradient->setAlpha(mData->opacity(frameNo) * alpha);
+    mGradient->mMatrix = matrix;
+    auto scale = mGradient->mMatrix.scale();
     mDrawable.setBrush(VBrush(mGradient.get()));
-    mDrawable.setStrokeInfo(mCap, mJoin, mMiterLimit, mWidth * scale);
-
-    if (!mDashInfo.empty()) {
-        for (auto &elm : mDashInfo) elm *= scale;
-        mDrawable.setDashInfo(mDashInfo);
+    mDrawable.setStrokeInfo(mData->capStyle(),  mData->joinStyle(),
+                            mData->miterLimit(), mData->width(frameNo) * scale);
+
+    if (mData->hasDashInfo()) {
+        Dash_Vector.clear();
+        mData->getDashInfo(frameNo, Dash_Vector);
+        if (!Dash_Vector.empty()) {
+            for (auto &elm : Dash_Vector) elm *= scale;
+            mDrawable.setDashInfo(Dash_Vector);
+        }
     }
 }
 
 LOTTrimItem::LOTTrimItem(LOTTrimData *data)
-    : LOTContentItem(ContentType::Trim), mData(data)
+    : mData(data)
 {
 }
 
@@ -1338,7 +1314,7 @@ LOTRepeaterItem::LOTRepeaterItem(LOTRepeaterData *data) : mRepeaterData(data)
     for (int i = 0; i < mCopies; i++) {
         auto content =
             std::make_unique<LOTContentGroupItem>(mRepeaterData->content());
-        content->setParent(this);
+        //content->setParent(this);
         mContents.push_back(std::move(content));
     }
 }
index 5baa933..1c046c5 100644 (file)
@@ -262,7 +262,7 @@ class LOTPathDataItem;
 class LOTPaintDataItem;
 class LOTTrimItem;
 
-enum class ContentType
+enum class ContentType : uchar
 {
     Unknown,
     Group,
@@ -271,21 +271,15 @@ enum class ContentType
     Trim
 };
 
+class LOTContentGroupItem;
 class LOTContentItem
 {
 public:
    virtual ~LOTContentItem() = default;
    LOTContentItem& operator=(LOTContentItem&&) noexcept = delete;
-   LOTContentItem(ContentType type=ContentType::Unknown):mType(type) {}
-   virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) = 0;
-   virtual void renderList(std::vector<VDrawable *> &){}
-   void setParent(LOTContentItem *parent) {mParent = parent;}
-   LOTContentItem *parent() const {return mParent;}
+   virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) = 0;   virtual void renderList(std::vector<VDrawable *> &){}
    virtual bool resolveKeyPath(LOTKeyPath &, uint, LOTVariant &) {return false;}
-   ContentType type() const {return mType;}
-private:
-   ContentType     mType{ContentType::Unknown};
-   LOTContentItem *mParent{nullptr};
+   virtual ContentType type() const {return ContentType::Unknown;}
 };
 
 class LOTContentGroupItem: public LOTContentItem
@@ -298,6 +292,7 @@ public:
    void processTrimItems(std::vector<LOTPathDataItem *> &list);
    void processPaintItems(std::vector<LOTPathDataItem *> &list);
    void renderList(std::vector<VDrawable *> &list) override;
+   ContentType type() const final {return ContentType::Group;}
    const VMatrix & matrix() const { return mMatrix;}
    const char* name() const
    {
@@ -314,13 +309,16 @@ protected:
 class LOTPathDataItem : public LOTContentItem
 {
 public:
-   LOTPathDataItem(bool staticPath): LOTContentItem(ContentType::Path), mStaticPath(staticPath){}
+   LOTPathDataItem(bool staticPath): mStaticPath(staticPath){}
    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
+   ContentType type() const final {return ContentType::Path;}
    bool dirty() const {return mPathChanged;}
    const VPath &localPath() const {return mTemp;}
    const VPath &finalPath();
    void updatePath(const VPath &path) {mTemp = path; mPathChanged = true; mNeedUpdate = true;}
    bool staticPath() const { return mStaticPath; }
+   void setParent(LOTContentGroupItem *parent) {mParent = parent;}
+   LOTContentGroupItem *parent() const {return mParent;}
 protected:
    virtual void updatePath(VPath& path, int frameNo) = 0;
    virtual bool hasChanged(int prevFrame, int curFrame) = 0;
@@ -333,6 +331,7 @@ private:
            (prevFrame == frameNo)) return false;
        return hasChanged(prevFrame, frameNo);
    }
+   LOTContentGroupItem                    *mParent{nullptr};
    VPath                                   mLocalPath;
    VPath                                   mTemp;
    VPath                                   mFinalPath;
@@ -353,7 +352,7 @@ protected:
    bool hasChanged(int prevFrame, int curFrame) final {
        return (mData->mPos.changed(prevFrame, curFrame) ||
                mData->mSize.changed(prevFrame, curFrame) ||
-               mData->mRound.changed(prevFrame, curFrame)) ? true : false;
+               mData->mRound.changed(prevFrame, curFrame));
    }
 };
 
@@ -366,7 +365,7 @@ private:
    LOTEllipseData           *mData;
    bool hasChanged(int prevFrame, int curFrame) final {
        return (mData->mPos.changed(prevFrame, curFrame) ||
-               mData->mSize.changed(prevFrame, curFrame)) ? true : false;
+               mData->mSize.changed(prevFrame, curFrame));
    }
 };
 
@@ -397,7 +396,7 @@ private:
                mData->mOuterRadius.changed(prevFrame, curFrame) ||
                mData->mInnerRoundness.changed(prevFrame, curFrame) ||
                mData->mOuterRoundness.changed(prevFrame, curFrame) ||
-               mData->mRotation.changed(prevFrame, curFrame)) ? true : false;
+               mData->mRotation.changed(prevFrame, curFrame));
    }
 };
 
@@ -410,16 +409,15 @@ public:
    void addPathItems(std::vector<LOTPathDataItem *> &list, size_t startOffset);
    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) override;
    void renderList(std::vector<VDrawable *> &list) final;
+   ContentType type() const final {return ContentType::Paint;}
 protected:
-   virtual void updateContent(int frameNo) = 0;
-   virtual void updateRenderNode();
-   inline float parentAlpha() const {return mParentAlpha;}
+   virtual void updateContent(int frameNo, const VMatrix &matrix, float alpha) = 0;
+private:
+   void updateRenderNode();
 protected:
    std::vector<LOTPathDataItem *>   mPathItems;
    LOTDrawable                      mDrawable;
    VPath                            mPath;
-   float                            mParentAlpha{1.0f};
-   int                              mFrameNo{-1};
    DirtyFlag                        mFlag;
    bool                             mStaticContent;
    bool                             mRenderNodeUpdate{true};
@@ -430,12 +428,10 @@ class LOTFillItem : public LOTPaintDataItem
 public:
    explicit LOTFillItem(LOTFillData *data);
 protected:
-   void updateContent(int frameNo) final;
-   void updateRenderNode() final;
+   void updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) final;
 private:
    LOTProxyModel<LOTFillData> mModel;
-   VColor                     mColor;
 };
 
 class LOTGFillItem : public LOTPaintDataItem
@@ -443,13 +439,10 @@ class LOTGFillItem : public LOTPaintDataItem
 public:
    explicit LOTGFillItem(LOTGFillData *data);
 protected:
-   void updateContent(int frameNo) final;
-   void updateRenderNode() final;
+   void updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
 private:
    LOTGFillData                 *mData;
    std::unique_ptr<VGradient>    mGradient;
-   float                         mAlpha{1.0};
-   FillRule                      mFillRule{FillRule::Winding};
 };
 
 class LOTStrokeItem : public LOTPaintDataItem
@@ -457,14 +450,10 @@ class LOTStrokeItem : public LOTPaintDataItem
 public:
    explicit LOTStrokeItem(LOTStrokeData *data);
 protected:
-   void updateContent(int frameNo) final;
-   void updateRenderNode() final;
+   void updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) final;
 private:
    LOTProxyModel<LOTStrokeData> mModel;
-   VColor                       mColor;
-   float                        mWidth{0};
-   std::vector<float>           mDashInfo;
 };
 
 class LOTGStrokeItem : public LOTPaintDataItem
@@ -472,18 +461,10 @@ class LOTGStrokeItem : public LOTPaintDataItem
 public:
    explicit LOTGStrokeItem(LOTGStrokeData *data);
 protected:
-   void updateContent(int frameNo) final;
-   void updateRenderNode() final;
+   void updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
 private:
    LOTGStrokeData               *mData;
    std::unique_ptr<VGradient>    mGradient;
-   CapStyle                      mCap{CapStyle::Flat};
-   JoinStyle                     mJoin{JoinStyle::Miter};
-   float                         mMiterLimit{0};
-   VColor                        mColor;
-   float                         mAlpha{1.0};
-   float                         mWidth{0};
-   std::vector<float>            mDashInfo;
 };
 
 
@@ -492,8 +473,9 @@ private:
 class LOTTrimItem : public LOTContentItem
 {
 public:
-   LOTTrimItem(LOTTrimData *data);
+   explicit LOTTrimItem(LOTTrimData *data);
    void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) final;
+   ContentType type() const final {return ContentType::Trim;}
    void update();
    void addPathItems(std::vector<LOTPathDataItem *> &list, size_t startOffset);
 private: