Skip to content

Commit

Permalink
[ASDisplayNode] Notify rasterized subnodes that render pass has compl…
Browse files Browse the repository at this point in the history
…eted (TextureGroup#532)

* Notify rasterized subsides that render pass has completed

* Traverse entire subnode tree notifying all subnodes

* Add entry in changelog

* Retrieve rasterizesSubtree flag while holding instance lock

* Balance display delegate calls for rasterized subnodes
  • Loading branch information
smeis authored and bernieperez committed Apr 25, 2018
1 parent 7490c2d commit 493a1ac
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Table and collection views to consider content inset when calculating (default) element size range [Huy Nguyen](https://github.com/nguyenhuy) [#525](https://github.com/TextureGroup/Texture/pull/525)
- [ASEditableTextNode] added -editableTextNodeShouldBeginEditing to ASEditableTextNodeDelegate to mirror the corresponding method from UITextViewDelegate. [Yan S.](https://github.com/yans) [#535](https://github.com/TextureGroup/Texture/pull/535)
- [Breaking] Remove APIs that have been deprecated since 2.0 and/or for at least 6 months [Huy Nguyen](https://github.com/nguyenhuy) [#529](https://github.com/TextureGroup/Texture/pull/529)
- [ASDisplayNode] Ensure `-displayWillStartAsynchronously:` and `-displayDidFinish` are invoked on rasterized subnodes. [Eric Scheers](https://github.com/smeis) [#532](https://github.com/TextureGroup/Texture/pull/532)

##2.4
- Fix an issue where inserting/deleting sections could lead to inconsistent supplementary element behavior. [Adlai Holler](https://github.com/Adlai-Holler)
Expand Down
15 changes: 15 additions & 0 deletions Source/Private/ASDisplayNode+AsyncDisplay.mm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#import <AsyncDisplayKit/ASDisplayNode+FrameworkSubclasses.h>
#import <AsyncDisplayKit/ASInternalHelpers.h>
#import <AsyncDisplayKit/ASSignpost.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>


@interface ASDisplayNode () <_ASDisplayLayerDelegate>
@end
Expand Down Expand Up @@ -302,6 +304,7 @@ - (void)displayAsyncLayer:(_ASDisplayLayer *)asyncLayer asynchronously:(BOOL)asy
}

CALayer *layer = _layer;
BOOL rasterizesSubtree = _flags.rasterizesSubtree;

__instanceLock__.unlock();

Expand Down Expand Up @@ -347,11 +350,23 @@ - (void)displayAsyncLayer:(_ASDisplayLayer *)asyncLayer asynchronously:(BOOL)asy
layer.contents = (id)image.CGImage;
}
[self didDisplayAsyncLayer:self.asyncLayer];

if (rasterizesSubtree) {
ASDisplayNodePerformBlockOnEverySubnode(self, NO, ^(ASDisplayNode * _Nonnull node) {
[node didDisplayAsyncLayer:node.asyncLayer];
});
}
}
};

// Call willDisplay immediately in either case
[self willDisplayAsyncLayer:self.asyncLayer asynchronously:asynchronously];

if (rasterizesSubtree) {
ASDisplayNodePerformBlockOnEverySubnode(self, NO, ^(ASDisplayNode * _Nonnull node) {
[node willDisplayAsyncLayer:node.asyncLayer asynchronously:asynchronously];
});
}

if (asynchronously) {
// Async rendering operations are contained by a transaction, which allows them to proceed and concurrently
Expand Down
49 changes: 49 additions & 0 deletions Tests/ASDisplayNodeTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ @interface ASTestDisplayNode : ASDisplayNode
@property (nonatomic) BOOL hasPreloaded;
@property (nonatomic) BOOL preloadStateChangedToYES;
@property (nonatomic) BOOL preloadStateChangedToNO;

@property (nonatomic, assign) NSUInteger displayWillStartCount;
@property (nonatomic, assign) NSUInteger didDisplayCount;

@end

@interface ASTestResponderNode : ASTestDisplayNode
Expand Down Expand Up @@ -154,6 +158,18 @@ - (void)dealloc
}
}

- (void)displayDidFinish
{
[super displayDidFinish];
_didDisplayCount++;
}

- (void)displayWillStartAsynchronously:(BOOL)asynchronously
{
[super displayWillStartAsynchronously:asynchronously];
_displayWillStartCount++;
}

@end

@interface UIDisplayNodeTestView : UIView
Expand Down Expand Up @@ -2018,6 +2034,39 @@ - (void)testThatRasterizingWrapperNodesIsNotAllowed
XCTAssertThrows([rasterizedSupernode addSubnode:subnode]);
}

- (void)testThatSubnodesGetDisplayUpdatesIfRasterized
{
ASTestDisplayNode *supernode = [[ASTestDisplayNode alloc] init];
supernode.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
[supernode enableSubtreeRasterization];

ASTestDisplayNode *subnode = [[ASTestDisplayNode alloc] init];
ASTestDisplayNode *subSubnode = [[ASTestDisplayNode alloc] init];

ASSetDebugNames(supernode, subnode);
UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[subnode addSubnode:subSubnode];
[supernode addSubnode:subnode];
[window addSubnode:supernode];
[window makeKeyAndVisible];

XCTAssertTrue(ASDisplayNodeRunRunLoopUntilBlockIsTrue(^BOOL{
return (subnode.didDisplayCount == 1);
}));

XCTAssertTrue(ASDisplayNodeRunRunLoopUntilBlockIsTrue(^BOOL{
return (subSubnode.didDisplayCount == 1);
}));

XCTAssertTrue(ASDisplayNodeRunRunLoopUntilBlockIsTrue(^BOOL{
return (subnode.displayWillStartCount == 1);
}));

XCTAssertTrue(ASDisplayNodeRunRunLoopUntilBlockIsTrue(^BOOL{
return (subSubnode.displayWillStartCount == 1);
}));
}

// Underlying issue for: https://github.com/facebook/AsyncDisplayKit/issues/2011
- (void)testThatLayerBackedSubnodesAreMarkedInvisibleBeforeDeallocWhenSupernodesViewIsRemovedFromHierarchyWhileBeingRetained
{
Expand Down

0 comments on commit 493a1ac

Please sign in to comment.