From fcfd0610f86bf2a3f96dbb8a1c9f717d6582e284 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Fri, 11 Jan 2019 10:16:07 +0900 Subject: [PATCH] lottie/render: Refactor matte rendering to support luma matte. Change-Id: I25d0855815fb3b4a3c5786c2b85692eac8220eb6 --- src/lottie/lottieitem.cpp | 107 ++++++++++++++++++++++++++++------------------ src/lottie/lottieitem.h | 7 ++- 2 files changed, 71 insertions(+), 43 deletions(-) diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index 667142c..b57833a 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -132,7 +132,7 @@ bool LOTCompItem::render(const lottie::Surface &surface) } VPainter painter(&bitmap); - mRootLayer->render(&painter, {}, {}, nullptr); + mRootLayer->render(&painter, {}, {}); return true; } @@ -250,20 +250,8 @@ void LOTLayerItem::buildLayerNode() } } -void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle &inheritMatte, LOTLayerItem *matteSource) +void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle &matteRle) { - VRle matteRle; - if (matteSource) { - mDrawableList.clear(); - matteSource->renderList(mDrawableList); - for (auto &i : mDrawableList) { - matteRle = matteRle + i->rle(); - } - if (!inheritMatte.empty()) - matteRle = matteRle & inheritMatte; - } else { - matteRle = inheritMatte; - } mDrawableList.clear(); renderList(mDrawableList); @@ -505,26 +493,8 @@ void LOTCompLayerItem::buildLayerNode() } } -void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle &inheritMatte, LOTLayerItem *matteSource) +void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask, const VRle &matteRle) { - VRle matteRle; - if (matteSource) { - mDrawableList.clear(); - matteSource->renderList(mDrawableList); - for (auto &i : mDrawableList) { - matteRle = matteRle + i->rle(); - } - - if (matteType() == MatteType::AlphaInv ) { - matteRle = VRle::toRle(painter->clipBoundingRect()) - matteRle; - } - - if (!inheritMatte.empty()) - matteRle = matteRle & inheritMatte; - } else { - matteRle = inheritMatte; - } - VRle mask; if (mLayerMask) { mask = mLayerMask->maskRle(painter->clipBoundingRect()); @@ -547,22 +517,77 @@ void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask, const LOTLayerItem *matteLayer = nullptr; for (const auto &layer : mLayers) { - if (!matteLayer && layer->hasMatte()) { + if (layer->hasMatte()) { + if (matteLayer) { + vWarning << "two consecutive layer has matter : not supported"; + } matteLayer = layer.get(); continue; } - if (matteLayer) { - if (matteLayer->visible() && layer->visible()) - matteLayer->render(painter, mask, matteRle, layer.get()); - matteLayer = nullptr; - } else { - if (layer->visible()) - layer->render(painter, mask, matteRle, nullptr); + if (layer->visible()) { + if (matteLayer) { + if (matteLayer->visible()) + renderMatteLayer(painter, mask, matteRle, matteLayer, layer.get()); + } else { + layer->render(painter, mask, matteRle); + } } + + matteLayer = nullptr; } } +void LOTCompLayerItem::renderMatteLayer(VPainter *painter, + const VRle &mask, + const VRle &matteRle, + LOTLayerItem *layer, + LOTLayerItem *src) +{ + VSize size = painter->clipBoundingRect().size(); + // Decide if we can use fast matte. + // 1. draw src layer to matte buffer + VPainter srcPainter; + VBitmap srcBitmap(size.width(), size.height(), VBitmap::Format::ARGB32_Premultiplied); + srcPainter.begin(&srcBitmap); + src->render(&srcPainter, mask, matteRle); + srcPainter.end(); + + // 2. draw layer to layer buffer + VPainter layerPainter; + VBitmap layerBitmap(size.width(), size.height(), VBitmap::Format::ARGB32_Premultiplied); + layerPainter.begin(&layerBitmap); + layer->render(&layerPainter, mask, matteRle); + + // 2.1update composition mode + switch (layer->matteType()) { + case MatteType::Alpha: + case MatteType::Luma: { + layerPainter.setCompositionMode(VPainter::CompositionMode::CompModeDestIn); + break; + } + case MatteType::AlphaInv: + case MatteType::LumaInv: { + layerPainter.setCompositionMode(VPainter::CompositionMode::CompModeDestOut); + break; + } + default: + break; + } + + //2.2 update srcBuffer if the matte is luma type + if (layer->matteType() == MatteType::Luma || + layer->matteType() == MatteType::LumaInv) { + srcBitmap.updateLuma(); + } + + // 2.3 draw src buffer as mask + layerPainter.drawBitmap(VPoint(), srcBitmap); + layerPainter.end(); + // 3. draw the result buffer into painter + painter->drawBitmap(VPoint(), layerBitmap); +} + void LOTClipperItem::update(const VMatrix &matrix) { mPath.reset(); diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index 47c816c..339473e 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -98,7 +98,7 @@ public: VMatrix matrix(int frameNo) const; virtual void renderList(std::vector &){} virtual void updateStaticProperty(); - virtual void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource); + 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;} bool visible() const; @@ -133,11 +133,14 @@ public: LOTCompLayerItem(LOTLayerData *layerData); void renderList(std::vector &list)final; void updateStaticProperty() final; - void render(VPainter *painter, const VRle &mask, const VRle &inheritMatte, LOTLayerItem *matteSource) final; + void render(VPainter *painter, const VRle &mask, const VRle &matteRle) final; void buildLayerNode() final; protected: void updateContent() final; private: + void renderMatteLayer(VPainter *painter, const VRle &inheritMask, const VRle &matteRle, + LOTLayerItem *layer, LOTLayerItem *src); +private: std::vector mLayersCNode; std::vector> mLayers; std::unique_ptr mClipper; -- 2.7.4