This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
[macOS] Isolate openGL rendering to FlutterOpenGLRenderer #22569
Merged
iskakaushik
merged 1 commit into
flutter:master
from
iskakaushik:opengl_rendering_isolation
Nov 17, 2020
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
|
|
||
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h" | ||
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h" | ||
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.h" | ||
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h" | ||
| #import "flutter/shell/platform/embedder/embedder.h" | ||
|
|
||
|
|
@@ -37,42 +38,11 @@ @interface FlutterEngine () <FlutterBinaryMessenger> | |
| */ | ||
| - (void)sendUserLocales; | ||
|
|
||
| /** | ||
| * Called by the engine to make the context the engine should draw into current. | ||
| */ | ||
| - (bool)engineCallbackOnMakeCurrent; | ||
|
|
||
| /** | ||
| * Called by the engine to clear the context the engine should draw into. | ||
| */ | ||
| - (bool)engineCallbackOnClearCurrent; | ||
|
|
||
| /** | ||
| * Called by the engine when the context's buffers should be swapped. | ||
| */ | ||
| - (bool)engineCallbackOnPresent; | ||
|
|
||
| /** | ||
| * Called by the engine when framebuffer object ID is requested. | ||
| */ | ||
| - (uint32_t)engineCallbackOnFBO:(const FlutterFrameInfo*)info; | ||
|
|
||
| /** | ||
| * Makes the resource context the current context. | ||
| */ | ||
| - (bool)engineCallbackOnMakeResourceCurrent; | ||
|
|
||
| /** | ||
| * Handles a platform message from the engine. | ||
| */ | ||
| - (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message; | ||
|
|
||
| /** | ||
| * Forwards texture copy request to the corresponding texture via |textureID|. | ||
| */ | ||
| - (BOOL)populateTextureWithIdentifier:(int64_t)textureID | ||
| openGLTexture:(FlutterOpenGLTexture*)openGLTexture; | ||
|
|
||
| /** | ||
| * Requests that the task be posted back the to the Flutter engine at the target time. The target | ||
| * time is in the clock used by the Flutter engine. | ||
|
|
@@ -119,7 +89,7 @@ - (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine | |
| } | ||
|
|
||
| - (id<FlutterTextureRegistry>)textures { | ||
| return _flutterEngine; | ||
| return _flutterEngine.openGLRenderer; | ||
| } | ||
|
|
||
| - (NSView*)view { | ||
|
|
@@ -138,38 +108,10 @@ - (void)addMethodCallDelegate:(nonnull id<FlutterPlugin>)delegate | |
| // Callbacks provided to the engine. See the called methods for documentation. | ||
| #pragma mark - Static methods provided to engine configuration | ||
|
|
||
| static bool OnMakeCurrent(FlutterEngine* engine) { | ||
| return [engine engineCallbackOnMakeCurrent]; | ||
| } | ||
|
|
||
| static bool OnClearCurrent(FlutterEngine* engine) { | ||
| return [engine engineCallbackOnClearCurrent]; | ||
| } | ||
|
|
||
| static bool OnPresent(FlutterEngine* engine) { | ||
| return [engine engineCallbackOnPresent]; | ||
| } | ||
|
|
||
| static uint32_t OnFBO(FlutterEngine* engine, const FlutterFrameInfo* info) { | ||
| return [engine engineCallbackOnFBO:info]; | ||
| } | ||
|
|
||
| static bool OnMakeResourceCurrent(FlutterEngine* engine) { | ||
| return [engine engineCallbackOnMakeResourceCurrent]; | ||
| } | ||
|
|
||
| static void OnPlatformMessage(const FlutterPlatformMessage* message, FlutterEngine* engine) { | ||
| [engine engineCallbackOnPlatformMessage:message]; | ||
| } | ||
|
|
||
| static bool OnAcquireExternalTexture(FlutterEngine* engine, | ||
| int64_t texture_identifier, | ||
| size_t width, | ||
| size_t height, | ||
| FlutterOpenGLTexture* open_gl_texture) { | ||
| return [engine populateTextureWithIdentifier:texture_identifier openGLTexture:open_gl_texture]; | ||
| } | ||
|
|
||
| #pragma mark - | ||
|
|
||
| @implementation FlutterEngine { | ||
|
|
@@ -179,22 +121,12 @@ @implementation FlutterEngine { | |
| // The project being run by this engine. | ||
| FlutterDartProject* _project; | ||
|
|
||
| // 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; | ||
|
|
||
| // Whether the engine can continue running after the view controller is removed. | ||
| BOOL _allowHeadlessExecution; | ||
|
|
||
| // A mapping of textureID to internal FlutterExternalTextureGL adapter. | ||
| NSMutableDictionary<NSNumber*, FlutterExternalTextureGL*>* _textures; | ||
|
|
||
| // Pointer to the Dart AOT snapshot and instruction data. | ||
| _FlutterEngineAOTData* _aotData; | ||
| } | ||
|
|
@@ -211,10 +143,10 @@ - (instancetype)initWithName:(NSString*)labelPrefix | |
|
|
||
| _project = project ?: [[FlutterDartProject alloc] init]; | ||
| _messageHandlers = [[NSMutableDictionary alloc] init]; | ||
| _textures = [[NSMutableDictionary alloc] init]; | ||
| _allowHeadlessExecution = allowHeadlessExecution; | ||
| _embedderAPI.struct_size = sizeof(FlutterEngineProcTable); | ||
| FlutterEngineGetProcAddresses(&_embedderAPI); | ||
| _openGLRenderer = [[FlutterOpenGLRenderer alloc] initWithFlutterEngine:_engine]; | ||
|
|
||
| NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter]; | ||
| [notificationCenter addObserver:self | ||
|
|
@@ -242,17 +174,8 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { | |
| return NO; | ||
| } | ||
|
|
||
| const FlutterRendererConfig rendererConfig = { | ||
| .type = kOpenGL, | ||
| .open_gl.struct_size = sizeof(FlutterOpenGLRendererConfig), | ||
| .open_gl.make_current = (BoolCallback)OnMakeCurrent, | ||
| .open_gl.clear_current = (BoolCallback)OnClearCurrent, | ||
| .open_gl.present = (BoolCallback)OnPresent, | ||
| .open_gl.fbo_with_frame_info_callback = (UIntFrameInfoCallback)OnFBO, | ||
| .open_gl.fbo_reset_after_present = true, | ||
| .open_gl.make_resource_current = (BoolCallback)OnMakeResourceCurrent, | ||
| .open_gl.gl_external_texture_frame_callback = (TextureFrameCallback)OnAcquireExternalTexture, | ||
| }; | ||
| [_openGLRenderer attachToFlutterView:_viewController.flutterView]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no guarantee that there will be a view here. How are you handling later changes to the view controller given that you removed
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, will account for it. |
||
| const FlutterRendererConfig rendererConfig = [_openGLRenderer createRendererConfig]; | ||
|
|
||
| // TODO(stuartmorgan): Move internal channel registration from FlutterViewController to here. | ||
|
|
||
|
|
@@ -351,15 +274,6 @@ - (void)loadAOTData:(NSString*)assetsDir { | |
| } | ||
| } | ||
|
|
||
| - (void)setViewController:(FlutterViewController*)controller { | ||
| _viewController = controller; | ||
| _mainOpenGLContext = controller.flutterView.openGLContext; | ||
| if (!controller && !_allowHeadlessExecution) { | ||
| [self shutDownEngine]; | ||
| _resourceContext = nil; | ||
| } | ||
| } | ||
|
|
||
| - (id<FlutterBinaryMessenger>)binaryMessenger { | ||
| // TODO(stuartmorgan): Switch to FlutterBinaryMessengerRelay to avoid plugins | ||
| // keeping the engine alive. | ||
|
|
@@ -372,17 +286,6 @@ - (BOOL)running { | |
| return _engine != nullptr; | ||
| } | ||
|
|
||
| - (NSOpenGLContext*)resourceContext { | ||
| if (!_resourceContext) { | ||
| NSOpenGLPixelFormatAttribute attributes[] = { | ||
| NSOpenGLPFAColorSize, 24, NSOpenGLPFAAlphaSize, 8, 0, | ||
| }; | ||
| NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; | ||
| _resourceContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; | ||
| } | ||
| return _resourceContext; | ||
| } | ||
|
|
||
| - (void)updateDisplayConfig { | ||
| if (!_engine) { | ||
| return; | ||
|
|
@@ -461,37 +364,6 @@ - (void)sendUserLocales { | |
| _embedderAPI.UpdateLocales(_engine, flutterLocaleList.data(), flutterLocaleList.size()); | ||
| } | ||
|
|
||
| - (bool)engineCallbackOnMakeCurrent { | ||
| if (!_mainOpenGLContext) { | ||
| return false; | ||
| } | ||
| [_mainOpenGLContext makeCurrentContext]; | ||
| return true; | ||
| } | ||
|
|
||
| - (uint32_t)engineCallbackOnFBO:(const FlutterFrameInfo*)info { | ||
| CGSize size = CGSizeMake(info->size.width, info->size.height); | ||
| return [_viewController.flutterView frameBufferIDForSize:size]; | ||
| } | ||
|
|
||
| - (bool)engineCallbackOnClearCurrent { | ||
| [NSOpenGLContext clearCurrentContext]; | ||
| return true; | ||
| } | ||
|
|
||
| - (bool)engineCallbackOnPresent { | ||
| if (!_mainOpenGLContext) { | ||
| return false; | ||
| } | ||
| [self.viewController.flutterView present]; | ||
| return true; | ||
| } | ||
|
|
||
| - (bool)engineCallbackOnMakeResourceCurrent { | ||
| [self.resourceContext makeCurrentContext]; | ||
| return true; | ||
| } | ||
|
|
||
| - (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message { | ||
| NSData* messageData = [NSData dataWithBytesNoCopy:(void*)message->message | ||
| length:message->message_size | ||
|
|
@@ -618,31 +490,6 @@ - (void)cleanupConnection:(FlutterBinaryMessengerConnection)connection { | |
| return [[FlutterEngineRegistrar alloc] initWithPlugin:pluginName flutterEngine:self]; | ||
| } | ||
|
|
||
| #pragma mark - FlutterTextureRegistrar | ||
|
|
||
| - (BOOL)populateTextureWithIdentifier:(int64_t)textureID | ||
| openGLTexture:(FlutterOpenGLTexture*)openGLTexture { | ||
| return [_textures[@(textureID)] populateTexture:openGLTexture]; | ||
| } | ||
|
|
||
| - (int64_t)registerTexture:(id<FlutterTexture>)texture { | ||
| FlutterExternalTextureGL* FlutterTexture = | ||
| [[FlutterExternalTextureGL alloc] initWithFlutterTexture:texture]; | ||
| int64_t textureID = [FlutterTexture textureID]; | ||
| _embedderAPI.RegisterExternalTexture(_engine, textureID); | ||
| _textures[@(textureID)] = FlutterTexture; | ||
| return textureID; | ||
| } | ||
|
|
||
| - (void)textureFrameAvailable:(int64_t)textureID { | ||
| _embedderAPI.MarkExternalTextureFrameAvailable(_engine, textureID); | ||
| } | ||
|
|
||
| - (void)unregisterTexture:(int64_t)textureID { | ||
| _embedderAPI.UnregisterExternalTexture(_engine, textureID); | ||
| [_textures removeObjectForKey:@(textureID)]; | ||
| } | ||
|
|
||
| #pragma mark - Task runner integration | ||
|
|
||
| - (void)postMainThreadTask:(FlutterTask)task targetTimeInNanoseconds:(uint64_t)targetTime { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| #import <Cocoa/Cocoa.h> | ||
|
|
||
| #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h" | ||
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h" | ||
| #import "flutter/shell/platform/embedder/embedder.h" | ||
|
|
||
| NS_ASSUME_NONNULL_BEGIN | ||
|
|
||
| /** | ||
| * Provides the renderer config needed to initialize the embedder engine and also handles external | ||
| * texture management. This is initialized during FlutterEngine creation and then attached to the | ||
| * FlutterView once the FlutterViewController is initializer. | ||
| */ | ||
| @interface FlutterOpenGLRenderer : NSObject <FlutterTextureRegistry> | ||
|
|
||
| /** | ||
| * The resource context used by the engine for texture uploads. FlutterViews associated with this | ||
| * engine should be created to share with this context. | ||
| */ | ||
| @property(nonatomic, readonly, nullable) NSOpenGLContext* resourceContext; | ||
|
|
||
| /** | ||
| * Intializes the renderer with the given FlutterEngine. | ||
| */ | ||
| - (instancetype)initWithFlutterEngine:(FLUTTER_API_SYMBOL(FlutterEngine))engine; | ||
|
|
||
| /** | ||
| * Attaches to the FlutterView and sets up the renderers main OpenGL context. | ||
| */ | ||
| - (void)attachToFlutterView:(FlutterView*)view; | ||
|
|
||
| /** | ||
| * Called by the engine to make the context the engine should draw into current. | ||
| */ | ||
| - (bool)makeCurrent; | ||
|
|
||
| /** | ||
| * Called by the engine to clear the context the engine should draw into. | ||
| */ | ||
| - (bool)clearCurrent; | ||
|
|
||
| /** | ||
| * Called by the engine when the context's buffers should be swapped. | ||
| */ | ||
| - (bool)present; | ||
|
|
||
| /** | ||
| * Called by the engine when framebuffer object ID is requested. | ||
| */ | ||
| - (uint32_t)getFBO:(const FlutterFrameInfo*)info; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "get" is not idiomatic ObjC naming. This should be called |
||
|
|
||
| /** | ||
| * Makes the resource context the current context. | ||
| */ | ||
| - (bool)makeResourceCurrent; | ||
|
|
||
| /** | ||
| * Called by the engine to unset the resource context. | ||
| */ | ||
| - (void)clearResourceContext; | ||
|
|
||
| /** | ||
| * Populates the texture registry with the provided openGLTexture. | ||
| */ | ||
| - (BOOL)populateTextureWithIdentifier:(int64_t)textureID | ||
| openGLTexture:(FlutterOpenGLTexture*)openGLTexture; | ||
|
|
||
| /** | ||
| * Creates a FlutterRendererConfig that renders using OpenGL context(s) held | ||
| * by this class. | ||
| */ | ||
| - (FlutterRendererConfig)createRendererConfig; | ||
|
|
||
| @end | ||
|
|
||
| NS_ASSUME_NONNULL_END | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you follow the breaking change process for this change? You've changed the public API of a public class.