From 99e93aadd1a0cd62bdbada6d9749229b8fc07529 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Thu, 9 May 2024 01:15:45 +0400 Subject: [PATCH] Lottie: optimization --- .../Sources/ViewController.swift | 3 +- .../CompLayers/PreCompositionLayer.hpp | 185 ++++++++---------- .../CompLayers/ShapeCompositionLayer.cpp | 60 +++--- .../MainThreadAnimationLayer.hpp | 59 +++--- 4 files changed, 145 insertions(+), 162 deletions(-) diff --git a/Tests/LottieMetalTest/Sources/ViewController.swift b/Tests/LottieMetalTest/Sources/ViewController.swift index 5c937dfd33..12c75e22e7 100644 --- a/Tests/LottieMetalTest/Sources/ViewController.swift +++ b/Tests/LottieMetalTest/Sources/ViewController.swift @@ -77,7 +77,8 @@ private final class ReferenceCompareTest { let _ = await cacheReferenceAnimation(baseCachePath: baseCachePath, width: sizeMapping[fileName] ?? defaultSize, path: filePath, name: fileName) } - var continueFromName: String? = "5138957708585599529.json" + var continueFromName: String? + //continueFromName = "1258816259754282.json" let _ = await processAnimationFolderAsync(basePath: bundlePath, path: "", stopOnFailure: true, process: { path, name, alwaysDraw in if let continueFromNameValue = continueFromName { diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp index 58f27deedf..6242d289d1 100644 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp +++ b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp @@ -102,19 +102,6 @@ public: virtual std::shared_ptr renderTreeNode() override { if (!_renderTreeNode) { - _renderTreeNode = std::make_shared( - CGRect(0.0, 0.0, 0.0, 0.0), - Vector2D(0.0, 0.0), - CATransform3D::identity(), - 1.0, - false, - false, - nullptr, - std::vector>(), - nullptr, - false - ); - _contentsTreeNode = std::make_shared( CGRect(0.0, 0.0, 0.0, 0.0), Vector2D(0.0, 0.0), @@ -127,104 +114,72 @@ public: nullptr, false ); - } - - if (_contentsLayer->isHidden()) { - return nullptr; - } - - std::shared_ptr maskNode; - bool invertMask = false; - if (_matteLayer) { - maskNode = _matteLayer->renderTreeNode(); - if (maskNode && _matteType.has_value() && _matteType.value() == MatteType::Invert) { - invertMask = true; + + std::vector> subnodes; + subnodes.push_back(_contentsTreeNode); + + std::shared_ptr maskNode; + bool invertMask = false; + if (_matteLayer) { + maskNode = _matteLayer->renderTreeNode(); + if (maskNode && _matteType.has_value() && _matteType.value() == MatteType::Invert) { + invertMask = true; + } } + + _renderTreeNode = std::make_shared( + CGRect(0.0, 0.0, 0.0, 0.0), + Vector2D(0.0, 0.0), + CATransform3D::identity(), + 1.0, + false, + false, + nullptr, + subnodes, + maskNode, + invertMask + ); + + std::vector> renderTreeSubnodes; + for (const auto &animationLayer : _animationLayers) { + bool found = false; + for (const auto &sublayer : contentsLayer()->sublayers()) { + if (animationLayer == sublayer) { + found = true; + break; + } + } + if (found) { + auto node = animationLayer->renderTreeNode(); + if (node) { + renderTreeSubnodes.push_back(node); + } + } + } + + std::vector> renderTreeValue; + auto renderTreeContentItem = std::make_shared( + CGRect(0.0, 0.0, 0.0, 0.0), + Vector2D(0.0, 0.0), + CATransform3D::identity(), + 1.0, + false, + false, + nullptr, + renderTreeSubnodes, + nullptr, + false + ); + if (renderTreeContentItem) { + renderTreeValue.push_back(renderTreeContentItem); + } + + _contentsTreeNode->_subnodes = renderTreeValue; } - std::vector> renderTreeValue; - auto renderTreeContentItem = renderTree(); - if (renderTreeContentItem) { - renderTreeValue.push_back(renderTreeContentItem); - } - - std::vector> subnodes; - - _contentsTreeNode->_bounds = _contentsLayer->bounds(); - _contentsTreeNode->_position = _contentsLayer->position(); - _contentsTreeNode->_transform = _contentsLayer->transform(); - _contentsTreeNode->_alpha = _contentsLayer->opacity(); - _contentsTreeNode->_masksToBounds = _contentsLayer->masksToBounds(); - _contentsTreeNode->_isHidden = _contentsLayer->isHidden(); - _contentsTreeNode->_subnodes = renderTreeValue; - - subnodes.push_back(_contentsTreeNode); - /*subnodes.push_back(std::make_shared( - _contentsLayer->bounds(), - _contentsLayer->position(), - _contentsLayer->transform(), - _contentsLayer->opacity(), - _contentsLayer->masksToBounds(), - _contentsLayer->isHidden(), - nullptr, - renderTreeValue, - nullptr, - false - ));*/ - - assert(opacity() == 1.0); - assert(!isHidden()); - assert(!masksToBounds()); - assert(transform().isIdentity()); - assert(position() == Vector2D::Zero()); - - _renderTreeNode->_bounds = bounds(); - _renderTreeNode->_position = position(); - _renderTreeNode->_transform = transform(); - _renderTreeNode->_alpha = opacity(); - _renderTreeNode->_masksToBounds = masksToBounds(); - _renderTreeNode->_isHidden = isHidden(); - _renderTreeNode->_subnodes = subnodes; - _renderTreeNode->_mask = maskNode; - _renderTreeNode->_invertMask = invertMask; - return _renderTreeNode; } - std::shared_ptr renderTree() { - std::vector> result; - - for (const auto &animationLayer : _animationLayers) { - bool found = false; - for (const auto &sublayer : contentsLayer()->sublayers()) { - if (animationLayer == sublayer) { - found = true; - break; - } - } - if (found) { - auto node = animationLayer->renderTreeNode(); - if (node) { - result.push_back(node); - } - } - } - - std::vector> subnodes; - return std::make_shared( - CGRect(0.0, 0.0, 0.0, 0.0), - Vector2D(0.0, 0.0), - CATransform3D::identity(), - 1.0, - false, - false, - nullptr, - result, - nullptr, - false - ); - } - virtual void updateRenderTree() override { if (_matteLayer) { _matteLayer->updateRenderTree(); @@ -242,6 +197,26 @@ public: animationLayer->updateRenderTree(); } } + + assert(opacity() == 1.0); + assert(!isHidden()); + assert(!masksToBounds()); + assert(transform().isIdentity()); + assert(position() == Vector2D::Zero()); + + _contentsTreeNode->_bounds = _contentsLayer->bounds(); + _contentsTreeNode->_position = _contentsLayer->position(); + _contentsTreeNode->_transform = _contentsLayer->transform(); + _contentsTreeNode->_alpha = _contentsLayer->opacity(); + _contentsTreeNode->_masksToBounds = _contentsLayer->masksToBounds(); + _contentsTreeNode->_isHidden = _contentsLayer->isHidden(); + + _renderTreeNode->_bounds = bounds(); + _renderTreeNode->_position = position(); + _renderTreeNode->_transform = transform(); + _renderTreeNode->_alpha = opacity(); + _renderTreeNode->_masksToBounds = masksToBounds(); + _renderTreeNode->_isHidden = isHidden(); } private: diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.cpp index a7b68a0506..bc23bcf9b3 100644 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.cpp +++ b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.cpp @@ -1295,19 +1295,6 @@ std::shared_ptr ShapeCompositionLayer::renderTreeNode() { } if (!_renderTreeNode) { - _renderTreeNode = std::make_shared( - CGRect(0.0, 0.0, 0.0, 0.0), - Vector2D(0.0, 0.0), - CATransform3D::identity(), - 1.0, - false, - false, - nullptr, - std::vector>(), - nullptr, - false - ); - std::vector> renderTreeValue; renderTreeValue.push_back(_contentTree->itemTree->renderTree()); @@ -1323,15 +1310,39 @@ std::shared_ptr ShapeCompositionLayer::renderTreeNode() { nullptr, false ); + + std::vector> subnodes; + subnodes.push_back(_contentsTreeNode); + + std::shared_ptr maskNode; + bool invertMask = false; + if (_matteLayer) { + maskNode = _matteLayer->renderTreeNode(); + if (maskNode && _matteType.has_value() && _matteType.value() == MatteType::Invert) { + invertMask = true; + } + } + + _renderTreeNode = std::make_shared( + CGRect(0.0, 0.0, 0.0, 0.0), + Vector2D(0.0, 0.0), + CATransform3D::identity(), + 1.0, + false, + false, + nullptr, + subnodes, + maskNode, + invertMask + ); } - std::shared_ptr maskNode; - bool invertMask = false; + return _renderTreeNode; +} + +void ShapeCompositionLayer::updateRenderTree() { if (_matteLayer) { - maskNode = _matteLayer->renderTreeNode(); - if (maskNode && _matteType.has_value() && _matteType.value() == MatteType::Invert) { - invertMask = true; - } + _matteLayer->updateRenderTree(); } _contentsTreeNode->_bounds = _contentsLayer->bounds(); @@ -1341,9 +1352,6 @@ std::shared_ptr ShapeCompositionLayer::renderTreeNode() { _contentsTreeNode->_masksToBounds = _contentsLayer->masksToBounds(); _contentsTreeNode->_isHidden = _contentsLayer->isHidden(); - std::vector> subnodes; - subnodes.push_back(_contentsTreeNode); - assert(position() == Vector2D::Zero()); assert(transform().isIdentity()); assert(opacity() == 1.0); @@ -1359,14 +1367,6 @@ std::shared_ptr ShapeCompositionLayer::renderTreeNode() { _renderTreeNode->_alpha = opacity(); _renderTreeNode->_masksToBounds = masksToBounds(); _renderTreeNode->_isHidden = isHidden(); - _renderTreeNode->_subnodes = subnodes; - _renderTreeNode->_mask = maskNode; - _renderTreeNode->_invertMask = invertMask; - - return _renderTreeNode; -} - -void ShapeCompositionLayer::updateRenderTree() { } } diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp index cbd9811be6..687be55199 100644 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp +++ b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp @@ -219,38 +219,43 @@ public: } virtual std::shared_ptr renderTreeNode() { - std::vector> subnodes; - for (const auto &animationLayer : _animationLayers) { - bool found = false; - for (const auto &sublayer : sublayers()) { - if (animationLayer == sublayer) { - found = true; - break; - } - } - if (found) { - auto node = animationLayer->renderTreeNode(); - if (node) { - subnodes.push_back(node); + if (!_renderTreeNode) { + std::vector> subnodes; + for (const auto &animationLayer : _animationLayers) { + bool found = false; + for (const auto &sublayer : sublayers()) { + if (animationLayer == sublayer) { + found = true; + break; + } + } + if (found) { + auto node = animationLayer->renderTreeNode(); + if (node) { + subnodes.push_back(node); + } } } + _renderTreeNode = std::make_shared( + bounds(), + position(), + CATransform3D::identity(), + 1.0, + false, + false, + nullptr, + subnodes, + nullptr, + false + ); } - return std::make_shared( - bounds(), - position(), - CATransform3D::identity(), - 1.0, - false, - false, - nullptr, - subnodes, - nullptr, - false - ); + updateRenderTree(); + + return _renderTreeNode; } - virtual void updateRenderTree() { + void updateRenderTree() { for (const auto &animationLayer : _animationLayers) { bool found = false; for (const auto &sublayer : sublayers()) { @@ -282,6 +287,8 @@ private: std::shared_ptr _layerImageProvider; std::shared_ptr _layerTextProvider; std::shared_ptr _layerFontProvider; + + std::shared_ptr _renderTreeNode; }; }