未验证 提交 94e217bc 编写于 作者: K Kaushik Iska 提交者: GitHub

[macOS] Isolate openGL rendering to FlutterOpenGLRenderer (#22569)

上级 c1e9cda1
......@@ -1054,6 +1054,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExter
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h
......
......@@ -39,7 +39,7 @@ FLUTTER_EXPORT
/**
* Registers a `FlutterTexture` for usage in Flutter and returns an id that can be used to reference
* that texture when calling into Flutter with channels. Textures must be registered on the
* platform thread.
* platform thread. On success returns the pointer to the registered texture, else returns 0.
*/
- (int64_t)registerTexture:(NSObject<FlutterTexture>*)texture;
/**
......
......@@ -54,6 +54,8 @@ source_set("flutter_framework_source") {
"framework/Source/FlutterExternalTextureGL.mm",
"framework/Source/FlutterMouseCursorPlugin.h",
"framework/Source/FlutterMouseCursorPlugin.mm",
"framework/Source/FlutterOpenGLRenderer.h",
"framework/Source/FlutterOpenGLRenderer.mm",
"framework/Source/FlutterResizeSynchronizer.h",
"framework/Source/FlutterResizeSynchronizer.mm",
"framework/Source/FlutterSurfaceManager.h",
......
......@@ -21,7 +21,7 @@
* Coordinates a single instance of execution of a Flutter engine.
*/
FLUTTER_EXPORT
@interface FlutterEngine : NSObject <FlutterTextureRegistry, FlutterPluginRegistry>
@interface FlutterEngine : NSObject <FlutterPluginRegistry>
/**
* Initializes an engine with the given viewController.
......
......@@ -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 @@ static FlutterLocale FlutterLocaleFromNSLocale(NSLocale* locale) {
*/
- (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 @@ static FlutterLocale FlutterLocaleFromNSLocale(NSLocale* locale) {
}
- (id<FlutterTextureRegistry>)textures {
return _flutterEngine;
return _flutterEngine.openGLRenderer;
}
- (NSView*)view {
......@@ -138,38 +108,10 @@ static FlutterLocale FlutterLocaleFromNSLocale(NSLocale* locale) {
// 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 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
// 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 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
_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 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
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];
const FlutterRendererConfig rendererConfig = [_openGLRenderer createRendererConfig];
// TODO(stuartmorgan): Move internal channel registration from FlutterViewController to here.
......@@ -351,15 +274,6 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
}
}
- (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 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
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 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
_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 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
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 {
......
......@@ -6,6 +6,7 @@
#import <Cocoa/Cocoa.h>
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.h"
#include "flutter/shell/platform/embedder/embedder.h"
@interface FlutterEngine ()
......@@ -16,10 +17,10 @@
@property(nonatomic, readonly) BOOL running;
/**
* The resource context used by the engine for texture uploads. FlutterViews associated with this
* engine should be created to share with this context.
* Provides the renderer config needed to initialize the engine and also handles external texture
* management.
*/
@property(nonatomic, readonly, nullable) NSOpenGLContext* resourceContext;
@property(nonatomic, readonly, nonnull) FlutterOpenGLRenderer* openGLRenderer;
/**
* Function pointers for interacting with the embedder.h API.
......
// 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;
/**
* 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
// 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 "flutter/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.h"
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
#include "flutter/shell/platform/embedder/embedder.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h"
#pragma mark - Static methods for openGL callbacks that require the engine.
static bool OnMakeCurrent(FlutterEngine* engine) {
return [engine.openGLRenderer makeCurrent];
}
static bool OnClearCurrent(FlutterEngine* engine) {
return [engine.openGLRenderer clearCurrent];
}
static bool OnPresent(FlutterEngine* engine) {
return [engine.openGLRenderer present];
}
static uint32_t OnFBO(FlutterEngine* engine, const FlutterFrameInfo* info) {
return [engine.openGLRenderer getFBO:info];
}
static bool OnMakeResourceCurrent(FlutterEngine* engine) {
return [engine.openGLRenderer makeResourceCurrent];
}
static bool OnAcquireExternalTexture(FlutterEngine* engine,
int64_t textureIdentifier,
size_t width,
size_t height,
FlutterOpenGLTexture* openGlTexture) {
return [engine.openGLRenderer populateTextureWithIdentifier:textureIdentifier
openGLTexture:openGlTexture];
}
#pragma mark - FlutterOpenGLRenderer implementation.
@implementation FlutterOpenGLRenderer {
// The embedding-API-level engine object.
FLUTTER_API_SYMBOL(FlutterEngine) _engine;
FlutterView* _flutterView;
// The context that is owned by the currently displayed FlutterView. This is stashed
// in the renderer so that the view doesn't need to be accessed from a background thread.
NSOpenGLContext* _openGLContext;
// The context provided to the Flutter engine for resource loading.
NSOpenGLContext* _resourceContext;
// A mapping of textureID to internal FlutterExternalTextureGL adapter.
NSMutableDictionary<NSNumber*, FlutterExternalTextureGL*>* _textures;
FlutterEngineProcTable _embedderAPI;
}
- (instancetype)initWithFlutterEngine:(FLUTTER_API_SYMBOL(FlutterEngine))engine {
self = [super init];
if (self) {
_engine = engine;
_textures = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)attachToFlutterView:(FlutterView*)view {
_flutterView = view;
_openGLContext = view.openGLContext;
}
- (bool)makeCurrent {
if (!_openGLContext) {
return false;
}
[_openGLContext makeCurrentContext];
return true;
}
- (bool)clearCurrent {
[NSOpenGLContext clearCurrentContext];
return true;
}
- (bool)present {
if (!_openGLContext) {
return false;
}
[_flutterView present];
return true;
}
- (uint32_t)getFBO:(const FlutterFrameInfo*)info {
CGSize size = CGSizeMake(info->size.width, info->size.height);
return [_flutterView frameBufferIDForSize:size];
}
- (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;
}
- (bool)makeResourceCurrent {
[self.resourceContext makeCurrentContext];
return true;
}
- (void)clearResourceContext {
_resourceContext = nil;
}
#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];
auto success = _embedderAPI.RegisterExternalTexture(_engine, textureID);
if (success == FlutterEngineResult::kSuccess) {
_textures[@(textureID)] = FlutterTexture;
return textureID;
} else {
NSLog(@"Unable to register the texture with id: %lld.", textureID);
return 0;
}
}
- (void)textureFrameAvailable:(int64_t)textureID {
auto success = _embedderAPI.MarkExternalTextureFrameAvailable(_engine, textureID);
if (success != FlutterEngineResult::kSuccess) {
NSLog(@"Unable to mark texture with id %lld as available.", textureID);
}
}
- (void)unregisterTexture:(int64_t)textureID {
auto success = _embedderAPI.UnregisterExternalTexture(_engine, textureID);
if (success == FlutterEngineResult::kSuccess) {
[_textures removeObjectForKey:@(textureID)];
} else {
NSLog(@"Unable to unregister texture with id: %lld.", textureID);
}
}
#pragma mark - Helper methods to create rendering config for embedder.
- (FlutterRendererConfig)createRendererConfig {
const FlutterRendererConfig rendererConfig = {
.type = kOpenGL,
.open_gl.struct_size = sizeof(FlutterOpenGLRendererConfig),
.open_gl.make_current = reinterpret_cast<BoolCallback>(OnMakeCurrent),
.open_gl.clear_current = reinterpret_cast<BoolCallback>(OnClearCurrent),
.open_gl.present = reinterpret_cast<BoolCallback>(OnPresent),
.open_gl.fbo_with_frame_info_callback = reinterpret_cast<UIntFrameInfoCallback>(OnFBO),
.open_gl.fbo_reset_after_present = true,
.open_gl.make_resource_current = reinterpret_cast<BoolCallback>(OnMakeResourceCurrent),
.open_gl.gl_external_texture_frame_callback =
reinterpret_cast<TextureFrameCallback>(OnAcquireExternalTexture),
};
return rendererConfig;
}
@end
......@@ -239,7 +239,7 @@ static void CommonInit(FlutterViewController* controller) {
}
- (void)loadView {
NSOpenGLContext* resourceContext = _engine.resourceContext;
NSOpenGLContext* resourceContext = _engine.openGLRenderer.resourceContext;
if (!resourceContext) {
NSLog(@"Unable to create FlutterView; no resource context available.");
return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册