mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Add caching for checking if ASDisplayNode can clear it contents or setNeedsDisplay: can be called on the layer
This commit is contained in:
@@ -273,6 +273,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
_preferredFrameSize = CGSizeZero;
|
_preferredFrameSize = CGSizeZero;
|
||||||
|
|
||||||
_environmentState = ASEnvironmentStateMakeDefault();
|
_environmentState = ASEnvironmentStateMakeDefault();
|
||||||
|
|
||||||
|
_flags.canClearContentsOfLayer = YES;
|
||||||
|
_flags.canCallNeedsDisplayOfLayer = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
@@ -441,6 +444,11 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
view = [[_viewClass alloc] init];
|
view = [[_viewClass alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update flags related to special handling of UIImageView layers. More details on the flags
|
||||||
|
BOOL isUIIMageViewViewClass = [view isKindOfClass:[UIImageView class]];
|
||||||
|
_flags.canClearContentsOfLayer = !isUIIMageViewViewClass;
|
||||||
|
_flags.canCallNeedsDisplayOfLayer = (_flags.synchronous && !isUIIMageViewViewClass);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1788,29 +1796,18 @@ static NSInteger incrementIfFound(NSInteger i) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to summarize whether or not the node run through the display process
|
/// Helper method to summarize whether or not the node run through the display process
|
||||||
- (BOOL)__implementsDisplay
|
- (BOOL)__implementsDisplay
|
||||||
{
|
{
|
||||||
return _flags.implementsDrawRect || _flags.implementsImageDisplay || _flags.shouldRasterizeDescendants ||
|
return _flags.implementsDrawRect || _flags.implementsImageDisplay || _flags.shouldRasterizeDescendants ||
|
||||||
_flags.implementsInstanceDrawRect || _flags.implementsInstanceImageDisplay;
|
_flags.implementsInstanceDrawRect || _flags.implementsInstanceImageDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)__canClearContentsOfLayer
|
// Helper method to determine if it's save to call setNeedsDisplay on a layer without throwing away the content.
|
||||||
{
|
// For details look at the comment on the canCallNeedsDisplayOfLayer flag
|
||||||
// The layer contents should not be cleared in case the node is wrapping a UIImageView.UIImageView is specifically
|
|
||||||
// optimized for performance and does not use the usual way to provide the contents of the CALayer via the
|
|
||||||
// CALayerDelegate method that backs the UIImageView.
|
|
||||||
return !_flags.synchronous || _viewClass != [UIImageView class];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)__canCallNeedsDisplayOfLayer
|
- (BOOL)__canCallNeedsDisplayOfLayer
|
||||||
{
|
{
|
||||||
// Prevent calling setNeedsDisplay on a layer that backs a UIImageView. Usually calling setNeedsDisplay on a CALayer
|
return _flags.canCallNeedsDisplayOfLayer;
|
||||||
// triggers a recreation of the contents of layer unfortunately calling it on a CALayer that backs a UIImageView
|
|
||||||
// it goes trough the normal flow to assign the contents to a layer via the CALayerDelegate methods. Unfortunately
|
|
||||||
// UIImageView does not do recreate the layer contents the usual way, it actually does not implement some of the
|
|
||||||
// methods at all instead it throws away the contents of the layer and nothing will show up.
|
|
||||||
return _flags.synchronous && _viewClass != [UIImageView class];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)placeholderShouldPersist
|
- (BOOL)placeholderShouldPersist
|
||||||
@@ -2114,7 +2111,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
|||||||
|
|
||||||
- (void)clearContents
|
- (void)clearContents
|
||||||
{
|
{
|
||||||
if ([self __canClearContentsOfLayer]) {
|
if (_flags.canClearContentsOfLayer) {
|
||||||
// No-op if these haven't been created yet, as that guarantees they don't have contents that needs to be released.
|
// No-op if these haven't been created yet, as that guarantees they don't have contents that needs to be released.
|
||||||
_layer.contents = nil;
|
_layer.contents = nil;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,20 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
|
|||||||
unsigned shouldAnimateSizeChanges:1;
|
unsigned shouldAnimateSizeChanges:1;
|
||||||
unsigned hasCustomDrawingPriority:1;
|
unsigned hasCustomDrawingPriority:1;
|
||||||
|
|
||||||
|
// Wrapped view handling
|
||||||
|
|
||||||
|
// The layer contents should not be cleared in case the node is wrapping a UIImageView.UIImageView is specifically
|
||||||
|
// optimized for performance and does not use the usual way to provide the contents of the CALayer via the
|
||||||
|
// CALayerDelegate method that backs the UIImageView.
|
||||||
|
unsigned canClearContentsOfLayer:1;
|
||||||
|
|
||||||
|
// Prevent calling setNeedsDisplay on a layer that backs a UIImageView. Usually calling setNeedsDisplay on a CALayer
|
||||||
|
// triggers a recreation of the contents of layer unfortunately calling it on a CALayer that backs a UIImageView
|
||||||
|
// it goes trough the normal flow to assign the contents to a layer via the CALayerDelegate methods. Unfortunately
|
||||||
|
// UIImageView does not do recreate the layer contents the usual way, it actually does not implement some of the
|
||||||
|
// methods at all instead it throws away the contents of the layer and nothing will show up.
|
||||||
|
unsigned canCallNeedsDisplayOfLayer:1;
|
||||||
|
|
||||||
// whether custom drawing is enabled
|
// whether custom drawing is enabled
|
||||||
unsigned implementsInstanceDrawRect:1;
|
unsigned implementsInstanceDrawRect:1;
|
||||||
unsigned implementsDrawRect:1;
|
unsigned implementsDrawRect:1;
|
||||||
|
|||||||
Reference in New Issue
Block a user