This includes a fix for a race seen in
EmbedderTest.PlatformThreadIsolatesWithCustomPlatformTaskRunner
The implementaion of MergedPlatformUIThread::kMergeAfterLaunch required
changing the interface of the TaskObserverAdd/TaskObserverRemove
callbacks so that TaskObserverAdd returned the TaskQueueId where the
observer was added. That TaskQueueId would later be given to
TaskObserverRemove.
The original implementation of this PR updated the embedder library's
implementation of TaskObserverAdd to return TaskQueueId::kInvalid to
signal that the observer was not added. However, this conflicted with
the embedder's EmbedderTaskRunner, whose implementation of
GetTaskQueueId returns TaskQueueId::kInvalid as a placeholder.
This PR reverts the embedder's TaskObserverAdd/TaskObserverRemove to the
original implementation which adds the observer to the current thread's
message loop and does not call GetTaskQueueId.
See https://github.com/flutter/flutter/issues/167418
If settings.merged_platform_ui_thread is set to kMergeAfterLaunch, then
the engine will be started on the UI thread. After engine setup
completes and the Dart isolate is loaded, the UI task runner will be
merged into the platform thread and all future Dart execution will run
on the platform thread.
This makes it possible for other work to run on the platform thread
while the engine starts.
See https://github.com/flutter/flutter/issues/163064
The cost of bootstapping the initial PSOs can regress cold startup time
for customer money. As an experiment, attempt to defer PSO construction
to skia like.
---------
Co-authored-by: Aaron Clarke <aaclarke@google.com>
Co-authored-by: gaaclarke <30870216+gaaclarke@users.noreply.github.com>
<!-- start_original_pr_link -->
Reverts: flutter/flutter#165261
<!-- end_original_pr_link -->
<!-- start_initiating_author -->
Initiated by: jonahwilliams
<!-- end_initiating_author -->
<!-- start_revert_reason -->
Reason for reverting: bork the tree
<!-- end_revert_reason -->
<!-- start_original_pr_author -->
Original PR Author: jonahwilliams
<!-- end_original_pr_author -->
<!-- start_reviewers -->
Reviewed By: {gaaclarke}
<!-- end_reviewers -->
<!-- start_revert_body -->
This change reverts the following previous change:
The cost of bootstapping the initial PSOs can regress cold startup time
for customer money. As an experiment, attempt to defer PSO construction
to skia like.
<!-- end_revert_body -->
Co-authored-by: auto-submit[bot] <flutter-engprod-team@google.com>
The cost of bootstapping the initial PSOs can regress cold startup time
for customer money. As an experiment, attempt to defer PSO construction
to skia like.
---------
Co-authored-by: Aaron Clarke <aaclarke@google.com>
Co-authored-by: gaaclarke <30870216+gaaclarke@users.noreply.github.com>
Delete remaining DlCanvas method overloads that were allowing the use of
Skia geometry objects in rendering code.
The only remaining uses of Skia classes in the DlCanvas interface are
SkImageInfo and SkTextBlob.
Towards https://github.com/flutter/flutter/issues/163792.
Major changes:
- `enum class AndroidRenderingAPI` physically moves to
`shell/platform/android`
- Store in `FlutterMain` (as a result of `::init`), instead of in
`Settings`
---------
Co-authored-by: Jonah Williams <jonahwilliams@google.com>
Adds an opt in flag for the Android surface control based swapchain.
This is off by default, but added for the sake of bug reports and
investigation of the functionality.
Enables the `-fobjc-arc` compiler flag for Objective-C and Objective-C++
translation units.
Eliminates the flutter_cflags_objc[c]_arc settings, since they're now
redundant.
All Obj-C/Obj-C++ code in our codebase has now been migrated to ARC.
Issue: https://github.com/flutter/flutter/issues/137801
Addresses https://github.com/flutter/flutter/issues/155541
This does **not** remove Skia itself from the build. I'll stage that in a followup. Want to keep the scope of this patch small.
This is the new behavior:
* Impeller is the default on iOS devices **and** simulators.
* On iOS devices **only**, all flags and plist options are ignored.
* On iOS simulators **only**, Flutter will used Impeller's Metal backend by default and fallback to the Null backend if Metal device access is not available.
* On iOS simulators **only**, Flutter can pick Skia using the command line flags or plist flags. This is to allow users one more month to migrate as communicated by @zanderso.
The settings objects `enable_impeller` field is now `static constexpr` to avoid accidentally disabling the flag while it still exists.
I've found a few instances where Vulkan worked correctly but surface control did not. lets add a debugging flag we can ask folks to try to narrow down the issue.
The first part of switching Impeller/Aiks to using the display list instead of re-recording rendering operations. This should eventually let us cut CPU overhead of the raster thread for complex applications, though it should have no impact on GPU performance.
This does introduce a GLES only rendering bug that I haven't had luck tracking down, but is almost certainly due to switching to DL computed depth values. I'd like to handle this as a follow up when we prioritize GLES. https://github.com/flutter/flutter/issues/153504
Part of https://github.com/flutter/flutter/issues/142054
Developers can control the backend in the following ways:
* **Do nothing**: Impeller with Vulkan is used where Vulkan is available with a fallback to Skia with OpenGL.
* **In `AndroidManifest.xml`, specify `io.flutter.embedding.android.EnableImpeller` as `false`**: Skia with OpenGL is used.
* **On the command line, specify `--no-enable-impeller`**: Skia with OpenGL is used.
Manifest options will take priority command line options when there is a conflict. This matches iOS behavior per https://github.com/flutter/flutter/issues/124049 (closed as WAI).
Fixes https://github.com/flutter/flutter/issues/149360
The `//flutter/build/archives:artifacts` target is used to build a zip
archive (artifacts.zip) of host tools such as flutter_tester, the Dart
kernel compiler, the impellerc shader compiler, and other tooling that
is bundled in debug-mode host builds.
This moves the `!is_android` to the definition of
`build_engine_artifacts`. This is required because of the way that we
produce 32-bit arm gen_snapshot for Android on Windows hosts, which
relies on the regular x64 host toolchain due to us having no 32-bit arm
toolchain for Windows. As such, `current_toolchain == host_toolchain` on
that platform.
```
build_engine_artifacts =
flutter_build_engine_artifacts &&
(current_toolchain == host_toolchain ||
(is_linux && !is_chromeos && current_cpu != "arm") || is_mac || is_win)
```
On iOS builds, we don't have this issue since `current_toolchain` will
be one of:
* `//build/toolchain/mac:ios_clang_arm`
* `//build/toolchain/mac:ios_clang_arm_sim`
* `//build/toolchain/mac:ios_clang_x64_sim`
Whereas `host_toolchain` will be one of:
* `//build/toolchain/mac:clang_arm64`
* `//build/toolchain/mac:clang_x64`
This patch also adds documentation to clarify the purpose of this target
and where related artifacts are produced so that future readers don't
need to do a deep dive into our build plumbing to figure this out.
While the target itself is primarily intended for producing host
binaries, one target binary (gen_snapshot) is bundled into the same
archive bundle as the host tools. This should be refactored such that
just like iOS and Android, they are bundled into their own
target-platform-specific archive, and the tool code accordingly updated
to pull these down into the appropriate cache directory.
As a side-note, on macOS we do rely on this archive target for the host
tools, but the bundled gen_snapshot is unused -- instead, one produced
by the //flutter/sky/tools/create_macos_gen_snapshots.py script used.
This should be fixe in a followup patch.
Related: https://github.com/flutter/flutter/issues/38935
Identified while trying to resolve:
Issue: https://github.com/flutter/flutter/issues/101138
Issue: https://github.com/flutter/flutter/issues/69157
## Pre-launch Checklist
- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I added new tests to check the change I am making or feature I am
adding, or the PR is [test-exempt]. See [testing the engine] for
instructions on writing and running engine tests.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [X] I signed the [CLA].
- [X] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-new channel
on [Discord].
<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[test-exempt]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[C++, Objective-C, Java style guides]:
https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
[testing the engine]:
https://github.com/flutter/flutter/wiki/Testing-the-engine
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
Experimentally support merging UI and platform thread on Android/iOS. This works by changing the shell holder to set the UI thread to the platform thread. Several shell APIs that post messages from the platform to ui thread were changed to use RunNowOrPostTask to immediately call the UI task if the threads are the same.
Experimentally, this seems to work reasonably well if there are no platform views. On Android with TLHC it works fine either way, while iOS currently takes a big performance hit.
This can be opted into via a Plist:
```
<key>FLTEnableMergedPlatformUIThread</key>
<true/>
```
Or via AndroidManifest.xml:
```
<meta-data
android:name="io.flutter.embedding.android.EnableMergedPlatformUIThread"
android:value="true" />
```
https://github.com/flutter/flutter/issues/150525
Reverts: flutter/engine#53099
Initiated by: jonahwilliams
Reason for reverting: manifest opt out doens't work.
Original PR Author: jonahwilliams
Reviewed By: {bdero, zanderso, chinmaygarde}
This change reverts the following previous change:
All plugin migrations have landed. Enable impeller by default on Android.
The size of the LTO build of the engine with the dylib compressed is as follows:
```sh
$ du -k libFlutter*
5236 libFlutter.dylib.tar.gz
4324 libFlutterSlimpeller.dylib.tar.gz
```
Sizes are in KiB. This represents a binary size reduction of 17.41% of the compressed artifacts. The compression ratios will likely differ based on the compression scheme.
Uncompressed, the sizes are:
```sh
$ du -k libFlutter*
16920 libFlutter.dylib
14044 libFlutterSlimpeller.dylib
```
This represents a binary size reduction of 16.99% which is in the same ballpark.
The really mucky bit was backing out the raster cache and persistent cache. I want to clean that up in a later patch so that those TUs are part of a separate submodule.
Opting out of Impeller will lead to a fatal log at startup saying the opt-out is disallowed.
Fixes https://github.com/flutter/flutter/issues/126606
Part of https://github.com/flutter/flutter/issues/144439
This does two things:
* Logs a warning when the embedder requests a non-Impeller preference when creating a shell.
* Makes the iOS embedder request a warning be logged when Impeller is not used.
I decided to put the warning logs in the shell so that as we get more opinionated about Impeller on other platforms, those platforms can just flip a flag with common log origin.
This is a prototype of the [PlatformIsolate
API](https://github.com/flutter/flutter/issues/136314).
**UPDATE (Jan 25):** The PR is ready for review. PTAL.
The `PlatformIsolate` creation flow is:
1. `PlatformIsolate.spawn` running on parent isolate
(platform_isolate.dart)
a. Create `isolateReadyPort`
b. `PlatformIsolateNativeApi::Spawn` (platform_isolate.cc)
c. `DartIsolate::CreatePlatformIsolate` (dart_isolate.cc)
d. Isolate created. Entry point invocation task dispatched to platform
thread
e. `PlatformIsolate.spawn` returns a `Future<Isolate>`
2. On the platform thread, `_platformIsolateMain` is invoked in the
platform isolate
a. Create `entryPointPort`
b. Send `Isolate.current` metadata and `entryPointPort` back to the
parent isolate via `isolateReadyPort`
3. Back in the parent isolate, `isolateReadyPort.handler` is invoked
a. Send the user's `entryPoint` and `message` to the platform isolate
via `entryPointPort`
b. Use received isolate metadata to create a new `Isolate` representing
the platform isolate and complete the `Future<Isolate>`
4. In the platform isolate, `entryPointPort.handler` is invoked
a. Run the user's `entryPoint(message)`
The engine shutdown flow is handled by `PlatformIsolateManager`, which
maintains a set of running platform isolates.
1. Makes it possible to implement Impeller Vulkan -> Skia fallback.
2. Fixes https://github.com/flutter/flutter/issues/143871
3. Fixes https://github.com/flutter/flutter/issues/143873
4. Work towards https://github.com/flutter/flutter/issues/137798
Combines AndroidRenderingAPI + enable_impeller into a 4 values enum that describes all combinations of rendering behavior: ImpellerVulkan, ImpellerOpenGLES, SkiaOpenGLES, Software.
Updates the fallback behavior to happen in flutter_main. This allows us to change the value of Settings.enable_impeller to support an Impeller -> Skia fallback.