From 34c12f2d605b6b1b00038c38b6fc1ad28938ef8c Mon Sep 17 00:00:00 2001 From: "sub.mohanty@samsung.com" Date: Mon, 10 Dec 2018 22:10:46 +0900 Subject: [PATCH] lottie: refactor mask handling of layer to a separate LOTLayerMaskItem object. Change-Id: Ifdc588dd95dbd4f00f07d5f713c47212847941cd --- src/lottie/lottieitem.cpp | 85 ++++++++++++++++++++++++++++++----------------- src/lottie/lottieitem.h | 23 +++++++++++-- 2 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index 9bb61e7..dcf3f8b 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -138,8 +138,10 @@ bool LOTCompItem::render(const lottie::Surface &surface) } void LOTMaskItem::update(int frameNo, const VMatrix &parentMatrix, - float parentAlpha, const DirtyFlag &/*flag*/) + float parentAlpha, const DirtyFlag &flag) { + if (flag.testFlag(DirtyFlagBit::None) && mData->isStatic()) return; + if (mData->mShape.isStatic()) { if (mLocalPath.empty()) { mData->mShape.value(frameNo).toPath(mLocalPath); @@ -205,19 +207,19 @@ void LOTLayerItem::buildLayerNode() break; } } - if (hasMask()) { + if (mLayerMask) { mMasksCNode.clear(); - for (const auto &mask : mMasks) { + for (const auto &mask : mLayerMask->mMasks) { LOTMask cNode; - const std::vector &elm = mask->mFinalPath.elements(); - const std::vector & pts = mask->mFinalPath.points(); + const std::vector &elm = mask.mFinalPath.elements(); + const std::vector & pts = mask.mFinalPath.points(); const float *ptPtr = reinterpret_cast(pts.data()); const char * elmPtr = reinterpret_cast(elm.data()); cNode.mPath.ptPtr = ptPtr; cNode.mPath.ptCount = pts.size(); cNode.mPath.elmPtr = elmPtr; cNode.mPath.elmCount = elm.size(); - switch (mask->maskMode()) { + switch (mask.maskMode()) { case LOTMaskData::Mode::Add: cNode.mMode = MaskModeAdd; break; @@ -259,8 +261,8 @@ void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle renderList(mDrawableList); VRle mask; - if (hasMask()) { - mask = maskRle(painter->clipBoundingRect()); + if (mLayerMask) { + mask = mLayerMask->maskRle(painter->clipBoundingRect()); if (!inheritMask.empty()) mask = mask & inheritMask; // if resulting mask is empty then return. @@ -288,43 +290,66 @@ void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle } } -VRle LOTLayerItem::maskRle(const VRect &clipRect) +LOTLayerMaskItem::LOTLayerMaskItem(LOTLayerData *layerData) +{ + mMasks.reserve(layerData->mMasks.size()); + + for (auto &i : layerData->mMasks) { + mMasks.emplace_back(i.get()); + mStatic &= i->isStatic(); + } +} + +void LOTLayerMaskItem::update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag) +{ + if (flag.testFlag(DirtyFlagBit::None) && isStatic()) return; + + for (auto &i : mMasks) { + i.update(frameNo, parentMatrix, parentAlpha, flag); + } + mDirty = true; +} + +VRle LOTLayerMaskItem::maskRle(const VRect &clipRect) { + if (!mDirty) return mRle; + VRle rle; for (auto &i : mMasks) { - switch (i->maskMode()) { + switch (i.maskMode()) { case LOTMaskData::Mode::Add: { - rle = rle + i->rle(); + rle = rle + i.rle(); break; } case LOTMaskData::Mode::Substarct: { if (rle.empty() && !clipRect.empty()) rle = VRle::toRle(clipRect); - rle = rle - i->rle(); + rle = rle - i.rle(); break; } case LOTMaskData::Mode::Intersect: { - rle = rle & i->rle(); + rle = rle & i.rle(); break; } case LOTMaskData::Mode::Difference: { - rle = rle ^ i->rle(); + rle = rle ^ i.rle(); break; } default: break; } } - return rle; + + mRle = rle; + mDirty = false; + return mRle; } + LOTLayerItem::LOTLayerItem(LOTLayerData *layerData): mLayerData(layerData) { - if (mLayerData->mHasMask) { - for (auto &i : mLayerData->mMasks) { - mMasks.push_back(std::make_unique(i.get())); - } - } + if (mLayerData->mHasMask) + mLayerMask = std::make_unique(mLayerData); } void LOTLayerItem::updateStaticProperty() @@ -348,11 +373,6 @@ void LOTLayerItem::update(int frameNumber, const VMatrix &parentMatrix, m *= parentMatrix; float alpha = parentAlpha * opacity(frameNo()); - // 6. update the mask - if (hasMask()) { - for (auto &i : mMasks) i->update(frameNo(), m, alpha, mDirtyFlag); - } - // 3. update the dirty flag based on the change if (!mCombinedMatrix.fuzzyCompare(m)) { mDirtyFlag |= DirtyFlagBit::Matrix; @@ -363,13 +383,18 @@ void LOTLayerItem::update(int frameNumber, const VMatrix &parentMatrix, mCombinedMatrix = m; mCombinedAlpha = alpha; - // 4. if no parent property change and layer is static then nothing to do. + // 4. update the mask + if (mLayerMask) { + mLayerMask->update(frameNo(), m, alpha, mDirtyFlag); + } + + // 5. if no parent property change and layer is static then nothing to do. if ((flag() & DirtyFlagBit::None) && isStatic()) return; - // 5. update the content of the layer + // 6. update the content of the layer updateContent(); - // 6. reset the dirty flag + // 7. reset the dirty flag mDirtyFlag = DirtyFlagBit::None; } @@ -470,8 +495,8 @@ void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask, const } VRle mask; - if (hasMask()) { - mask = maskRle(painter->clipBoundingRect()); + if (mLayerMask) { + mask = mLayerMask->maskRle(painter->clipBoundingRect()); if (!inheritMask.empty()) mask = mask & inheritMask; // if resulting mask is empty then return. diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index f2680c4..737ce43 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -53,6 +53,8 @@ private: std::vector mDrawableList; }; +class LOTLayerMaskItem; + typedef vFlag DirtyFlag; class LOTLayerItem { @@ -81,13 +83,11 @@ protected: inline bool isStatic() const {return mStatic;} float opacity(int frameNo) const; inline DirtyFlag flag() const {return mDirtyFlag;} - VRle maskRle(const VRect &clipRect); - bool hasMask() const {return !mMasks.empty();} protected: std::vector mMasksCNode; std::unique_ptr mLayerCNode; std::vector mDrawableList; - std::vector> mMasks; + std::unique_ptr mLayerMask; LOTLayerData *mLayerData{nullptr}; LOTLayerItem *mParentLayer{nullptr}; LOTLayerItem *mPrecompLayer{nullptr}; @@ -167,6 +167,23 @@ public: VRle mRle; }; +/* + * Handels mask property of a layer item + */ +class LOTLayerMaskItem +{ +public: + LOTLayerMaskItem(LOTLayerData *layerData); + void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, const DirtyFlag &flag); + bool isStatic() const {return mStatic;} + VRle maskRle(const VRect &clipRect); +public: + std::vector mMasks; + VRle mRle; + bool mStatic{true}; + bool mDirty{true}; +}; + class LOTDrawable : public VDrawable { public: -- 2.7.4