From: Michal Szczecinski Date: Thu, 6 Apr 2023 11:16:35 +0000 (+0200) Subject: Update color blending style in LottieItem X-Git-Tag: accepted/tizen/7.0/unified/20230526.164245~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=272130dbd9c1516eee854ff99bbcd77386b6435a;p=platform%2Fcore%2Fuifw%2Flottie-player.git Update color blending style in LottieItem This commit modifies the LottieItem rendering process to match Adobe After Effects blending style. Initially, the entire content of the layer is rendered to an intermediate buffer. Then, the buffer is rendered with applied alpha layer. Change-Id: Ic145daa83c7d8f3007e46f08cdfcc063d22526ae --- diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index 4cd22e4..f0e181a 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -165,6 +165,28 @@ bool renderer::Composition::render(const rlottie::Surface &surface) painter.setDrawRegion( VRect(int(surface.drawRegionPosX()), int(surface.drawRegionPosY()), int(surface.drawRegionWidth()), int(surface.drawRegionHeight()))); + + // layer surface should be created if it is not created already or its size + // is changed. + bool isLayerSurfaceCreated = mSurfaceCache.is_layer_surface_created(); + bool isLayerSurfaceSizeChanged = + isLayerSurfaceCreated && + (mSurfaceCache.get_layer_surface()->width() != surface.width() || + mSurfaceCache.get_layer_surface()->height() != surface.height()); + + if (!isLayerSurfaceCreated || isLayerSurfaceSizeChanged) { + if (isLayerSurfaceCreated && isLayerSurfaceSizeChanged) + mSurfaceCache.delete_layer_surface(); + + mSurfaceCache.create_layer_surface(surface.width(), surface.height(), + VBitmap::Format::ARGB32_Premultiplied); + + // set layer draw region + mSurfaceCache.get_layer_painter()->setDrawRegion( + VRect(int(surface.drawRegionPosX()), int(surface.drawRegionPosY()), + int(surface.drawRegionWidth()), int(surface.drawRegionHeight()))); + } + mRootLayer->render(&painter, {}, {}, mSurfaceCache); painter.end(); return true; @@ -214,7 +236,7 @@ void renderer::Mask::preprocess(const VRect &clip) } void renderer::Layer::render(VPainter *painter, const VRle &inheritMask, - const VRle &matteRle, SurfaceCache &) + const VRle &matteRle, SurfaceCache &cache) { auto renderlist = renderList(); @@ -230,31 +252,42 @@ void renderer::Layer::render(VPainter *painter, const VRle &inheritMask, mask = inheritMask; } + VPainter *usedPainter = painter; + + if (cache.get_layer_painter() != nullptr) { + usedPainter = cache.get_layer_painter(); + usedPainter->begin(cache.get_layer_surface()); + } + for (auto &i : renderlist) { - painter->setBrush(i->mBrush); + usedPainter->setBrush(i->mBrush); VRle rle = i->rle(); if (matteRle.empty()) { if (mask.empty()) { // no mask no matte - painter->drawRle(VPoint(), rle); + usedPainter->drawRle(VPoint(), rle); } else { // only mask - painter->drawRle(rle, mask); + usedPainter->drawRle(rle, mask); } - } else { if (!mask.empty()) rle = rle & mask; if (rle.empty()) continue; if (matteType() == model::MatteType::AlphaInv) { rle = rle - matteRle; - painter->drawRle(VPoint(), rle); + usedPainter->drawRle(VPoint(), rle); } else { // render with matteRle as clip. - painter->drawRle(rle, matteRle); + usedPainter->drawRle(rle, matteRle); } } } + + if (cache.get_layer_painter() != nullptr) { + usedPainter->end(); + painter->drawBitmap(VPoint(), *cache.get_layer_surface(), mCombinedAlpha * 255.0f); + } } void renderer::LayerMask::preprocess(const VRect &clip) @@ -1238,9 +1271,9 @@ renderer::Fill::Fill(model::Fill *data) mDrawable.setName(mModel.name()); } -bool renderer::Fill::updateContent(int frameNo, const VMatrix &, float alpha) +bool renderer::Fill::updateContent(int frameNo, const VMatrix &, float) { - auto combinedAlpha = alpha * mModel.opacity(frameNo); + auto combinedAlpha = mModel.opacity(frameNo); auto color = mModel.color(frameNo).toColor(combinedAlpha); VBrush brush(color); @@ -1284,9 +1317,9 @@ renderer::Stroke::Stroke(model::Stroke *data) static vthread_local std::vector Dash_Vector; bool renderer::Stroke::updateContent(int frameNo, const VMatrix &matrix, - float alpha) + float) { - auto combinedAlpha = alpha * mModel.opacity(frameNo); + auto combinedAlpha = mModel.opacity(frameNo); auto color = mModel.color(frameNo).toColor(combinedAlpha); VBrush brush(color); diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index 001ce66..587f10b 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -106,9 +106,31 @@ public: } void release_surface(VBitmap &surface) { mCache.push_back(surface); } + bool is_layer_surface_created() const { return mIsLayerBitmapCreated; } + void create_layer_surface(size_t width, size_t height, VBitmap::Format format) + { + if (mIsLayerBitmapCreated) return; + + mLayerBitmap = std::make_unique(width, height, format); + mBitmapPainter = std::make_unique(mLayerBitmap.get()); + mIsLayerBitmapCreated = true; + } + void delete_layer_surface() + { + if (!mIsLayerBitmapCreated) return; + + mLayerBitmap.reset(); + mBitmapPainter.reset(); + mIsLayerBitmapCreated = false; + } + VPainter* get_layer_painter() const { return mBitmapPainter.get(); } + VBitmap* get_layer_surface() const { return mLayerBitmap.get(); } private: std::vector mCache; + std::unique_ptr mLayerBitmap{nullptr}; + std::unique_ptr mBitmapPainter{nullptr}; + bool mIsLayerBitmapCreated{false}; }; class Drawable final : public VDrawable {