Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Fix race condition in FlutterSurfaceManager #27828

Merged
merged 1 commit into from
Aug 2, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ @implementation FlutterIOSurfaceManager {

CGSize _surfaceSize;
FlutterIOSurfaceHolder* _ioSurfaces[kFlutterSurfaceManagerBufferCount];
BOOL _frameInProgress;
}

- (instancetype)initWithLayer:(CALayer*)containingLayer contentTransform:(CATransform3D)transform {
Expand Down Expand Up @@ -66,23 +67,33 @@ - (void)swapBuffers {
_ioSurfaces[kFlutterSurfaceManagerFrontBuffer]);
[_delegate onSwapBuffers];

dispatch_async(dispatch_get_main_queue(), ^{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onIdle) object:nil];
[self performSelector:@selector(onIdle) withObject:nil afterDelay:kIdleDelay];
});
// performSelector:withObject:afterDelay needs to be performed on RunLoop thread
[self performSelectorOnMainThread:@selector(reschedule) withObject:nil waitUntilDone:NO];

@synchronized(self) {
_frameInProgress = NO;
}
}

- (void)reschedule {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onIdle) object:nil];
[self performSelector:@selector(onIdle) withObject:nil afterDelay:kIdleDelay];
}

- (void)onIdle {
@synchronized(self) {
// Release the back buffer and notify delegate. The buffer will be restored
// on demand in ensureBackBuffer
_ioSurfaces[kFlutterSurfaceManagerBackBuffer] = nil;
[self.delegate onSurfaceReleased:kFlutterSurfaceManagerBackBuffer];
if (!_frameInProgress) {
// Release the back buffer and notify delegate. The buffer will be restored
// on demand in ensureBackBuffer
_ioSurfaces[kFlutterSurfaceManagerBackBuffer] = nil;
[self.delegate onSurfaceReleased:kFlutterSurfaceManagerBackBuffer];
}
}
}

- (void)ensureBackBuffer {
@synchronized(self) {
_frameInProgress = YES;
if (_ioSurfaces[kFlutterSurfaceManagerBackBuffer] == nil) {
// Restore previously released backbuffer
_ioSurfaces[kFlutterSurfaceManagerBackBuffer] = [[FlutterIOSurfaceHolder alloc] init];
Expand Down