rlottie/opt: refactor renderList() api to return a Span to optimize the LayerObject...
authorsubhransu mohanty <sub.mohanty@samsung.com>
Wed, 30 Oct 2019 00:19:36 +0000 (09:19 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Wed, 13 Nov 2019 00:44:45 +0000 (09:44 +0900)
previously renderList() was returning a vector by keeping a vector object which was adding to
the overal size of the layer objects. by changing to a simple span object now only shpelayer has to keep
the vector and rest of the layer object types don't have to.

src/lottie/lottieitem.cpp
src/lottie/lottieitem.h
src/lottie/lottieitem_capi.cpp

index 9ee0b5c..6372c59 100644 (file)
@@ -202,8 +202,9 @@ void LOTMaskItem::preprocess(const VRect &clip)
 void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask,
                           const VRle &matteRle)
 {
-    mDrawableList.clear();
-    renderList(mDrawableList);
+    auto renderlist = renderList();
+
+    if (renderlist.empty()) return;
 
     VRle mask;
     if (mLayerMask) {
@@ -215,7 +216,7 @@ void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask,
         mask = inheritMask;
     }
 
-    for (auto &i : mDrawableList) {
+    for (auto &i : renderlist) {
         painter->setBrush(i->mBrush);
         VRle rle = i->rle();
         if (matteRle.empty()) {
@@ -641,33 +642,11 @@ void LOTCompLayerItem::preprocessStage(const VRect &clip)
         }
     }
 }
-void LOTCompLayerItem::renderList(std::vector<VDrawable *> &list)
-{
-    if (skipRendering()) return;
-
-    LOTLayerItem *matte = nullptr;
-    for (const auto &layer : mLayers) {
-        if (layer->hasMatte()) {
-            matte = layer.get();
-        } else {
-            if (layer->visible()) {
-                if (matte) {
-                    if (matte->visible()) {
-                        layer->renderList(list);
-                        matte->renderList(list);
-                    }
-                } else {
-                    layer->renderList(list);
-                }
-            }
-            matte = nullptr;
-        }
-    }
-}
 
 LOTSolidLayerItem::LOTSolidLayerItem(LOTLayerData *layerData)
     : LOTLayerItem(layerData)
 {
+    mDrawableList = &mRenderNode;
 }
 
 void LOTSolidLayerItem::updateContent()
@@ -695,16 +674,18 @@ void LOTSolidLayerItem::preprocessStage(const VRect& clip)
     mRenderNode.preprocess(clip);
 }
 
-void LOTSolidLayerItem::renderList(std::vector<VDrawable *> &list)
+DrawableList LOTSolidLayerItem::renderList()
 {
-    if (skipRendering()) return;
+    if (skipRendering()) return {};
 
-    list.push_back(&mRenderNode);
+    return {&mDrawableList , 1};
 }
 
 LOTImageLayerItem::LOTImageLayerItem(LOTLayerData *layerData)
     : LOTLayerItem(layerData)
 {
+    mDrawableList = &mRenderNode;
+
     if (!mLayerData->asset()) return;
 
     mTexture.mBitmap = mLayerData->asset()->bitmap();
@@ -736,11 +717,11 @@ void LOTImageLayerItem::preprocessStage(const VRect& clip)
     mRenderNode.preprocess(clip);
 }
 
-void LOTImageLayerItem::renderList(std::vector<VDrawable *> &list)
+DrawableList LOTImageLayerItem::renderList()
 {
-    if (skipRendering()) return;
+    if (skipRendering()) return {};
 
-    list.push_back(&mRenderNode);
+    return {&mDrawableList , 1};
 }
 
 LOTNullLayerItem::LOTNullLayerItem(LOTLayerData *layerData)
@@ -836,10 +817,16 @@ void LOTShapeLayerItem::preprocessStage(const VRect& clip)
 
 }
 
-void LOTShapeLayerItem::renderList(std::vector<VDrawable *> &list)
+DrawableList LOTShapeLayerItem::renderList()
 {
-    if (skipRendering()) return;
-    mRoot->renderList(list);
+    if (skipRendering()) return {};
+
+    mDrawableList.clear();
+    mRoot->renderList(mDrawableList);
+
+    if (mDrawableList.empty()) return {};
+
+    return {mDrawableList.data() , mDrawableList.size()};
 }
 
 bool LOTContentGroupItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
index 1626a27..9c9934e 100644 (file)
@@ -78,10 +78,8 @@ private:
    VSize                                       mViewSize;
    LOTCompositionData                         *mCompData;
    std::unique_ptr<LOTLayerItem>               mRootLayer;
-   bool                                        mKeepAspectRatio{true};
    int                                         mCurFrameNo;
-   std::vector<LOTNode *>                      mRenderList;
-   std::vector<VDrawable *>                    mDrawableList;
+   bool                                        mKeepAspectRatio{true};
 };
 
 class LOTLayerMaskItem;
@@ -112,6 +110,38 @@ struct LOTCApiData
     std::vector<LOTNode *>        mCNodeList;
 };
 
+template< class T>
+class VSpan
+{
+public:
+    using reference         = T &;
+    using pointer           = T *;
+    using const_pointer     = T const *;
+    using const_reference   = T const &;
+    using index_type        = size_t;
+
+    using iterator          = pointer;
+    using const_iterator    = const_pointer;
+
+    VSpan() = default;
+    VSpan(pointer data, index_type size):_data(data), _size(size){}
+
+    constexpr pointer data() const noexcept {return _data; }
+    constexpr index_type size() const noexcept {return _size; }
+    constexpr bool empty() const noexcept { return size() == 0 ;}
+    constexpr iterator begin() const noexcept { return data(); }
+    constexpr iterator end() const noexcept {return data() + size() ;}
+    constexpr const_iterator cbegin() const noexcept {return  data();}
+    constexpr const_iterator cend() const noexcept { return data() + size();}
+    constexpr reference operator[]( index_type idx ) const { return *( data() + idx );}
+
+private:
+    pointer      _data{nullptr};
+    index_type   _size{0};
+};
+
+using DrawableList = VSpan<VDrawable *>;
+
 class LOTLayerItem
 {
 public:
@@ -126,7 +156,7 @@ public:
    virtual void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha);
    VMatrix matrix(int frameNo) const;
    void preprocess(const VRect& clip);
-   virtual void renderList(std::vector<VDrawable *> &){}
+   virtual DrawableList renderList(){ return {};}
    virtual void render(VPainter *painter, const VRle &mask, const VRle &matteRle);
    bool hasMatte() { if (mLayerData->mMatteType == MatteType::None) return false; return true; }
    MatteType matteType() const { return mLayerData->mMatteType;}
@@ -150,7 +180,6 @@ protected:
    inline DirtyFlag flag() const {return mDirtyFlag;}
    bool skipRendering() const {return (!visible() || vIsZero(combinedAlpha()));}
 protected:
-   std::vector<VDrawable *>                    mDrawableList;
    std::unique_ptr<LOTLayerMaskItem>           mLayerMask;
    LOTLayerData                               *mLayerData{nullptr};
    LOTLayerItem                               *mParentLayer{nullptr};
@@ -168,7 +197,6 @@ class LOTCompLayerItem: public LOTLayerItem
 public:
    explicit LOTCompLayerItem(LOTLayerData *layerData);
 
-   void renderList(std::vector<VDrawable *> &list)final;
    void render(VPainter *painter, const VRle &mask, const VRle &matteRle) final;
    void buildLayerNode() final;
    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) override;
@@ -189,12 +217,13 @@ class LOTSolidLayerItem: public LOTLayerItem
 public:
    explicit LOTSolidLayerItem(LOTLayerData *layerData);
    void buildLayerNode() final;
+   DrawableList renderList() final;
 protected:
    void preprocessStage(const VRect& clip) final;
    void updateContent() final;
-   void renderList(std::vector<VDrawable *> &list) final;
 private:
    LOTDrawable                  mRenderNode;
+   VDrawable                   *mDrawableList{nullptr}; //to work with the Span api
 };
 
 class LOTContentItem;
@@ -204,12 +233,13 @@ class LOTShapeLayerItem: public LOTLayerItem
 public:
    explicit LOTShapeLayerItem(LOTLayerData *layerData);
    static std::unique_ptr<LOTContentItem> createContentItem(LOTData *contentData);
-   void renderList(std::vector<VDrawable *> &list)final;
+   DrawableList renderList() final;
    void buildLayerNode() final;
    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) override;
 protected:
    void preprocessStage(const VRect& clip) final;
    void updateContent() final;
+   std::vector<VDrawable *>             mDrawableList;
    std::unique_ptr<LOTContentGroupItem> mRoot;
 };
 
@@ -227,13 +257,14 @@ class LOTImageLayerItem: public LOTLayerItem
 public:
    explicit LOTImageLayerItem(LOTLayerData *layerData);
    void buildLayerNode() final;
+   DrawableList renderList() final;
 protected:
    void preprocessStage(const VRect& clip) final;
    void updateContent() final;
-   void renderList(std::vector<VDrawable *> &list) final;
 private:
    LOTDrawable                  mRenderNode;
    VTexture                     mTexture;
+   VDrawable                   *mDrawableList{nullptr}; //to work with the Span api
 };
 
 class LOTMaskItem
index 295ed03..6242f43 100644 (file)
@@ -69,11 +69,10 @@ void LOTShapeLayerItem::buildLayerNode()
 {
     LOTLayerItem::buildLayerNode();
 
-    mDrawableList.clear();
-    renderList(mDrawableList);
+    auto renderlist = renderList();
 
     cnodes().clear();
-    for (auto &i : mDrawableList) {
+    for (auto &i : renderlist) {
         auto lotDrawable = static_cast<LOTDrawable *>(i);
         lotDrawable->sync();
         cnodes().push_back(lotDrawable->mCNode.get());
@@ -152,11 +151,10 @@ void LOTSolidLayerItem::buildLayerNode()
 {
     LOTLayerItem::buildLayerNode();
 
-    mDrawableList.clear();
-    renderList(mDrawableList);
+    auto renderlist = renderList();
 
     cnodes().clear();
-    for (auto &i : mDrawableList) {
+    for (auto &i : renderlist) {
         auto lotDrawable = static_cast<LOTDrawable *>(i);
         lotDrawable->sync();
         cnodes().push_back(lotDrawable->mCNode.get());
@@ -169,11 +167,10 @@ void LOTImageLayerItem::buildLayerNode()
 {
     LOTLayerItem::buildLayerNode();
 
-    mDrawableList.clear();
-    renderList(mDrawableList);
+    auto renderlist = renderList();
 
     cnodes().clear();
-    for (auto &i : mDrawableList) {
+    for (auto &i : renderlist) {
         auto lotDrawable = static_cast<LOTDrawable *>(i);
         lotDrawable->sync();