This commit is contained in:
Isaac 2024-05-18 11:22:53 +04:00
parent 5545bdd978
commit 8b20aea99b
12 changed files with 50 additions and 91 deletions

View File

@ -651,13 +651,13 @@ CGRect getPathNativeBoundingBox(CGPathRef _Nonnull path) {
} }
- (UIImage * _Nullable)renderForSize:(CGSize)size useReferenceRendering:(bool)useReferenceRendering { - (UIImage * _Nullable)renderForSize:(CGSize)size useReferenceRendering:(bool)useReferenceRendering {
LottieAnimation *animation = _animationContainer.animation; if (!useReferenceRendering) {
std::shared_ptr<lottie::RenderTreeNode> renderNode = [_animationContainer internalGetRootRenderTreeNode];
if (!renderNode) {
return nil; return nil;
} }
if (!useReferenceRendering) { LottieAnimation *animation = _animationContainer.animation;
std::shared_ptr<lottie::RenderTreeNode> renderNode = [_animationContainer internalGetRootRenderTreeNode];
if (!renderNode) {
return nil; return nil;
} }

View File

@ -119,7 +119,7 @@ public final class ViewController: UIViewController {
self.view.layer.addSublayer(MetalEngine.shared.rootLayer) self.view.layer.addSublayer(MetalEngine.shared.rootLayer)
if !"".isEmpty { if "".isEmpty {
if #available(iOS 13.0, *) { if #available(iOS 13.0, *) {
self.test = ReferenceCompareTest(view: self.view) self.test = ReferenceCompareTest(view: self.view)
} }

View File

@ -802,11 +802,14 @@ final class ChatSendMessageContextScreenComponent: Component {
} }
let standaloneReactionAnimation: AnimatedStickerNode let standaloneReactionAnimation: AnimatedStickerNode
var effectiveScale: CGFloat = 1.0
#if targetEnvironment(simulator) #if targetEnvironment(simulator)
standaloneReactionAnimation = DirectAnimatedStickerNode() standaloneReactionAnimation = DirectAnimatedStickerNode()
effectiveScale = 1.4
#else #else
if "".isEmpty { if "".isEmpty {
standaloneReactionAnimation = DirectAnimatedStickerNode() standaloneReactionAnimation = DirectAnimatedStickerNode()
effectiveScale = 1.4
} else { } else {
standaloneReactionAnimation = LottieMetalAnimatedStickerNode() standaloneReactionAnimation = LottieMetalAnimatedStickerNode()
} }
@ -823,7 +826,7 @@ final class ChatSendMessageContextScreenComponent: Component {
let pathPrefix = component.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(customEffectResource.id) let pathPrefix = component.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(customEffectResource.id)
let source = AnimatedStickerResourceSource(account: component.context.account, resource: customEffectResource, fitzModifier: nil) 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 standaloneReactionAnimation.completed = { [weak self, weak standaloneReactionAnimation] _ in
guard let self else { guard let self else {
return return

View File

@ -5922,17 +5922,20 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
let pathPrefix = item.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(resource.id) let pathPrefix = item.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(resource.id)
let additionalAnimationNode: AnimatedStickerNode let additionalAnimationNode: AnimatedStickerNode
var effectiveScale: CGFloat = 1.0
#if targetEnvironment(simulator) #if targetEnvironment(simulator)
additionalAnimationNode = DirectAnimatedStickerNode() additionalAnimationNode = DirectAnimatedStickerNode()
effectiveScale = 1.4
#else #else
if "".isEmpty { if "".isEmpty {
additionalAnimationNode = DirectAnimatedStickerNode() additionalAnimationNode = DirectAnimatedStickerNode()
effectiveScale = 1.4
} else { } else {
additionalAnimationNode = LottieMetalAnimatedStickerNode() additionalAnimationNode = LottieMetalAnimatedStickerNode()
} }
#endif #endif
additionalAnimationNode.updateLayout(size: animationSize) 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 var animationFrame: CGRect
if isStickerEffect { if isStickerEffect {
let offsetScale: CGFloat = 0.3 let offsetScale: CGFloat = 0.3

View File

@ -7,7 +7,6 @@ namespace lottie {
InvertedMatteLayer::InvertedMatteLayer(std::shared_ptr<CompositionLayer> inputMatte) : InvertedMatteLayer::InvertedMatteLayer(std::shared_ptr<CompositionLayer> inputMatte) :
_inputMatte(inputMatte) { _inputMatte(inputMatte) {
setBounds(inputMatte->bounds()); setBounds(inputMatte->bounds());
setNeedsDisplay(true);
addSublayer(_inputMatte); addSublayer(_inputMatte);
} }

View File

@ -83,13 +83,15 @@ public:
} }
void displayWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) { void displayWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) {
_transformNode->updateTree(frame, forceUpdates);
bool layerVisible = isInRangeOrEqual(frame, _inFrame, _outFrame); bool layerVisible = isInRangeOrEqual(frame, _inFrame, _outFrame);
_contentsLayer->setTransform(_transformNode->globalTransform()); if (_transformNode->updateTree(frame, forceUpdates) || _contentsLayer->isHidden() != !layerVisible) {
_contentsLayer->setOpacity(_transformNode->opacity()); _contentsLayer->setTransform(_transformNode->globalTransform());
_contentsLayer->setIsHidden(!layerVisible); _contentsLayer->setOpacity(_transformNode->opacity());
_contentsLayer->setIsHidden(!layerVisible);
updateContentsLayerParameters();
}
/// Only update contents if current time is within the layers time bounds. /// Only update contents if current time is within the layers time bounds.
if (layerVisible) { if (layerVisible) {
@ -100,6 +102,9 @@ public:
} }
} }
virtual void updateContentsLayerParameters() {
}
virtual void displayContentsWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) { virtual void displayContentsWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) {
/// To be overridden by subclass /// To be overridden by subclass
} }
@ -155,9 +160,6 @@ public:
return nullptr; return nullptr;
} }
virtual void updateRenderTree(BezierPathsBoundingBoxContext &boundingBoxContext) {
}
public: public:
std::shared_ptr<LayerTransformNode> const transformNode() const { std::shared_ptr<LayerTransformNode> const transformNode() const {
return _transformNode; return _transformNode;

View File

@ -174,39 +174,9 @@ public:
_contentsTreeNode->_subnodes = renderTreeValue; _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->_bounds = _contentsLayer->bounds();
_contentsTreeNode->_position = _contentsLayer->position(); _contentsTreeNode->_position = _contentsLayer->position();
_contentsTreeNode->_transform = _contentsLayer->transform();
_contentsTreeNode->_alpha = _contentsLayer->opacity();
_contentsTreeNode->_masksToBounds = _contentsLayer->masksToBounds(); _contentsTreeNode->_masksToBounds = _contentsLayer->masksToBounds();
_contentsTreeNode->_isHidden = _contentsLayer->isHidden();
_renderTreeNode->_bounds = bounds(); _renderTreeNode->_bounds = bounds();
_renderTreeNode->_position = position(); _renderTreeNode->_position = position();
@ -214,6 +184,14 @@ public:
_renderTreeNode->_alpha = opacity(); _renderTreeNode->_alpha = opacity();
_renderTreeNode->_masksToBounds = masksToBounds(); _renderTreeNode->_masksToBounds = masksToBounds();
_renderTreeNode->_isHidden = isHidden(); _renderTreeNode->_isHidden = isHidden();
return _renderTreeNode;
}
virtual void updateContentsLayerParameters() override {
_contentsTreeNode->_transform = _contentsLayer->transform();
_contentsTreeNode->_alpha = _contentsLayer->opacity();
_contentsTreeNode->_isHidden = _contentsLayer->isHidden();
} }
private: private:

View File

@ -1388,27 +1388,22 @@ std::shared_ptr<RenderTreeNode> ShapeCompositionLayer::renderTreeNode(BezierPath
); );
} }
return _renderTreeNode;
}
void ShapeCompositionLayer::updateRenderTree(BezierPathsBoundingBoxContext &boundingBoxContext) {
if (_matteLayer) {
_matteLayer->updateRenderTree(boundingBoxContext);
}
_contentRenderTreeNode->_bounds = _contentsLayer->bounds(); _contentRenderTreeNode->_bounds = _contentsLayer->bounds();
_contentRenderTreeNode->_position = _contentsLayer->position(); _contentRenderTreeNode->_position = _contentsLayer->position();
_contentRenderTreeNode->_transform = _contentsLayer->transform();
_contentRenderTreeNode->_alpha = _contentsLayer->opacity();
_contentRenderTreeNode->_masksToBounds = _contentsLayer->masksToBounds(); _contentRenderTreeNode->_masksToBounds = _contentsLayer->masksToBounds();
_contentRenderTreeNode->_isHidden = _contentsLayer->isHidden();
_renderTreeNode->_masksToBounds = masksToBounds();
_renderTreeNode->_bounds = bounds(); _renderTreeNode->_bounds = bounds();
_renderTreeNode->_position = position(); _renderTreeNode->_position = position();
_renderTreeNode->_transform = transform();
_renderTreeNode->_alpha = opacity(); return _renderTreeNode;
_renderTreeNode->_masksToBounds = masksToBounds(); }
_renderTreeNode->_isHidden = isHidden();
void ShapeCompositionLayer::updateContentsLayerParameters() {
_contentRenderTreeNode->_transform = _contentsLayer->transform();
_contentRenderTreeNode->_alpha = _contentsLayer->opacity();
_contentRenderTreeNode->_isHidden = _contentsLayer->isHidden();
} }
} }

View File

@ -18,7 +18,8 @@ public:
virtual void displayContentsWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) override; virtual void displayContentsWithFrame(double frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) override;
virtual std::shared_ptr<RenderTreeNode> renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) override; virtual std::shared_ptr<RenderTreeNode> renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) override;
virtual void updateRenderTree(BezierPathsBoundingBoxContext &boundingBoxContext) override; void initializeContentsLayerParameters();
virtual void updateContentsLayerParameters() override;
private: private:
std::shared_ptr<ShapeLayerPresentationTree> _contentTree; std::shared_ptr<ShapeLayerPresentationTree> _contentTree;

View File

@ -90,7 +90,7 @@ public:
_layerFontProvider->addTextLayers(textLayers); _layerFontProvider->addTextLayers(textLayers);
_layerFontProvider->reloadTexts(); _layerFontProvider->reloadTexts();
setNeedsDisplay(true); renderTreeNode();
} }
void setRespectAnimationFrameRate(bool respectAnimationFrameRate) { void setRespectAnimationFrameRate(bool respectAnimationFrameRate) {
@ -249,26 +249,9 @@ public:
); );
} }
updateRenderTree();
return _renderTreeNode; 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: private:
// MARK: Internal // MARK: Internal

View File

@ -185,9 +185,12 @@ public:
return localUpdatesPermeateDownstream() ? hasUpstreamUpdates() || hasLocalUpdates() : hasUpstreamUpdates(); return localUpdatesPermeateDownstream() ? hasUpstreamUpdates() || hasLocalUpdates() : hasUpstreamUpdates();
} }
virtual void updateTree(double frame, bool forceUpdates) { bool updateTree(double frame, bool forceUpdates) {
updateContents(frame, forceUpdates); if (updateContents(frame, forceUpdates)) {
updateOutputs(frame, forceUpdates); return updateOutputs(frame, forceUpdates);
} else {
return false;
}
} }
/// The name of the Keypath /// The name of the Keypath

View File

@ -45,13 +45,6 @@ public:
} }
} }
bool needsDisplay() const {
return _needsDisplay;
}
void setNeedsDisplay(bool needsDisplay) {
_needsDisplay = true;
}
virtual bool implementsDraw() const { virtual bool implementsDraw() const {
return false; return false;
} }
@ -148,7 +141,6 @@ private:
private: private:
CALayer *_superlayer = nullptr; CALayer *_superlayer = nullptr;
std::vector<std::shared_ptr<CALayer>> _sublayers; std::vector<std::shared_ptr<CALayer>> _sublayers;
bool _needsDisplay = false;
bool _isHidden = false; bool _isHidden = false;
float _opacity = 1.0; float _opacity = 1.0;
Vector2D _position = Vector2D(0.0, 0.0); Vector2D _position = Vector2D(0.0, 0.0);