-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[macos] Enable macOS platform views only for Metal #30853
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// 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. | ||
|
||
#ifndef FLUTTER_FLUTTERPLATFORMVIEWS_H_ | ||
#define FLUTTER_FLUTTERPLATFORMVIEWS_H_ | ||
|
||
#import <AppKit/AppKit.h> | ||
|
||
#import "FlutterCodecs.h" | ||
#import "FlutterMacros.h" | ||
|
||
@protocol FlutterPlatformViewFactory <NSObject> | ||
|
||
/** | ||
* Create a Platform View which is an `NSView`. | ||
* | ||
* A MacOS plugin should implement this method and return an `NSView`, which can be embedded in a | ||
* Flutter App. | ||
* | ||
* The implementation of this method should create a new `NSView`. | ||
* | ||
* @param viewId A unique identifier for this view. | ||
* @param args Parameters for creating the view sent from the Dart side of the | ||
* Flutter app. If `createArgsCodec` is not implemented, or if no creation arguments were sent from | ||
* the Dart code, this will be null. Otherwise this will be the value sent from the Dart code as | ||
* decoded by `createArgsCodec`. | ||
*/ | ||
- (nonnull NSView*)createWithviewIdentifier:(int64_t)viewId arguments:(nullable id)args; | ||
|
||
/** | ||
* Returns the `FlutterMessageCodec` for decoding the args parameter of `createWithFrame`. | ||
* | ||
* Only implement this if `createWithFrame` needs an arguments parameter. | ||
*/ | ||
@optional | ||
- (nullable NSObject<FlutterMessageCodec>*)createArgsCodec; | ||
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. This ideally shouldn't have "create" in the name; that's not standard naming for a getter. There's no reason this needs to create something every time. |
||
@end | ||
|
||
#endif // FLUTTER_FLUTTERPLATFORMVIEWS_H_ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,9 +15,10 @@ | |
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalCompositor.h" | ||
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalRenderer.h" | ||
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.h" | ||
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h" | ||
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderingBackend.h" | ||
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h" | ||
#include "flutter/shell/platform/embedder/embedder.h" | ||
#import "flutter/shell/platform/embedder/embedder.h" | ||
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. This change violates the style guide |
||
|
||
/** | ||
* Constructs and returns a FlutterLocale struct corresponding to |locale|, which must outlive | ||
|
@@ -95,6 +96,11 @@ - (void)postMainThreadTask:(FlutterTask)task targetTimeInNanoseconds:(uint64_t)t | |
*/ | ||
- (void)loadAOTData:(NSString*)assetsDir; | ||
|
||
/** | ||
* Creates a platform view channel and sets up the method handler. | ||
*/ | ||
- (void)setupPlatformViewChannel; | ||
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. The verb is "set up", so this should be setUpPlatformViewChannel |
||
|
||
@end | ||
|
||
#pragma mark - | ||
|
@@ -145,6 +151,11 @@ - (void)addMethodCallDelegate:(nonnull id<FlutterPlugin>)delegate | |
}]; | ||
} | ||
|
||
- (void)registerViewFactory:(nonnull NSObject<FlutterPlatformViewFactory>*)factory | ||
withId:(nonnull NSString*)factoryId { | ||
[[_flutterEngine platformViewController] registerViewFactory:factory withId:factoryId]; | ||
} | ||
|
||
@end | ||
|
||
// Callbacks provided to the engine. See the called methods for documentation. | ||
|
@@ -186,6 +197,14 @@ @implementation FlutterEngine { | |
|
||
// FlutterCompositor is copied and used in embedder.cc. | ||
FlutterCompositor _compositor; | ||
|
||
// Method channel for platform view functions. These functions include creating, disposing and | ||
// mutating a platform view. | ||
FlutterMethodChannel* _platformViewsChannel; | ||
|
||
// Used to support creation and deletion of platform views and registering platform view | ||
// factories. Lifecycle is tied to the engine. | ||
FlutterPlatformViewController* _platformViewController; | ||
} | ||
|
||
- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project { | ||
|
@@ -219,6 +238,9 @@ - (instancetype)initWithName:(NSString*)labelPrefix | |
name:NSCurrentLocaleDidChangeNotification | ||
object:nil]; | ||
|
||
_platformViewController = [[FlutterPlatformViewController alloc] init]; | ||
[self setupPlatformViewChannel]; | ||
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. You should never call methods on self in init. |
||
|
||
return self; | ||
} | ||
|
||
|
@@ -383,8 +405,8 @@ - (FlutterCompositor*)createFlutterCompositor { | |
|
||
if ([FlutterRenderingBackend renderUsingMetal]) { | ||
FlutterMetalRenderer* metalRenderer = reinterpret_cast<FlutterMetalRenderer*>(_renderer); | ||
_macOSCompositor = | ||
std::make_unique<flutter::FlutterMetalCompositor>(_viewController, metalRenderer.device); | ||
_macOSCompositor = std::make_unique<flutter::FlutterMetalCompositor>( | ||
_viewController, _platformViewController, metalRenderer.device); | ||
_macOSCompositor->SetPresentCallback([weakSelf](bool has_flutter_content) { | ||
if (has_flutter_content) { | ||
FlutterMetalRenderer* metalRenderer = | ||
|
@@ -541,6 +563,10 @@ - (void)dispatchSemanticsAction:(FlutterSemanticsAction)action | |
_embedderAPI.DispatchSemanticsAction(_engine, target, action, data.GetMapping(), data.GetSize()); | ||
} | ||
|
||
- (FlutterPlatformViewController*)platformViewController { | ||
return _platformViewController; | ||
} | ||
|
||
#pragma mark - Private methods | ||
|
||
- (void)sendUserLocales { | ||
|
@@ -630,6 +656,18 @@ - (void)shutDownEngine { | |
_engine = nullptr; | ||
} | ||
|
||
- (void)setupPlatformViewChannel { | ||
_platformViewsChannel = | ||
[FlutterMethodChannel methodChannelWithName:@"flutter/platform_views" | ||
binaryMessenger:self.binaryMessenger | ||
codec:[FlutterStandardMethodCodec sharedInstance]]; | ||
|
||
__weak FlutterEngine* weakSelf = self; | ||
[_platformViewsChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { | ||
[[weakSelf platformViewController] handleMethodCall:call result:result]; | ||
}]; | ||
} | ||
|
||
#pragma mark - FlutterBinaryMessenger | ||
|
||
- (void)sendOnChannel:(nonnull NSString*)channel message:(nullable NSData*)message { | ||
|
@@ -781,20 +819,22 @@ - (void)updateSemanticsCustomActions:(const FlutterSemanticsCustomAction*)action | |
|
||
#pragma mark - Task runner integration | ||
|
||
- (void)postMainThreadTask:(FlutterTask)task targetTimeInNanoseconds:(uint64_t)targetTime { | ||
const auto engine_time = _embedderAPI.GetCurrentTime(); | ||
- (void)runTaskOnEmbedder:(FlutterTask)task { | ||
if (_engine) { | ||
auto result = _embedderAPI.RunTask(_engine, &task); | ||
if (result != kSuccess) { | ||
NSLog(@"Could not post a task to the Flutter engine."); | ||
} | ||
} | ||
} | ||
|
||
__weak FlutterEngine* weak_self = self; | ||
- (void)postMainThreadTask:(FlutterTask)task targetTimeInNanoseconds:(uint64_t)targetTime { | ||
__weak FlutterEngine* weakSelf = self; | ||
auto worker = ^{ | ||
FlutterEngine* strong_self = weak_self; | ||
if (strong_self && strong_self->_engine) { | ||
auto result = _embedderAPI.RunTask(strong_self->_engine, &task); | ||
if (result != kSuccess) { | ||
NSLog(@"Could not post a task to the Flutter engine."); | ||
} | ||
} | ||
[weakSelf runTaskOnEmbedder:task]; | ||
}; | ||
|
||
const auto engine_time = _embedderAPI.GetCurrentTime(); | ||
if (targetTime <= engine_time) { | ||
dispatch_async(dispatch_get_main_queue(), worker); | ||
|
||
|
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.
view
is incorrectly capitalized. This should be fixed ASAP as it is a breaking change.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.
Fixing this at: #30996, I will make a follow up PR for the other issues raised.