-
Notifications
You must be signed in to change notification settings - Fork 6k
[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.