-
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; | ||
|
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. 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" | ||
|
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. 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; | ||
|
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. 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]; | ||
|
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. 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.
viewis 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.