diff --git a/CHANGELOG.md b/CHANGELOG.md index 32708c063..83041497a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ - Use `NS_RETURNS_RETAINED` macro to make our methods a tiny bit faster. [Adlai Holler](https://github.com/Adlai-Holler) [#843](https://github.com/TextureGroup/Texture/pull/843/) - `ASDisplayNode, ASLayoutSpec, and ASLayoutElementStyle` now conform to `NSLocking`. They act as recursive locks. Useful locking macros have been added as `ASThread.h`. Subclasses / client code can lock these objects but should be careful as usual when dealing with locks. [Adlai Holler](https://github.com/Adlai-Holler) - Introduces `ASRecursiveUnfairLock` as an experiment to improve locking performance. [Adlai Holler](https://github.com/Adlai-Holler) +- Adds an experiment to shorten init time. [Adlai Holler](https://github.com/Adlai-Holler) ## 2.6 - [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon) diff --git a/Source/ASExperimentalFeatures.h b/Source/ASExperimentalFeatures.h index 0df466b6f..8b20c2269 100644 --- a/Source/ASExperimentalFeatures.h +++ b/Source/ASExperimentalFeatures.h @@ -24,6 +24,7 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { ASExperimentalTextNode = 1 << 1, // exp_text_node ASExperimentalInterfaceStateCoalescing = 1 << 2, // exp_interface_state_coalesce ASExperimentalUnfairLock = 1 << 3, // exp_unfair_lock + ASExperimentalLayerDefaults = 1 << 4, // exp_infer_layer_defaults ASExperimentalFeatureAll = 0xFFFFFFFF }; diff --git a/Source/ASExperimentalFeatures.m b/Source/ASExperimentalFeatures.m index 5ce20c70b..8cfb0fb6c 100644 --- a/Source/ASExperimentalFeatures.m +++ b/Source/ASExperimentalFeatures.m @@ -16,7 +16,9 @@ { NSArray *allNames = ASCreateOnce((@[@"exp_graphics_contexts", @"exp_text_node", - @"exp_interface_state_coalesce"])); + @"exp_interface_state_coalesce", + @"exp_unfair_lock", + @"exp_infer_layer_defaults"])); if (flags == ASExperimentalFeatureAll) { return allNames; diff --git a/Source/Details/ASThread.h b/Source/Details/ASThread.h index 198a8c810..e7be43f02 100644 --- a/Source/Details/ASThread.h +++ b/Source/Details/ASThread.h @@ -29,7 +29,7 @@ #import #import -ASDISPLAYNODE_INLINE BOOL ASDisplayNodeThreadIsMain() +ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASDisplayNodeThreadIsMain() { return 0 != pthread_main_np(); } diff --git a/Source/Private/ASInternalHelpers.m b/Source/Private/ASInternalHelpers.m index 3912a66c7..34b9bd586 100644 --- a/Source/Private/ASInternalHelpers.m +++ b/Source/Private/ASInternalHelpers.m @@ -25,26 +25,42 @@ #import #import -static BOOL defaultAllowsGroupOpacity = YES; -static BOOL defaultAllowsEdgeAntialiasing = NO; +static NSNumber *allowsGroupOpacityFromUIKitOrNil; +static NSNumber *allowsEdgeAntialiasingFromUIKitOrNil; -void ASInitializeFrameworkMainThread(void) +BOOL ASDefaultAllowsGroupOpacity() { - ASDisplayNodeThreadIsMain(); - // Ensure these values are cached on the main thread before needed in the background. - CALayer *layer = [[[UIView alloc] init] layer]; - defaultAllowsGroupOpacity = layer.allowsGroupOpacity; - defaultAllowsEdgeAntialiasing = layer.allowsEdgeAntialiasing; + static BOOL groupOpacity; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSNumber *groupOpacityObj = allowsGroupOpacityFromUIKitOrNil ?: [NSBundle.mainBundle objectForInfoDictionaryKey:@"UIViewGroupOpacity"]; + groupOpacity = groupOpacityObj ? groupOpacityObj.boolValue : YES; + }); + return groupOpacity; } -BOOL ASDefaultAllowsGroupOpacity(void) +BOOL ASDefaultAllowsEdgeAntialiasing() { - return defaultAllowsGroupOpacity; + static BOOL edgeAntialiasing; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSNumber *antialiasingObj = allowsEdgeAntialiasingFromUIKitOrNil ?: [NSBundle.mainBundle objectForInfoDictionaryKey:@"UIViewEdgeAntialiasing"]; + edgeAntialiasing = antialiasingObj ? antialiasingObj.boolValue : NO; + }); + return edgeAntialiasing; } -BOOL ASDefaultAllowsEdgeAntialiasing(void) +void ASInitializeFrameworkMainThread(void) { - return defaultAllowsEdgeAntialiasing; + ASDisplayNodeCAssertMainThread(); + // Ensure these values are cached on the main thread before needed in the background. + if (ASActivateExperimentalFeature(ASExperimentalLayerDefaults)) { + // Nop. We will gather default values on-demand in ASDefaultAllowsGroupOpacity and ASDefaultAllowsEdgeAntialiasing + } else { + CALayer *layer = [[[UIView alloc] init] layer]; + allowsGroupOpacityFromUIKitOrNil = @(layer.allowsGroupOpacity); + allowsEdgeAntialiasingFromUIKitOrNil = @(layer.allowsEdgeAntialiasing); + } } BOOL ASSubclassOverridesSelector(Class superclass, Class subclass, SEL selector)