Second attempt to reland https://github.com/flutter/engine/pull/52023
Fixes since the previous reland attempt:
* We need to pass the skwasm main JS URI when loading the module so that it can pass that along to the worker. Since the worker uses the workaround to allow a cross script worker, it has trouble locating the main JS URI in relation to itself in a way that actually works for dynamic imports, so passing it along fixes that issue.
* Some of the Google3 tests relied on the relative default canvaskit path. Dynamic module imports seems to not handle relative paths the way we expect, so we do our own URL resolution using the URL constructor before passing it into the dynamic import API. Also cleaned up some of the other relative pathing stuff that we do around the base URI. in flutter.js
Safari actually pauses execution of our unit tests if the window becomes occluded or non-visible. As such, I am inserting this egregious hack which just makes the Safari window frontmost every 2 seconds so that the unit tests don't get stalled out.
This should fix https://github.com/flutter/flutter/issues/150023
This PR adds the "Noto Serif Tibetan" fallback font to Flutter Web, so it can render Dzongkha, and other languages in Tibetan script.
(In order to add this fallback font, an automated script is run which updates the versions and glyphs of other fallback fonts at the same time)
(Bundle uploaded to CIPD)
## Issues
* Fixes https://github.com/flutter/flutter/issues/148797
## Testing
* Added unit test for font resolution with sample text
* Manually, in localhost, using the sample Dzongkha test from the Noto site:
<img width="959" alt="Screenshot 2024-05-21 at 2 01 19â¯PM" src="https://github.com/flutter/engine/assets/1255594/3f2db34d-c004-4b90-9fda-62a9cff817f9">
```
à½à½ºà¼à½¡à½à¼ འà½à½à¼à½à¾³à½²à½à¼à½à½à¼à½à½²à¼à½à½²à¼à½à½à½ºà¼à½à½à¼à½à¾²à½à¼à½à¾²à½²à½à½¦à¼ à½à½ºà¼à½£à½¦à¼à½à½£à¼à½à½à½à¼à½à½´à¼à½à½²à¼à½à½à½²à¼à½ à½à¾±à½à¼à½à½à½¼à¼à½à½¼à¼à½à½ºà¼
```
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
At some point, we inherited a change from the repo-level `analysis_options.yaml` that [allowed deprecated](https://github.com/flutter/engine/pull/50575) members to be used. We rely on that analyzer error to prevent `solo: true` from being committed in our tests ([example](c935c3ba36/lib/web_ui/test/ui/line_metrics_test.dart (L179)) of one that slipped recently).
This PR overrides the `deprecated_member_use` error to enable it inside the web engine.
The previous code here introduced an extra slash. Our test platform was tolerant to this extra slash and essentially ignored it, but this probably won't work for most hosting solutions. I went ahead and added some extra validation to the URL when fetching so that we won't serve URLs that have the double slash in their path, in order to catch this if it regresses again.
This is a reland of the change moving the emsdk out of the buildroot, but without the removal of `web_dependencies`, since that removal was causing issues with the rollers.
Reverts: flutter/engine#51299
Initiated by: zanderso
Reason for reverting: Blocking the autoroller
Original PR Author: eyebrowsoffire
Reviewed By: {matanlurey}
This change reverts the following previous change:
This migrates the emscripten toolchain into the flutter repo, as well as the fonts for web unit tests. Also, removed the `web_dependencies` thing which is no longer used.
This fixes https://github.com/flutter/flutter/issues/143332
Depends on a buildroot change here: https://github.com/flutter/buildroot/pull/833
This PR makes some major revisions to our flutter.js bootstrapper.
* Modularize flutter.js into multiple files to make it a little simpler to manage from source code. They are still bundled into a single .js file by esbuild.
* Added a `types.d.ts` file which contains declarations of the types of some of the objects used in the flutter.js API
* Deprecated the old `FlutterLoader.loadEntrypoint` API and added a new function simply called `FlutterLoader.load`, which has a few more capabilities:
- A build tool can inject a build config, that may describe multiple builds that `FlutterLoader.load` can attempt to use. It will use the first one that is compatible with the browser environment and the user's configuration.
- It can also load wasm flutter apps.
- It also pre-loads and instantiates CanvasKit (and Skwasm) as necessary depending on the build configuration.
- `FlutterLoader.load` also immediately takes a flutter configuration object. If an `onEntrypointLoaded` callback is not provided by the user, it just does the expected thing and initializes the engine and immediately starts the app, passing the configuration along as needed.
* `flutter.js` has the engine hash built into it now, which allows it to ascertain the correct CDN URLs for both CanvasKit and Skwasm.
The ulimit logic has been failing for me for months now and felt still
ran fine. I think we don't need it any more.
Also add the `-i` option for incremental runs of `felt`. It causes felt
to start faster because it doesn't run `pub get`. In the future, we can
also run felt from the snapshot for even faster start-up.
Run the JS unit tests with flutter.js.
I am going to leave the dart2wasm tests doing the old `window.flutterConfiguration` setup for now, until I actually get dart2wasm/dart2js switching logic built into flutter.js itself.
* Roll esbuild as a CIPD package along with the browser roller. I renamed `browser_lock`/`browser_roller` etc to `package_lock` and `package_roller` since it will handle more than just browsers now.
* Download the esbuild CIPD package via DEPS.
* Have a build rule for running esbuild on some JavaScript or TypeScript
* Bundle and minify `flutter.js` using esbuild.
* Include in `flutter_web_sdk` the original `flutter.js` source, the minified `flutter.js`, and a sourcemap file to map between thnm.
* Also slightly changed the structure to put the `flutter.js` stuff in `flutter_web_sdk/flutter_js` instead of just at the root level of `flutter_web_sdk`. This should be fine because I haven't merged the change that has the flutter tool consume this yet.
- Update the pinned version of `test` to the latest published.
- Add support for reading the `source.location` of messages to the JS
interop library.
- Update `host.dart` to support the new communication pattern with the
test frame. See https://github.com/dart-lang/test/issues/2065
- Use `Runtime.edge` for the edge browser. We may deprecate or remove
the constant. Edge is a more appropriate value for this usage.
This switches over to using Chrome for Testing instead of Chromium. This requires some changes from the recipes repo (https://flutter-review.googlesource.com/c/recipes/+/51482) in order to coordinate the change in filestructure on the mac versions.
Use the newly exposed functionality in `dart:_wasm` to fix up two different hacks we have:
1) When creating an image from an image source, use `wasm:import` instead of `@Native` and pass the image source directly as an externref. (Direct wasm binding instead of a JS interop shim, yay).
2) When binding the surface callback, previously we were wrapping the callback in a JS function, and then using `WebAssembly.Function` to create a wasm function wrapper around that. Now, we can create a `WasmFuncRef` that is a direct reference to a dart function and pass that over. Now there are no intermediary JavaScript layers when skwasm calls back to us, and we no longer are dependent on the type reflection flag in Chrome.
This fixes https://github.com/flutter/flutter/issues/134556
The PR improves the code size and runtime performance of fallback font selection.
### Performance improvements
Initialization of the data structures to support fallback font selection has been moved from creating the FallbackFontManager (first frame) to the first use, i.e. the first frame actually needing a fallback font.
The numbers reported below are for a lightly edited version of the counter demo that appends to the counter about ~300 missing code points that need ~25 fallback fonts to cover the missing code points. Timings taken from a few profiles on my performance workstation.
| | Before | After |
| --- | ---: | ---: |
| FallbackFontManager() |~100ms | <2ms |
| First need | 0ms | 12ms |
| Subsequent need | 20-30ms | <1ms |
### Size improvements
| | Before | After | Î |
| --- | ---: | ---: | ---: |
| main.dart.js | 1586405 | 1477319 | -109086 (-6.87%) |
| brotli -9 | 427304 | 401611 | -25693 (-6.01%) |
### Algorithm notes
#### Startup
The old algorithm built an interval tree from the code point ranges of the ~140 fallback fonts and uses the interval tree to build a list of fonts that support each missing code point. The new algorithm uses a binary search map that directly produces the list of fonts. There are fewer binary search ranges (~22k) than the aggregate ranges for all the fonts (~26k).
Most of the startup time gain comes from using a data unpacks directly into a useful form rather than needing processing to build an interval tree (~12ms vs ~100ms).
#### Running
The runtime for font selection is greatly improved for several reasons
- The code point space is partitioned into components so that code point counting can be batched.
- When a font is selected, the counts are updated incrementally rather than being recomputed.
- The counts are held in fields of the NotoFont and component objects rather than in Maps or Sets.
Batching, incremental update and avoiding hash tables are roughly multiplicative in effect.
## Issues
- https://github.com/flutter/flutter/issues/131440
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This implements platform views in Skwasm. There are a number of substantial changes rolled up in this change, including:
* Reworked the rendering system to use multiple canvases with a single WebGL context, via ImageBitmap rendering.
* Reworked our object management and bindings to use the `__externref_t` construct in C code.
* Upgraded emscripten to a much newer version
* Generified skwasm's scene builder to be able to work with any renderer that can produce `ImageBitmap` objects from Pictures, and whose `Canvas`, `Picture` and `ImageFilter` objects conform to `SceneCanvas`/`ScenePicture`/`SceneImageFilter`
For platform views themselves, most stuff is implemented except for clipping. I plan on doing that in a subsequent change.
In the spirit of keeping the happy path's output as clean as possible, let's hide the many lines printed by `pub get` even when it's successful.
If `pub get` fails, its output will be printed on the terminal.
A ~~simpler~~ very similar version of https://github.com/flutter/engine/pull/43854
* Makes it harder for users to accidentally remove default configuration values, while still allowing them to do so if needed (configuration is now overridden with a subset of values, rather than passing a full configuration object).
* Moves `merge` from the configuration object and into the override method.
* Removes a test-only configuration option:
* `window._flutter_canvaskit_variant_for_test_only`
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style