This PR introduces a `NativeAssetsManifest.json` next to the `AssetManifest.json` and `FontManifest.json`. This removes the need for embedding the native assets mapping inside the kernel file and will enable decoupling native assets building and bundling from the kernel compilation in flutter tools. This will then allow us to remove dry-run from the build hook protocol.
(It also means all isolate groups will have the same native assets. However, since Flutter does not support `Isolate.spawnUri` from kernel files anyways, this is not a regression.)
This manifest is parsed eagerly on startup by the engine in a manner similar to how the font manifest is parsed. The manifest contents need to be available in the callback for resolving assets, which does not have access to the engine. Therefore the parsed manifest is `NativeAssetsManager` stored in the `IsolateGroupData`. The engine passes it in on isolate group creation, and the FFI callbacks access it from the isolate group data.
Issue:
* https://github.com/flutter/flutter/issues/154425
Related PRs:
* https://dart-review.googlesource.com/c/sdk/+/388161
Follow up work:
* This PR does not yet remove the engine callbacks registered via the dart_api that rely on kernel embedding. If we were to do that in this PR, it would require a manual roll of the engine into flutter/flutter with the PR that switches flutter_tools to emit the native assets manifest instead of embedding in kernel, and a manual roll into g3 to switch emitting a manifest instead of embedding in kernel. A TODO is left in the code for those callbacks to be removed.
## Testing
Most of this PR cannot be tested in isolation. The code in this PR is heavily exercised in the follow up flutter_tools PR which creates the `NativeAssetsManifest.json` and removes the embedding of native assets in kernel files.
* This PR adds a unit test for parsing the JSON manifest.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Flutter_tester has a task observer that checks whether the test's Dart code has finished execution. If Dart no longer has live ports but does have pending microtasks, then flutter_tester should continue running and force a drain of the microtask queue.
Fixes https://github.com/flutter/flutter/issues/158129
When running with merged platform and ui threads, set the dart thread name of the main thread to io.futter.ui. Also change the thread mask settings to avoid creating an unused UI thread.
ui.Canvas and ui.SceneBuilder now use the DlPath object directly from the ui.Path object. This results in increased sharing of the wrapper objects which then increases the sharing of both the converted Impeller paths and Skia's volatile flag.
The VolatilePathTracker mechanism is deleted and rather than count the number of frames that a path is stable for, instead we count the number of times it is used for rendering. If a path is used 100 times in a single frame, it will become non-volatile and start being cached almost immediately. The cached Impeller paths are now also tracked for all instances of the same path, rather than for each call site that originated from a DisplayList dispatch.
This is a re-land of https://github.com/flutter/engine/pull/55006, except that we special case the navigation channel to immediately dispatch its message if the isolate is not yet running.
This preserves the existing behavior relied upon by several iOS add2app tests, as well as the still used embedder v1 - and potentially undicovered future embedders.
We used to require this only on iOS because the standard library till iOS 9 didn't have support for this. We have moved past that version. No change on other platforms.
This initializes the `NativeAssetsApi` for native assets resolution in the isolate group creation callback.
* https://github.com/dart-lang/sdk/issues/55523
## Implementation considerations
The DartIO initialization lives in its own GN target. This doesn't work for the native assets initialization due to it having to look up the `script_uri` in one of the callbacks. Since the callbacks are function pointers, we can't have a lambda that captures the script uri. So instead, the native assets initialization lives in the flutter/runtime target.
The import from dart should probably be `runtime/include/bin/native_assets_api.h` to mirror what we're doing with dart IO, rather than directly importing from `runtime/bin/native_assets.h`.
## Testing
All native asset testing is in flutter_tools, so those tests will only run once this rolls into flutter/flutter. I have done manual testing locally with a Dart branch that removes the fallback: https://dart-review.googlesource.com/c/sdk/+/370740
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This is a refactor that moves the `PointerDataPacketConverter` from `PlatformView` to `RuntimeController`.
This change is made for the following reasons:
- Currently, the pointer data conversion contains no platform specific logic (because the current converter's only responsibility is to make the event sequence conform Flutter's protocol). Therefore these logics should reside in a platform-independent place.
- The converter typically converts one event to many. It's better to have this conversion later than earlier.
- It removes a member from `PlatformView`, making it closer to a pure virtual class.
The reason to choose `RuntimeController` as the destination is because `RuntimeController` manages a map for views, which is required for the converter to implement a later patch https://github.com/flutter/engine/pull/51925.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Some embedders use a custom platform task runner that does not support fml::MessageLoopTaskQueues and may not have an fml::MessageLoop.
To support those embedders, DartIsolate::SetMessageHandlingTaskRunner will not use fml::MessageLoopTaskQueues for platform isolates.
See https://github.com/flutter/engine/pull/48551#issuecomment-1962190896
* Do not check IsolateIsShutdown after CreateAndRegisterIsolate in the MultithreadedCreation test.
The test's main thread could run ShutdownPlatformIsolates between a worker thread's calls to CreateAndRegisterIsolate and IsolateIsShutdown. If that happens, IsolateIsShutdown will return true even though CreateAndRegisterIsolate succeeded.
* Change the is_registered flag to was_registered and do not clear it during isolate shutdown
Tests like MultithreadedCreation need to know whether RegisterPlatformIsolate succeeded so they can determine if the isolate will be shut down by ShutdownPlatformIsolates or if it needs to be shut down explicitly. If the flag is cleared during shutdown, then the test may see an isolate that was successfully registered and shut down and think that it was never registered.
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.
Flutter implements the UI isolates message via posting to a UI task queue. That task queue has a primary and a secondary queue. The
* primary is used for running tasks resulated to framework (e.g. draw frame)
* secondary is used to run Dart event loop messages (e.g. received data on a socket)
The Dart semantics requires running microtasks before processing the next event loop message.
The way flutter implements by attaching an observer to the secondary queue. Every time a task from the queue is run, all observers are run and one of them is going to run pending microtasks.
In some situations the engine pauses the dart event loop. The terminology used in the code is "microtask" when in reality what it means is "event loop".
=> This PR changes this terminology to reflect what actually happens.
This enables work ongoing by @derekxu16 to improve performance in flutter_tester when running multiple files from large test suites.
Specifically, it:
- Exposes a `Spawn` C symbol from flutter_tester that runs the current kernel in a new UI isolate with a different entrypoint and/or route name
- Exposes two symbols from flutter_tester to allow a test harness to more efficiently load particular kernel files or to lookup an entrypoint from an imported source file.
- Avoids re-loading the kernel file completely when spawning a new UI isolate
Googlers can look at go/flutter-tester-isolates for some more context. If anyone wants I'm happy to create a public version of that doc.
This is part of the work towards supporting OpenGLES and Vulkan for runtime stage shaders.
Removes some redundant work we had around SkSL. Now only bundles the shaders we actually ask for from the command line.
@bdero, we should figure out if this is the right approach for flutter_gpu.
With this change, the IPLR format goes from having a root table of shader related information to a root table of shader information per `sksl`, `metal`, `opengles`, and `vulkan` platforms.
This may end up allowing us to revert https://github.com/flutter/engine/pull/47278, but I'm not sure I understand all the implications of that at this point.
I have run some but not all tests locally.
This reverts commit 87171e73397f7edfd4c145fbaebdd7208954debf.
Internal performance test shows that this PR negatively affects startup time. I'll reland this PR in parts.
b/307872797
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This keeps things consistent with other imports and fixes the internal breakage (b/314687390).
While the build system here is able to handle imports both with and without the `flutter` prefix, the internal mechanism that rewrites these imports is currently unable to handle the latter case.
Found by @mraleph while looking at flutter_tester related things with me.
I took some suggestions from him and added a test. This should eventually help speed up running large multi-file test suites.
The test is a little bit wonky because we don't have great inspection points (e.g. something to mock or examine from a test). It should break if we change the way we load kernel assets in the test harness, and is verifying that we only ask for the test asset once where we used to ask for it twice.
Towards https://github.com/flutter/flutter/issues/134501.
This PR makes the following changes to the public dart:ui API:
* It adds the `FlutterView.pysicalConstraints` property that describes max and min width and height for a view. The framework is allowed to size the `FlutterView` to any `Size` that meets these constraints.
* It adds an optional `size` argument to `FlutterView.render`. The framework provides the chosen `Size` that meets the aforementioned constraints to the `render` method. If the `FlutterView.pysicalConstraints` are tight (minHeight == maxHeight and minWidth == maxWidth) the argument is optional to remain backwards compatible. In all other cases, a `Size` must be provided.
* It adds a `ViewConstraints` class, which is basically the `dart:ui` version of `BoxConstraints` (This is similar to how we have `ViewPadding` in dart:ui to mirror `EdgeInsets` from the framework). It describes the constraints of a `FlutterView`, i.e. it powers the `FlutterView.pysicalConstraints` property.
This change does not wire anything up to the embedders. For now, `FlutterView.pysicalConstraints` just returns tight constraints for the embedder-provided size of the view (`FlutterView.physicalSize`) and the size provided to `FlutterView.render` is ignored (after it is checked that it meets the constrains).
This PR enables the framework to implement the new dynamic view sizing and embedders to separately expose the new functionality to their clients.
Presubmits will fail until https://github.com/flutter/flutter/pull/138565 is submitted to the framework.
**DO NOT SUBMIT until https://github.com/flutter/flutter/pull/138648 is ready.**
The new `BUILD.gn` files in the Engine tree can't go under
`build/secondary` because Skia still has its own, and they'd be selected
first. So, this PR puts the new `BUILD.gn` files under `flutter/skia`.
As part of eliminating the Flutter buildroot
(https://github.com/flutter/flutter/issues/67373), we are moving all
third-party dependencies from //third_party to //flutter/third_party.
Once all third-party dependencies have been migrated, tooling and config
will be moved and the buildroot will be eliminated altogether.
No tests changed because there is no semantic change to this PR. This is
simply relocating a dependency.
This PR relands https://github.com/flutter/engine/pull/44473.
The previous PR was immediately reverted after merging because we found that the PR could cause illegal renders to be skipped on debug builds but crash the app on release builds. This PR makes the `Animator::Render` skip illegal renders as well. This should not be the final shape of this feature, and thus a TODO is added.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style