From 8ffae051ead225a7ba60cf2c875ba3e752e3a2f6 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Mon, 28 Oct 2019 19:47:07 +0900 Subject: [PATCH] rlottie: added a dedicated pass to preprocess the render nodes --- src/lottie/lottieitem.cpp | 92 +++++++++++++++++++++++++++++++++++++++++------ src/lottie/lottieitem.h | 13 +++++++ 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index e195750..9ee0b5c 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -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 &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 &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 &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 &list) { - if (!visible() || vIsZero(combinedAlpha())) return; + if (skipRendering()) return; mRoot->renderList(list); } diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index 6b155ec..1626a27 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -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 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 &){} 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 mDrawableList; std::unique_ptr mLayerMask; @@ -162,11 +167,13 @@ class LOTCompLayerItem: public LOTLayerItem { public: explicit LOTCompLayerItem(LOTLayerData *layerData); + void renderList(std::vector &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 &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 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 &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 mMasks; VRle mRle; -- 2.7.4