rlottie: added a dedicated pass to preprocess the render nodes
authorsubhransu mohanty <sub.mohanty@samsung.com>
Mon, 28 Oct 2019 10:47:07 +0000 (19:47 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Mon, 11 Nov 2019 20:58:15 +0000 (05:58 +0900)
src/lottie/lottieitem.cpp
src/lottie/lottieitem.h

index e195750..9ee0b5c 100644 (file)
@@ -149,12 +149,8 @@ bool LOTCompItem::render(const rlottie::Surface &surface)
 
     /* schedule all preprocess task for this frame at once.
      */
-    mDrawableList.clear();
-    mRootLayer->renderList(mDrawableList);
     VRect clip(0, 0, int(surface.drawRegionWidth()), int(surface.drawRegionHeight()));
-    for (auto &e : mDrawableList) {
-        e->preprocess(clip);
-    }
+    mRootLayer->preprocess(clip);
 
     mPainter.begin(&mSurface);
     // set sub surface area for drawing.
@@ -184,7 +180,6 @@ void LOTMaskItem::update(int frameNo, const VMatrix &            parentMatrix,
     mFinalPath.clone(mLocalPath);
     mFinalPath.transform(parentMatrix);
 
-    mRasterizer.rasterize(mFinalPath);
     mRasterRequest = true;
 }
 
@@ -199,6 +194,11 @@ VRle LOTMaskItem::rle()
     return mRasterizer.rle();
 }
 
+void LOTMaskItem::preprocess(const VRect &clip)
+{
+    if (mRasterRequest) mRasterizer.rasterize(mFinalPath, FillRule::Winding, clip);
+}
+
 void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask,
                           const VRle &matteRle)
 {
@@ -242,6 +242,14 @@ void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask,
     }
 }
 
+void LOTLayerMaskItem::preprocess(const VRect &clip)
+{
+    for (auto &i : mMasks) {
+        i.preprocess(clip);
+    }
+}
+
+
 LOTLayerMaskItem::LOTLayerMaskItem(LOTLayerData *layerData)
 {
     if (!layerData->mExtra) return;
@@ -413,6 +421,17 @@ bool LOTLayerItem::visible() const
             frameNo() < mLayerData->outFrame());
 }
 
+void LOTLayerItem::preprocess(const VRect& clip)
+{
+    // layer dosen't contribute to the frame
+    if (skipRendering()) return;
+
+    // preprocess layer masks
+    if (mLayerMask) mLayerMask->preprocess(clip);
+
+    preprocessStage(clip);
+}
+
 LOTCompLayerItem::LOTCompLayerItem(LOTLayerData *layerModel)
     : LOTLayerItem(layerModel)
 {
@@ -564,7 +583,15 @@ void LOTClipperItem::update(const VMatrix &matrix)
     mPath.reset();
     mPath.addRect(VRectF(0, 0, mSize.width(), mSize.height()));
     mPath.transform(matrix);
-    mRasterizer.rasterize(mPath);
+    mRasterRequest = true;
+}
+
+void LOTClipperItem::preprocess(const VRect &clip)
+{
+    if (mRasterRequest)
+        mRasterizer.rasterize(mPath, FillRule::Winding, clip);
+
+    mRasterRequest = false;
 }
 
 VRle LOTClipperItem::rle(const VRle& mask)
@@ -590,9 +617,33 @@ void LOTCompLayerItem::updateContent()
     }
 }
 
+void LOTCompLayerItem::preprocessStage(const VRect &clip)
+{
+    // if layer has clipper
+    if (mClipper) mClipper->preprocess(clip);
+
+    LOTLayerItem *matte = nullptr;
+    for (const auto &layer : mLayers) {
+        if (layer->hasMatte()) {
+            matte = layer.get();
+        } else {
+            if (layer->visible()) {
+                if (matte) {
+                    if (matte->visible()) {
+                        layer->preprocess(clip);
+                        matte->preprocess(clip);
+                    }
+                } else {
+                    layer->preprocess(clip);
+                }
+            }
+            matte = nullptr;
+        }
+    }
+}
 void LOTCompLayerItem::renderList(std::vector<VDrawable *> &list)
 {
-    if (!visible() || vIsZero(combinedAlpha())) return;
+    if (skipRendering()) return;
 
     LOTLayerItem *matte = nullptr;
     for (const auto &layer : mLayers) {
@@ -639,9 +690,14 @@ void LOTSolidLayerItem::updateContent()
     }
 }
 
+void LOTSolidLayerItem::preprocessStage(const VRect& clip)
+{
+    mRenderNode.preprocess(clip);
+}
+
 void LOTSolidLayerItem::renderList(std::vector<VDrawable *> &list)
 {
-    if (!visible() || vIsZero(combinedAlpha())) return;
+    if (skipRendering()) return;
 
     list.push_back(&mRenderNode);
 }
@@ -675,9 +731,14 @@ void LOTImageLayerItem::updateContent()
     }
 }
 
+void LOTImageLayerItem::preprocessStage(const VRect& clip)
+{
+    mRenderNode.preprocess(clip);
+}
+
 void LOTImageLayerItem::renderList(std::vector<VDrawable *> &list)
 {
-    if (!visible() || vIsZero(combinedAlpha())) return;
+    if (skipRendering()) return;
 
     list.push_back(&mRenderNode);
 }
@@ -766,9 +827,18 @@ void LOTShapeLayerItem::updateContent()
     }
 }
 
+void LOTShapeLayerItem::preprocessStage(const VRect& clip)
+{
+    mDrawableList.clear();
+    mRoot->renderList(mDrawableList);
+
+    for (auto &drawable : mDrawableList) drawable->preprocess(clip);
+
+}
+
 void LOTShapeLayerItem::renderList(std::vector<VDrawable *> &list)
 {
-    if (!visible() || vIsZero(combinedAlpha())) return;
+    if (skipRendering()) return;
     mRoot->renderList(list);
 }
 
index 6b155ec..1626a27 100644 (file)
@@ -91,12 +91,14 @@ class LOTClipperItem
 public:
     explicit LOTClipperItem(VSize size): mSize(size){}
     void update(const VMatrix &matrix);
+    void preprocess(const VRect &clip);
     VRle rle(const VRle& mask);
 public:
     VSize                    mSize;
     VPath                    mPath;
     VRle                     mMaskedRle;
     VRasterizer              mRasterizer;
+    bool                     mRasterRequest{false};
 };
 
 typedef vFlag<DirtyFlagBit> DirtyFlag;
@@ -123,6 +125,7 @@ public:
    bool complexContent() const {return mComplexContent;}
    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 void render(VPainter *painter, const VRle &mask, const VRle &matteRle);
    bool hasMatte() { if (mLayerData->mMatteType == MatteType::None) return false; return true; }
@@ -137,6 +140,7 @@ public:
    virtual bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value);
    VBitmap& bitmap() {return mRenderBuffer;}
 protected:
+   virtual void preprocessStage(const VRect& clip) = 0;
    virtual void updateContent() = 0;
    inline VMatrix combinedMatrix() const {return mCombinedMatrix;}
    inline int frameNo() const {return mFrameNo;}
@@ -144,6 +148,7 @@ protected:
    inline bool isStatic() const {return mLayerData->isStatic();}
    float opacity(int frameNo) const {return mLayerData->opacity(frameNo);}
    inline DirtyFlag flag() const {return mDirtyFlag;}
+   bool skipRendering() const {return (!visible() || vIsZero(combinedAlpha()));}
 protected:
    std::vector<VDrawable *>                    mDrawableList;
    std::unique_ptr<LOTLayerMaskItem>           mLayerMask;
@@ -162,11 +167,13 @@ 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;
 protected:
+   void preprocessStage(const VRect& clip) final;
    void updateContent() final;
 private:
     void renderHelper(VPainter *painter, const VRle &mask, const VRle &matteRle);
@@ -183,6 +190,7 @@ public:
    explicit LOTSolidLayerItem(LOTLayerData *layerData);
    void buildLayerNode() final;
 protected:
+   void preprocessStage(const VRect& clip) final;
    void updateContent() final;
    void renderList(std::vector<VDrawable *> &list) final;
 private:
@@ -200,6 +208,7 @@ public:
    void buildLayerNode() final;
    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) override;
 protected:
+   void preprocessStage(const VRect& clip) final;
    void updateContent() final;
    std::unique_ptr<LOTContentGroupItem> mRoot;
 };
@@ -209,6 +218,7 @@ class LOTNullLayerItem: public LOTLayerItem
 public:
    explicit LOTNullLayerItem(LOTLayerData *layerData);
 protected:
+   void preprocessStage(const VRect&) final {}
    void updateContent() final;
 };
 
@@ -218,6 +228,7 @@ public:
    explicit LOTImageLayerItem(LOTLayerData *layerData);
    void buildLayerNode() final;
 protected:
+   void preprocessStage(const VRect& clip) final;
    void updateContent() final;
    void renderList(std::vector<VDrawable *> &list) final;
 private:
@@ -232,6 +243,7 @@ public:
     void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag);
     LOTMaskData::Mode maskMode() const { return mData->mMode;}
     VRle rle();
+    void preprocess(const VRect &clip);
 public:
     LOTMaskData             *mData;
     float                    mCombinedAlpha{0};
@@ -252,6 +264,7 @@ public:
     void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag);
     bool isStatic() const {return mStatic;}
     VRle maskRle(const VRect &clipRect);
+    void preprocess(const VRect &clip);
 public:
     std::vector<LOTMaskItem>   mMasks;
     VRle                       mRle;