-
Notifications
You must be signed in to change notification settings - Fork 6k
[macOS] Allow loading of AOT snapshots and instructions from elf bundle #21670
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 |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h" | ||
|
|
||
| #include <algorithm> | ||
| #include <filesystem> | ||
| #include <vector> | ||
|
|
||
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h" | ||
|
|
@@ -162,6 +163,16 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine, | |
|
|
||
| #pragma mark - | ||
|
|
||
| namespace { | ||
|
|
||
| struct AotDataDeleter { | ||
| void operator()(FlutterEngineAOTData aot_data) { FlutterEngineCollectAOTData(aot_data); } | ||
| }; | ||
|
|
||
| using UniqueAotDataPtr = std::unique_ptr<_FlutterEngineAOTData, AotDataDeleter>; | ||
|
|
||
| } | ||
|
|
||
| @implementation FlutterEngine { | ||
| // The embedding-API-level engine object. | ||
| FLUTTER_API_SYMBOL(FlutterEngine) _engine; | ||
|
|
@@ -184,6 +195,9 @@ @implementation FlutterEngine { | |
|
|
||
| // A mapping of textureID to internal FlutterExternalTextureGL adapter. | ||
| NSMutableDictionary<NSNumber*, FlutterExternalTextureGL*>* _textures; | ||
|
|
||
| // Pointer to the Dart AOT snapshot and instruction data. | ||
| UniqueAotDataPtr _aotData; | ||
| } | ||
|
|
||
| - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project { | ||
|
|
@@ -274,6 +288,11 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { | |
| }; | ||
| flutterArguments.custom_task_runners = &custom_task_runners; | ||
|
|
||
| _aotData = [self loadAotData:flutterArguments.assets_path]; | ||
| if (_aotData) { | ||
| flutterArguments.aot_data = _aotData.get(); | ||
| } | ||
|
|
||
| FlutterEngineResult result = FlutterEngineInitialize( | ||
| FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine); | ||
| if (result != kSuccess) { | ||
|
|
@@ -293,6 +312,33 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { | |
| return YES; | ||
| } | ||
|
|
||
| - (UniqueAotDataPtr)loadAotData:(std::string)assetsDir { | ||
|
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. Nit: the correct ObjC naming is
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. macOS embedder style is to declare and document all private methods at the top of the file in the private interface.
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. If you're going to use a |
||
| if (!FlutterEngineRunsAOTCompiledDartCode()) { | ||
| return nullptr; | ||
| } | ||
|
|
||
| std::filesystem::path assetsFsDir(assetsDir); | ||
| std::filesystem::path elfFile("app_elf_snapshot.so"); | ||
|
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. Why is this elf data and not the |
||
| auto fullElfPath = assetsFsDir / elfFile; | ||
|
|
||
| if (!std::filesystem::exists(fullElfPath)) { | ||
| return nullptr; | ||
| } | ||
|
|
||
| FlutterEngineAOTDataSource source = {}; | ||
| source.type = kFlutterEngineAOTDataSourceTypeElfPath; | ||
| source.elf_path = fullElfPath.c_str(); | ||
|
|
||
| FlutterEngineAOTData data = nullptr; | ||
| auto result = FlutterEngineCreateAOTData(&source, &data); | ||
|
Member
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. Doesn't FlutterEngineCreateAOTData require a non-null
Member
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. It does, but this is a non-null pointer to a pointer variable that will be populated on a successful result. On success, the ownership of that variable is given to a unique_ptr with a custom deleter.
Member
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. Ah yep -- lgtm! This seems fine then but someone needs to clean up the struct. |
||
| if (result != kSuccess) { | ||
| NSLog(@"Failed to load AOT data from: %@", @(fullElfPath.c_str())); | ||
| return nullptr; | ||
| } | ||
|
|
||
| return UniqueAotDataPtr(data); | ||
| } | ||
|
|
||
| - (void)setViewController:(FlutterViewController*)controller { | ||
| _viewController = controller; | ||
| _mainOpenGLContext = controller.flutterView.openGLContext; | ||
|
|
||
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.
This doesn't really feel like it's being used as a
unique_ptr, but rather just as an RAII wrapper that does some cleanup on destruction. It doesn't look like this actually deletesaot_dataafter it runs the collect function on it.See the comment below about passing a non-null data ptr to the create function since it's related to lifetime of this struct.