Skip to content

Commit

Permalink
Avoid accessing the Cocoa view on the GPU or IO task runners. (#13295)
Browse files Browse the repository at this point in the history
The view was being accessed from a background thread so its OpenGL context could be accessed. This tripped thread safety assertions in Cocoa. Now the OpenGL context is stashed in the FlutterEngine instance itself.
  • Loading branch information
chinmaygarde committed Oct 22, 2019
1 parent 591d149 commit 97f5ad4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 36 deletions.
48 changes: 30 additions & 18 deletions shell/platform/darwin/macos/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ @implementation FlutterEngine {
// The context provided to the Flutter engine for resource loading.
NSOpenGLContext* _resourceContext;

// The context that is owned by the currently displayed FlutterView. This is stashed in the engine
// so that the view doesn't need to be accessed from a background thread.
NSOpenGLContext* _mainOpenGLContext;

// A mapping of channel names to the registered handlers for those channels.
NSMutableDictionary<NSString*, FlutterBinaryMessageHandler>* _messageHandlers;

Expand Down Expand Up @@ -215,18 +219,26 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint {
flutterArguments.platform_message_callback = (FlutterPlatformMessageCallback)OnPlatformMessage;
flutterArguments.custom_dart_entrypoint = entrypoint.UTF8String;

FlutterEngineResult result = FlutterEngineRun(
FlutterEngineResult result = FlutterEngineInitialize(
FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine);
if (result != kSuccess) {
NSLog(@"Failed to start Flutter engine: error %d", result);
NSLog(@"Failed to initialize Flutter engine: error %d", result);
return NO;
}

result = FlutterEngineRunInitialized(_engine);
if (result != kSuccess) {
NSLog(@"Failed to run an initialized engine: error %d", result);
return NO;
}

[self updateWindowMetrics];
return YES;
}

- (void)setViewController:(FlutterViewController*)controller {
_viewController = controller;
_mainOpenGLContext = controller.flutterView.openGLContext;
if (!controller && !_allowHeadlessExecution) {
[self shutDownEngine];
_resourceContext = nil;
Expand Down Expand Up @@ -281,33 +293,26 @@ - (void)sendPointerEvent:(const FlutterPointerEvent&)event {
#pragma mark - Private methods

- (bool)engineCallbackOnMakeCurrent {
if (!_viewController.flutterView) {
if (!_mainOpenGLContext) {
return false;
}
[_viewController.flutterView makeCurrentContext];
[_mainOpenGLContext makeCurrentContext];
return true;
}

- (bool)engineCallbackOnClearCurrent {
if (!_viewController.flutterView) {
return false;
}
[NSOpenGLContext clearCurrentContext];
return true;
}

- (bool)engineCallbackOnPresent {
if (!_viewController.flutterView) {
return false;
if (!_mainOpenGLContext) {
}
[_viewController.flutterView onPresent];
[_mainOpenGLContext flushBuffer];
return true;
}

- (bool)engineCallbackOnMakeResourceCurrent {
if (!_viewController.flutterView) {
return false;
}
[self.resourceContext makeCurrentContext];
return true;
}
Expand Down Expand Up @@ -344,11 +349,18 @@ - (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message {
* Note: Called from dealloc. Should not use accessors or other methods.
*/
- (void)shutDownEngine {
if (_engine) {
FlutterEngineResult result = FlutterEngineShutdown(_engine);
if (result != kSuccess) {
NSLog(@"Failed to shut down Flutter engine: error %d", result);
}
if (_engine == nullptr) {
return;
}

FlutterEngineResult result = FlutterEngineDeinitialize(_engine);
if (result != kSuccess) {
NSLog(@"Could not de-initialize the Flutter engine: error %d", result);
}

result = FlutterEngineShutdown(_engine);
if (result != kSuccess) {
NSLog(@"Failed to shut down Flutter engine: error %d", result);
}
_engine = nullptr;
}
Expand Down
10 changes: 0 additions & 10 deletions shell/platform/darwin/macos/framework/Source/FlutterView.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,4 @@
- (nullable instancetype)initWithCoder:(nonnull NSCoder*)coder NS_UNAVAILABLE;
- (nonnull instancetype)init NS_UNAVAILABLE;

/**
* Sets this view as the current context object for OpenGL drawing.
*/
- (void)makeCurrentContext;

/**
* Called when the OpenGL display should be updated.
*/
- (void)onPresent;

@end
8 changes: 0 additions & 8 deletions shell/platform/darwin/macos/framework/Source/FlutterView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ - (instancetype)initWithFrame:(NSRect)frame
return self;
}

- (void)makeCurrentContext {
[self.openGLContext makeCurrentContext];
}

- (void)onPresent {
[self.openGLContext flushBuffer];
}

#pragma mark - NSView overrides

/**
Expand Down

0 comments on commit 97f5ad4

Please sign in to comment.