diff --git a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/SoftwareLottieRenderer.mm b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/SoftwareLottieRenderer.mm index 90dd8f4c1e..367c31e5e2 100644 --- a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/SoftwareLottieRenderer.mm +++ b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/SoftwareLottieRenderer.mm @@ -651,13 +651,13 @@ CGRect getPathNativeBoundingBox(CGPathRef _Nonnull path) { } - (UIImage * _Nullable)renderForSize:(CGSize)size useReferenceRendering:(bool)useReferenceRendering { - LottieAnimation *animation = _animationContainer.animation; - std::shared_ptr renderNode = [_animationContainer internalGetRootRenderTreeNode]; - if (!renderNode) { + if (!useReferenceRendering) { return nil; } - if (!useReferenceRendering) { + LottieAnimation *animation = _animationContainer.animation; + std::shared_ptr renderNode = [_animationContainer internalGetRootRenderTreeNode]; + if (!renderNode) { return nil; } diff --git a/Tests/LottieMetalTest/Sources/ViewController.swift b/Tests/LottieMetalTest/Sources/ViewController.swift index ff9c7fe159..f4ca69a3c5 100644 --- a/Tests/LottieMetalTest/Sources/ViewController.swift +++ b/Tests/LottieMetalTest/Sources/ViewController.swift @@ -119,7 +119,7 @@ public final class ViewController: UIViewController { self.view.layer.addSublayer(MetalEngine.shared.rootLayer) - if !"".isEmpty { + if "".isEmpty { if #available(iOS 13.0, *) { self.test = ReferenceCompareTest(view: self.view) } diff --git a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift index c895bc1284..e4cf552b8e 100644 --- a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift +++ b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift @@ -802,11 +802,14 @@ final class ChatSendMessageContextScreenComponent: Component { } let standaloneReactionAnimation: AnimatedStickerNode + var effectiveScale: CGFloat = 1.0 #if targetEnvironment(simulator) standaloneReactionAnimation = DirectAnimatedStickerNode() + effectiveScale = 1.4 #else if "".isEmpty { standaloneReactionAnimation = DirectAnimatedStickerNode() + effectiveScale = 1.4 } else { standaloneReactionAnimation = LottieMetalAnimatedStickerNode() } @@ -823,7 +826,7 @@ final class ChatSendMessageContextScreenComponent: Component { let pathPrefix = component.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(customEffectResource.id) let source = AnimatedStickerResourceSource(account: component.context.account, resource: customEffectResource, fitzModifier: nil) - standaloneReactionAnimation.setup(source: source, width: Int(effectSize.width), height: Int(effectSize.height), playbackMode: .once, mode: .direct(cachePathPrefix: pathPrefix)) + standaloneReactionAnimation.setup(source: source, width: Int(effectSize.width * effectiveScale), height: Int(effectSize.height * effectiveScale), playbackMode: .once, mode: .direct(cachePathPrefix: pathPrefix)) standaloneReactionAnimation.completed = { [weak self, weak standaloneReactionAnimation] _ in guard let self else { return diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift index db570aef1f..85183d2692 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift @@ -5922,17 +5922,20 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI let pathPrefix = item.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(resource.id) let additionalAnimationNode: AnimatedStickerNode + var effectiveScale: CGFloat = 1.0 #if targetEnvironment(simulator) additionalAnimationNode = DirectAnimatedStickerNode() + effectiveScale = 1.4 #else if "".isEmpty { additionalAnimationNode = DirectAnimatedStickerNode() + effectiveScale = 1.4 } else { additionalAnimationNode = LottieMetalAnimatedStickerNode() } #endif additionalAnimationNode.updateLayout(size: animationSize) - additionalAnimationNode.setup(source: source, width: Int(animationSize.width), height: Int(animationSize.height), playbackMode: .once, mode: .direct(cachePathPrefix: pathPrefix)) + additionalAnimationNode.setup(source: source, width: Int(animationSize.width * effectiveScale), height: Int(animationSize.height * effectiveScale), playbackMode: .once, mode: .direct(cachePathPrefix: pathPrefix)) var animationFrame: CGRect if isStickerEffect { let offsetScale: CGFloat = 0.3 diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.cpp index db9e76ffc7..0765e43a96 100644 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.cpp +++ b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.cpp @@ -7,7 +7,6 @@ namespace lottie { InvertedMatteLayer::InvertedMatteLayer(std::shared_ptr inputMatte) : _inputMatte(inputMatte) { setBounds(inputMatte->bounds()); - setNeedsDisplay(true); addSublayer(_inputMatte); } diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp index c8a97b55dd..1d795079fe 100644 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp +++ b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp @@ -83,13 +83,15 @@ public: } void displayWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) { - _transformNode->updateTree(frame, forceUpdates); - bool layerVisible = isInRangeOrEqual(frame, _inFrame, _outFrame); - _contentsLayer->setTransform(_transformNode->globalTransform()); - _contentsLayer->setOpacity(_transformNode->opacity()); - _contentsLayer->setIsHidden(!layerVisible); + if (_transformNode->updateTree(frame, forceUpdates) || _contentsLayer->isHidden() != !layerVisible) { + _contentsLayer->setTransform(_transformNode->globalTransform()); + _contentsLayer->setOpacity(_transformNode->opacity()); + _contentsLayer->setIsHidden(!layerVisible); + + updateContentsLayerParameters(); + } /// Only update contents if current time is within the layers time bounds. if (layerVisible) { @@ -100,6 +102,9 @@ public: } } + virtual void updateContentsLayerParameters() { + } + virtual void displayContentsWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) { /// To be overridden by subclass } @@ -155,9 +160,6 @@ public: return nullptr; } - virtual void updateRenderTree(BezierPathsBoundingBoxContext &boundingBoxContext) { - } - public: std::shared_ptr const transformNode() const { return _transformNode; 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 aff1d21f8b..adacde6a4b 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 @@ -174,39 +174,9 @@ public: _contentsTreeNode->_subnodes = renderTreeValue; } - return _renderTreeNode; - } - - virtual void updateRenderTree(BezierPathsBoundingBoxContext &boundingBoxContext) override { - if (_matteLayer) { - _matteLayer->updateRenderTree(boundingBoxContext); - } - - for (const auto &animationLayer : _animationLayers) { - bool found = false; - for (const auto &sublayer : contentsLayer()->sublayers()) { - if (animationLayer == sublayer) { - found = true; - break; - } - } - if (found) { - animationLayer->updateRenderTree(boundingBoxContext); - } - } - - 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(); @@ -214,6 +184,14 @@ public: _renderTreeNode->_alpha = opacity(); _renderTreeNode->_masksToBounds = masksToBounds(); _renderTreeNode->_isHidden = isHidden(); + + return _renderTreeNode; + } + + virtual void updateContentsLayerParameters() override { + _contentsTreeNode->_transform = _contentsLayer->transform(); + _contentsTreeNode->_alpha = _contentsLayer->opacity(); + _contentsTreeNode->_isHidden = _contentsLayer->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 e9b2afb90e..8a7759e4b0 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 @@ -1388,27 +1388,22 @@ std::shared_ptr ShapeCompositionLayer::renderTreeNode(BezierPath ); } - return _renderTreeNode; -} - -void ShapeCompositionLayer::updateRenderTree(BezierPathsBoundingBoxContext &boundingBoxContext) { - if (_matteLayer) { - _matteLayer->updateRenderTree(boundingBoxContext); - } - _contentRenderTreeNode->_bounds = _contentsLayer->bounds(); _contentRenderTreeNode->_position = _contentsLayer->position(); - _contentRenderTreeNode->_transform = _contentsLayer->transform(); - _contentRenderTreeNode->_alpha = _contentsLayer->opacity(); _contentRenderTreeNode->_masksToBounds = _contentsLayer->masksToBounds(); - _contentRenderTreeNode->_isHidden = _contentsLayer->isHidden(); + + _renderTreeNode->_masksToBounds = masksToBounds(); _renderTreeNode->_bounds = bounds(); _renderTreeNode->_position = position(); - _renderTreeNode->_transform = transform(); - _renderTreeNode->_alpha = opacity(); - _renderTreeNode->_masksToBounds = masksToBounds(); - _renderTreeNode->_isHidden = isHidden(); + + return _renderTreeNode; +} + +void ShapeCompositionLayer::updateContentsLayerParameters() { + _contentRenderTreeNode->_transform = _contentsLayer->transform(); + _contentRenderTreeNode->_alpha = _contentsLayer->opacity(); + _contentRenderTreeNode->_isHidden = _contentsLayer->isHidden(); } } diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp index 27fed46a4e..2be2f974f2 100644 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp +++ b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp @@ -18,7 +18,8 @@ public: virtual void displayContentsWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) override; virtual std::shared_ptr renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) override; - virtual void updateRenderTree(BezierPathsBoundingBoxContext &boundingBoxContext) override; + void initializeContentsLayerParameters(); + virtual void updateContentsLayerParameters() override; private: std::shared_ptr _contentTree; 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 3d6f999f6b..7f95758791 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 @@ -90,7 +90,7 @@ public: _layerFontProvider->addTextLayers(textLayers); _layerFontProvider->reloadTexts(); - setNeedsDisplay(true); + renderTreeNode(); } void setRespectAnimationFrameRate(bool respectAnimationFrameRate) { @@ -249,26 +249,9 @@ public: ); } - updateRenderTree(); - return _renderTreeNode; } - void updateRenderTree() { - for (const auto &animationLayer : _animationLayers) { - bool found = false; - for (const auto &sublayer : sublayers()) { - if (animationLayer == sublayer) { - found = true; - break; - } - } - if (found) { - animationLayer->updateRenderTree(_boundingBoxContext); - } - } - } - private: // MARK: Internal diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp index 1d62e6c8d2..8c07963fcd 100644 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp +++ b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp @@ -185,9 +185,12 @@ public: return localUpdatesPermeateDownstream() ? hasUpstreamUpdates() || hasLocalUpdates() : hasUpstreamUpdates(); } - virtual void updateTree(double frame, bool forceUpdates) { - updateContents(frame, forceUpdates); - updateOutputs(frame, forceUpdates); + bool updateTree(double frame, bool forceUpdates) { + if (updateContents(frame, forceUpdates)) { + return updateOutputs(frame, forceUpdates); + } else { + return false; + } } /// The name of the Keypath diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.hpp index 9f9fd4641f..171c75f850 100644 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.hpp +++ b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.hpp @@ -45,13 +45,6 @@ public: } } - bool needsDisplay() const { - return _needsDisplay; - } - void setNeedsDisplay(bool needsDisplay) { - _needsDisplay = true; - } - virtual bool implementsDraw() const { return false; } @@ -148,7 +141,6 @@ private: private: CALayer *_superlayer = nullptr; std::vector> _sublayers; - bool _needsDisplay = false; bool _isHidden = false; float _opacity = 1.0; Vector2D _position = Vector2D(0.0, 0.0);