393 Commits

Author SHA1 Message Date
Jason Simmons
c53fdbdf24
Reduce app startup latency by initializing the engine on a separate thread (#166918)
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
2025-04-17 21:40:08 +00:00
Matej Knopp
a400e79ce6
[Embedder] Only call removeview callback when raster thread is done with the view (#164571)
Fixes
https://github.com/flutter/flutter/issues/164564#issuecomment-2698714466

This would ensure that raster thread is completely done with the view,
i.e. it won't try to use the opengl context, which might be associated
with view window. So the client can know for sure, that when the
callback returns, it is safe to destroy the view and container window.

## 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], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [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/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
2025-04-04 18:38:19 +00:00
chunhtai
bf6481104d
Revert "Add set semantics enabled API and wire iOS a11y bridge (#1612… (#165901)
…65)"

This reverts commit 26037dff87ade9d9dee04cc2ef90b3fe5cf0faf3.

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

PR causes internal test failures

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] 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/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-03-25 18:24:46 +00:00
chunhtai
26037dff87
Add set semantics enabled API and wire iOS a11y bridge (#161265)
fixes https://github.com/flutter/flutter/issues/158399

old pr https://github.com/flutter/engine/pull/56691

previously the only correct way to enable semantics is that ios
embedding receive signal from native OS, it call SetSemanticsEnabled to
shell and then to dart to enable semantics tree generation.

If for some reason framework decide to enable semantics first, e.g.
through SemanticsBinding.instance.ensureSemantics(typically due to
integration test or ci that wants to test semantics), the update will be
dropped in shell. Even if it later on receive signal from native OS to
turn on semantics, it can't construct the complete accessibility tree in
embedding because the updatesemantics sends diff update and previous
updates are gone forever. It will end up in a broken state.

This pr changes so that the only source of truth will be in the
framework side. When framework starts generating the the semantics tree,
it will call SetSemanticsTreeEnabled through dart:ui, and the embedding
needs to prepare itself to accept semantics update after receiving the
message.

This however require some refactoring on iOS embedding because it will
only create a11y bridge when receiving OS notification when assitive
technologies turns on.

This requires three phase transition

add an empty dart:ui API setSemanticsTreeEnabled
makes framework calls the empty API.
merge this pr with actual implementation of setSemanticsTreeEnabled

I will do the android part in a separate pr


## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] 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/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-03-24 20:11:13 +00:00
Jason Simmons
08d2703016
Roll libcxx to bd557f6f (#165621)
Changes required for this roll:
* addition of LLVM libc (which is now a dependency of libcxx)
* updates the to license script
* patching the verify_exported check to allow some symbols added by
libcxx
* annotations for clang-tidy warnings
2025-03-24 15:39:26 +00:00
Matthew Kosarek
554c814ada
(#112207) Adding view_id parameter to DispatchSemanticsAction and UpdateSemantics (#164577)
fixes #112207

## What's new?
- Added a `view_id` on `UpdateSemantics`
- Added a `view_id` on `DispatchSemanticsAction`
- Piped the `view_id` all over creation
- Updated tests for these actions across the different platforms
- Added `FlutterEngineSendSemanticsAction` to the embedder API in order
to not break `FlutterEngineDispatchSemanticsAction`
- Using this view ID properly on the Windows platform (see
`engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc`)

## How to test
1. Checkout
[foundation-plus-framework](https://github.com/canonical/flutter/pull/36)
from canonical/flutter
2. Merge this branch into it
3. Enable the "Narrator" screen reader on windows
4. Run the Multi window reference app (see
[PR](https://github.com/canonical/flutter/pull/36) for details)
5. Open up another window, and note that the right buttons and things
are being highlighted, as the screenreader would expect 🎉

## 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], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
2025-03-20 16:30:07 +00:00
Matej Knopp
940fb3c8b1
[Embedder] Wire view focus event and focus request (#163930)
This wires `PlatformDispatcher.onViewFocusChange` and
`PlatformDispatches.requestViewFocusChange` through embedder API.

*If you had to change anything in the [flutter/tests] repo, include a
link to the migration guide as per the [breaking change policy].*

## 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 readand followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [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/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Matthew Kosarek <matt.kosarek@canonical.com>
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
2025-02-25 17:37:06 +00:00
Jonah Williams
72cc1d198c
[iOS] always post new task during gesture dispatch. (#163646)
Fixes https://github.com/flutter/flutter/issues/163429

If we synchronously call into dart ui when dispatching pointer events,
then we only end up scheduling about ~half as many frames as we should.
Nothing is blocked, no task starvation, et cetera. It should always be
safe to post pointer events as a new task instead.
2025-02-19 22:52:07 +00:00
Matej Knopp
94cd4b14c9
[Embedder] Implement merged platform and UI thread (#162944)
Fixes https://github.com/flutter/flutter/issues/152337

Introduces `ui_task_runner` field on `FlutterCustomTaskRunners`. This
lets the embedder to specify task runner for UI isolate tasks, allowing
for merging platform and UI threads.

With custom UI task runner there is no `MessageLoop` anymore for the UI
thread, so the message loop task observer can no longer be used to flush
microtask queue. Instead the microtask queue is flushed at the end of
each `FlutterEngineRunTask` invocation if needed. This is handled
internally by the embedder.

## 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], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [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/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Jonah Williams <jonahwilliams@google.com>
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
2025-02-11 12:24:13 +00:00
Jim Graham
9af7a2a64d Migrate layers and layer_tree to DisplayList/Impeller geometry classes (flutter/engine#57153)
Migrates Layers and LayerTree and parts of the `flow/` utility classes to use DlGeometry (Impeller) classes.
2024-12-12 19:30:55 +00:00
Jonah Williams
f8a0105146 [engine] changes to DlVertices::Builder and Stopwatch visualizer. (flutter/engine#57031)
Collection of changes to DlVertices::Builder and the stopwatch visualizer.

At a high level:

* improve performance of the stopwatch visualizer by pre-allocating storage (and sharing it across both visualizers), lookup up font once, and cache the debug frame rate used. Updates to use Dl types instead of SkTypes.

* Change DlVerticesBuilder to allow storing the bounds and use that in the visualizer, since we already know them. Make FML_CHECKS into dchecks, as the dart:ui vertices will already bounds check correctly - so these should only be necessary for debugging engine changes.
2024-12-11 21:03:06 +00:00
Jonah Williams
2e80dbea2c [Impeller] create a 300 es variant of all GLES shaders to support UBO binding. (flutter/engine#56960)
Create a GLES3 "backend" by compiling a second set of GLES shaders to 300 es. This allows the usage of UBOs and SSBOs.
2024-12-05 20:56:16 +00:00
Jonah Williams
fb62aa5d47 [engine] reland: more consistently flush message loops tasks (flutter/engine#56815)
Changes the following shell callbacks to flush the dart event loop:

* OnPlatformViewSetViewportMetrics
* OnPlatformViewDispatchPointerDataPacket
* OnPlatformViewDispatchPlatformMessage
* OnPlatformViewSetSemanticsEnabled
* OnPlatformViewSetAccessibilityFeatures
Using a new TaskRunner API RunNowAndFlushMessages. If the task runner can run tasks on the current thread, this will immediately invoke a callback and then post an empty task to the event loop to ensure dart listeners fire.

Unlike https://github.com/flutter/engine/pull/56738, does not touch the vsync API - which looks like it depends on scheduling behavior today, at least for iOS.
2024-11-26 22:34:00 +00:00
auto-submit[bot]
2805143dd5 Reverts "[engine] more consistently flush dart event loop, run vsync callback immediately (#56738)" (flutter/engine#56767)
Reverts: flutter/engine#56738
Initiated by: jonahwilliams
Reason for reverting: speculative revert for framework failures.
Original PR Author: jonahwilliams

Reviewed By: {jason-simmons}

This change reverts the following previous change:
Changes the following shell callbacks to flush the dart event loop:

* OnPlatformViewSetViewportMetrics
* OnPlatformViewDispatchPointerDataPacket
* OnPlatformViewDispatchPlatformMessage
* OnPlatformViewSetSemanticsEnabled
* OnPlatformViewSetAccessibilityFeatures

Using a new TaskRunner API RunNowAndFlushMessages. If the task runner can run tasks on the current thread, this will immediately invoke a callback and then post an empty task to the event loop to ensure dart listeners fire.

This also updates the vsync waiter to use RunNowOrPostTask, so that we start vsync events as early as possible.
2024-11-22 23:51:26 +00:00
Jonah Williams
602ab9846d [engine] more consistently flush dart event loop, run vsync callback immediately (flutter/engine#56738)
Changes the following shell callbacks to flush the dart event loop:

* OnPlatformViewSetViewportMetrics
* OnPlatformViewDispatchPointerDataPacket
* OnPlatformViewDispatchPlatformMessage
* OnPlatformViewSetSemanticsEnabled
* OnPlatformViewSetAccessibilityFeatures

Using a new TaskRunner API RunNowAndFlushMessages. If the task runner can run tasks on the current thread, this will immediately invoke a callback and then post an empty task to the event loop to ensure dart listeners fire.

This also updates the vsync waiter to use RunNowOrPostTask, so that we start vsync events as early as possible.
2024-11-22 07:47:17 +00:00
Jonah Williams
d838b4bd03 [engine] force semantics action to post a task. (flutter/engine#56514)
Repro:

Testing WIP.

b/373761573

```dart

import 'package:flutter/material.dart';

void main() {
  runApp(const Example());
}

class Example extends StatefulWidget {
  const Example({super.key});

  @override
  State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  bool value = true;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Semantics(
            child: Text(
              value ? 'Hello, world!' : 'Goodbye, World!',
            ),
            button: true,
            onTap: () async {
              await null;
              setState(() {
                value = !value;
              });
            },
          ),
        ),
      ),
      );
  }
}

```
2024-11-13 01:06:05 +00:00
Jason Simmons
ef5c2fc014 Do not stop flutter_tester if microtasks are still pending (flutter/engine#56432)
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
2024-11-11 19:22:07 +00:00
Jason Simmons
c6cbbc775c On a merged UI/platform thread, immediately execute platform message handlers and then run microtasks (flutter/engine#55933)
Shell::OnPlatformViewDispatchPlatformMessage is called on the platform thread and must invoke the message handler on the UI thread.  If the platform and UI threads are merged, then the handler can be run immediately.  The shell can then post an empty task to the UI thread to make the UI message loop run the task observer that drains the microtask queue.

Fixes https://github.com/flutter/flutter/issues/156595
2024-10-18 14:01:28 +00:00
Jim Graham
7da9ad1862 Delete VolatilePathTracker in favor of Dispatch tracking (flutter/engine#55125)
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.
2024-09-13 21:49:09 +00:00
Jonah Williams
0a0883219e [engine] dispatch platform channel messages through event loop, except navigation on start. (flutter/engine#55027)
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.
2024-09-08 17:38:18 +00:00
auto-submit[bot]
f84f9c92b5 Reverts "[engine] reland: always post tasks for platform channel responses. (#55006)" (flutter/engine#55022)
Reverts: flutter/engine#55006
Initiated by: jonahwilliams
Reason for reverting: still failling mac module test
Original PR Author: jonahwilliams

Reviewed By: {jason-simmons}

This change reverts the following previous change:
Reland of https://github.com/flutter/engine/pull/54975

Fixes the initial route behavior for iOS. Previously the initial route setting would _always_ be posted as a task, which after merging the threads would fire after isolate creation, thus it would not actually update the initial route setting. Fixed Engine constructor so that it reads the initial route from the settings.
2024-09-07 02:56:46 +00:00
Jonah Williams
8ca7e1cd90 [engine] reland: always post tasks for platform channel responses. (flutter/engine#55006)
Reland of https://github.com/flutter/engine/pull/54975

Fixes the initial route behavior for iOS. Previously the initial route setting would _always_ be posted as a task, which after merging the threads would fire after isolate creation, thus it would not actually update the initial route setting. Fixed Engine constructor so that it reads the initial route from the settings.
2024-09-06 23:48:09 +00:00
auto-submit[bot]
f3c121ecb5 Reverts "[engine] always force platform channel responses to schedule a task. (#54975)" (flutter/engine#55000)
Reverts: flutter/engine#54975
Initiated by: jtmcdole
Reason for reverting: I believe this change caused flutter/flutter to break in an engine roll. It was one of two changes - the other being a webui change.

Tests broken:

module_test_ios:  testDualCold

router test:

```
[2024-09-05 17:43:20.837343] [STDOUT] stderr: [ +135 ms] VMServiceFlutterDriver: Connected to Flutter application.
[2024-09-05 17:43:20.841927] [STDOUT] stdout: [   +4 ms] 00:00 +0: 
Original PR Author: jonahwilliams

Reviewed By: {jason-simmons, johnmccutchan}

This change reverts the following previous change:
If we use runNowOrPostTask on platform channel responses, then we may not wake up the dart message loop. If nothing else wakes it up, then the embedder may hang on platform channel responses.

This fixes several google3 integration tests when run in merged thread mode.
2024-09-06 15:54:46 +00:00
Jonah Williams
326bd99dc9 [engine] always force platform channel responses to schedule a task. (flutter/engine#54975)
If we use runNowOrPostTask on platform channel responses, then we may not wake up the dart message loop. If nothing else wakes it up, then the embedder may hang on platform channel responses.

This fixes several google3 integration tests when run in merged thread mode.
2024-09-05 20:49:56 +00:00
Jonah Williams
9808dcbb8f [engine] remove raster stats feature. (flutter/engine#54187)
This debugging tool does not give accurate measurements and we've decided to remove it.

See also: https://github.com/flutter/flutter/issues/131941
2024-07-29 20:30:52 +00:00
Jonah Williams
d11db4f8c9 [engine] support combined UI/Platform thread for iOS/Android. (flutter/engine#53656)
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
2024-07-09 19:32:20 +00:00
Jonah Williams
acf48b5a05 [engine] null check texture registry in OnPlatformViewMarkTextureFrameAvailable. (flutter/engine#53334)
From the issue, it looks like an NPE in this closure, we're not sure what else it could be besides the weak ptr - which could be null.

Fixes https://github.com/flutter/flutter/issues/149895
2024-06-11 16:48:03 +00:00
Chinmay Garde
f20b17a2ae [Impeller] Prepare a SkiaGPU-less iOS build. (flutter/engine#52748)
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
2024-05-13 21:43:47 +00:00
Tong Mu
dc82dbb0b9 Move Shell::Add/RemoveView to PlatformView and refine embedder API doc (flutter/engine#52003)
This PR moves the methods to add or remove views from `Shell` to
`PlatformView`. By design, the `Shell` is supposed to be a messenger
that glues classes together, while `PlatformView` is the operator that
embedders that do not use the embedder API should operate on. The
current design was made due to lack of knowledge to this design.

This also makes `PlatformView` aware of views, which might be a
prerequisite to https://github.com/flutter/engine/pull/51925.

This PR also adds some details to embedder API `AddView` and
`RemoveView`.

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] 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.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I signed the [CLA].
- [ ] 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
2024-04-11 13:26:24 -07:00
Chinmay Garde
22be0b9fa4 [Impeller] Enable logging a warning when the user opts out of using Impeller. (flutter/engine#51849)
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.
2024-04-03 19:52:51 +00:00
Loïc Sharma
a01206ad39 Add completion callback to Shell::AddView (flutter/engine#51659)
In the future, `FlutterEngineAddView` will be added to the embedder API to allow embedders to add views. `FlutterEngineAddView` will accept a callback that notifies the embedder once the view has been added.

This embedder API will be powered by `Shell::AddView`. This change adds a completion callback to `Shell::AddView` to prepare for the embedder API.

Design doc: https://flutter.dev/go/multi-view-embedder-apis

Part of https://github.com/flutter/flutter/issues/144806
Part of https://github.com/flutter/flutter/issues/142845

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
2024-03-29 00:39:10 +00:00
Loïc Sharma
21c9a731f0 [Embedder API] Remove view (flutter/engine#51400)
Adds `FlutterEngineRemoveView` to the embedder API. This will be used to destroy a view.

The embedder API does not allow embedders to create multiple views yet.

Design doc: https://flutter.dev/go/multi-view-embedder-apis

Part of https://github.com/flutter/flutter/issues/144806
Part of https://github.com/flutter/flutter/issues/142845

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
2024-03-18 18:23:22 +00:00
Liam Appelbe
27ca389132 Experimental platform isolates API (flutter/engine#48551)
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.
2024-03-04 16:47:41 +13:00
Dan Field
ce731f3716 Fix Shell::Screenshot for Impeller (flutter/engine#50072)
Fixes https://github.com/flutter/flutter/issues/141571

Shell::Screenshot was impelemnted in a Skia-only way and would crash when invoked. Adds test coverage for the breaking path on iOS that ends up calling `FlutterView drawLayer`.
2024-01-26 17:17:32 +00:00
Dan Field
ae9289f5c1 [Impeller] Make IPLR files multi-platform (flutter/engine#49253)
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.
2023-12-21 06:17:26 +00:00
gaaclarke
002ab77448 Expanded the performance lints (flutter/engine#47868)
fixes https://github.com/flutter/flutter/issues/137372

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
2023-11-09 23:54:01 +00:00
gaaclarke
52fcefb32a Made clang tidy use arm64 if on an arm64 mac. (flutter/engine#47494)
fixes https://github.com/flutter/flutter/issues/137260

## 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

---------

Co-authored-by: Zachary Anderson <zanderso@users.noreply.github.com>
2023-10-31 15:35:36 -07:00
John McCutchan
632d65292d Don't re-initialize the default RenderSurface when returning from hybrid composition mode (flutter/engine#47358)
When we enter hybrid composition mode we 'pause' the default RenderSurface (implemented by SurfaceView or TextureView) and swap to an ImageReader based RenderSurface.

When we return from hybrid composition mode we recreate and re-initialize the real RenderSurface as if it was being used for the first time.

This broke Platform Views in an internal app b/306122497 because we would incorrectly tell the texture to attach when it was never detached.

This CL changes the protocol so that when we return from hybrid composition mode we only swap the RenderSurface and do not re-create it. This avoids doing a bunch of unnecessary work and fixes the logic error of re-attaching textures that were never detached.

*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.*

*List which issues are fixed by this PR. You must list at least one issue.*

*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
2023-10-27 00:33:23 +00:00
gaaclarke
2b28dc130d Adds lint for checking argument commments (flutter/engine#47305)
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
2023-10-25 17:21:09 +00:00
Jonah Williams
063c7f54f4 [Impeller] Disable raster stats service protocol. (flutter/engine#47206)
As far as I can tell, this functionality has _always_ been falling back to software rendering with Skia when Impeller was enabled. This is at best extremely misleading. Since I started putting Impeller specific objects in the display list it introduced crashes, and must be disabled.

Fixes https://github.com/flutter/flutter/issues/136847
2023-10-23 18:45:18 +00:00
Tong Mu
6584b2c308 Reland 2 (part 1): Enforce the rule of calling FlutterView.Render (flutter/engine#47062)
This PR relands part of https://github.com/flutter/engine/pull/45300,
which was reverted in https://github.com/flutter/engine/pull/46919 due
to performance regression.

Due to how little and trivial production code the original PR touches, I
really couldn't figure out the exact line that caused it except through
experimentation, which requires changes to be officially landed on the
main branch. After this PR lands, I'll immediately fire a performance
test.

This PR contains the `Shell` refactor of the original PR. I made a
slight change where the isolate snapshot is no longer returned through
return value, but the parameter, in order to avoid the overhead of
assigning.

It is intentional to not contain any unit tests or other changes of the
original PR. They will be landed shortly after this PR.

Part of https://github.com/flutter/flutter/issues/136826.

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] 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.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I signed the [CLA].
- [ ] 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
2023-10-18 14:09:01 -07:00
Tong Mu
f263e6a49f Revert "Reland: Enforce the rule of calling FlutterView.Render (#45300)" (flutter/engine#46919)
Reverts flutter/engine#45555 due to possible performance regression, b/304898239
2023-10-16 05:37:20 +00:00
Dan Field
1e318d57d4 [Impeller] flutter_tester --enable-impeller (flutter/engine#46389)
This patch does the following:

- Updates `flutter_tester` to set up an Impeller rendering context and surface if `--enable-impeller` is set to true, using the Vulkan backend with Swiftshader.
- Updates `run_tests.py` to run all tests except the smoke test (that one really has no rendering impact whatsoever) with and without `--enable-impeller`.
- Updates a few tests to work that were trivial:
  - A couple tests needed updated goldens for very minor rendering differences. Filed https://github.com/flutter/flutter/issues/135684 to track using Skia gold for this instead.
  - Disabled SKP screenshotting if Impeller is enabled, and updated the test checking that to verify an error is thrown if an SKP is requested.
  - The Dart GPU based test now asserts that the gpu context is available if Impeller is enabled, and does not deadlock if run in a single threaded mode.
  - We were missing some trace events around `Canvas::SaveLayer` for Impeller as compared to Skia.
  - A couple other tests had strict checks about exception messages that are slightly different between Skia and Impeller.
- I've filed bugs for other tests that may require a little more work, and skipped them for now. For FragmentProgram on Vulkan I reused an existing bug.

This is part of my attempt to address https://github.com/flutter/flutter/issues/135693, although @chinmaygarde and I had slightly different ideas about how to do this.

The goals here are:

- Run the Dart unit tests we already have with Impeller enabled.
- Enable running more of the framework tests (including gold tests) with Impeller enabled.
- Run all of these tests via public `dart:ui` API rather than mucking around in C++ internals in the engine.
2023-10-11 21:42:24 +00:00
Kevin Lubick
5d70f10ebb Add Base64::EncodedSize to tidy up allocations (flutter/engine#46624)
As a follow-up to #46543, this adds a dedicated function to compute the
size of the buffer needed to encode data using Base64 instead of calling
the encode function with nullptr.

## 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].
- [ ] 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
2023-10-06 16:50:20 -04:00
Kevin Lubick
ec62430ff1 Replace use of Skia's Base64 Encoding/Decoding logic with a copy of the equivalent code (flutter/engine#46543)
Skia would like to remove SkBase64.h from its public API. This ports the
same functionality into Flutter's codebase with tests.

The implementation was copied from
[Skia](387853af19/src/utils/SkBase64.cpp)
then modified to match Flutter's style and have readable tests.

In a follow-up PR, I would like to add a function to pre-flight the
calculation needed to figure out how many
bytes are needed to be allocated, to avoid the clunky double API
call (see the TODOs).

I chose to put the code in `//shell/common` at the suggestion of Flutter
devs, but it needs to be in its own source_set because it is used in a
few other places (for now) and we want to avoid dependency cycles.

## 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].
- [ ] 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
2023-10-05 10:21:39 -04:00
Tong Mu
c7f206212a Multi-view Rasterizer (flutter/engine#45512)
This PR refactors `Rasterizer` so that it's more suitable for multi-view.

Design doc: [flutter.dev/go/multi-view-pipeline-and-rasterizer](http://flutter.dev/go/multi-view-pipeline-and-rasterizer)

With this change, `Rasterizer::DrawToSurfaces` has a structure that can handle drawing to multiple views, although the lack of some functionality still blocks it, mostly related to `ExternalViewEmbedder` and `RasterCache`. 

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
2023-09-29 21:43:55 +00:00
Tong Mu
38b8ce1c29 Reland: Enforce the rule of calling FlutterView.Render (#45300) (flutter/engine#45555)
This PR relands #45300 which was reverted in https://github.com/flutter/engine/pull/45525 due to hanging on a windows startup test. The culprit test still calls `FlutterView.render` in the illegal way, which is ignored, causing no frame being ever produced. This has been fixed in https://github.com/flutter/flutter/pull/134245. I've also searched through the framework repo for `render(` to ensure there are no other cases.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
2023-09-21 21:11:03 +00:00
Matan Lurey
476b46954c Migrate from LOG_X to kLogX. (flutter/engine#46107)
These should be entirely non-breaking, i.e. 1:1 and same backing `int`
value.

(See https://github.com/flutter/engine/pull/46052)
2023-09-20 13:24:01 -07:00
Zachary Anderson
a1dcb39a45 Revert "Enforce the rule of calling FlutterView.Render" (flutter/engine#45525)
Reverts flutter/engine#45300

Speculative revert for the post-submit framework CI failure in `windows_startup_test`: https://ci.chromium.org/ui/p/flutter/builders/prod/Windows%20windows_startup_test/6227/overview
2023-09-07 01:35:09 +00:00
Tong Mu
0b39609150 Enforce the rule of calling FlutterView.Render (flutter/engine#45300)
This PR enforces the rules as documented in `FlutterView.Render`, where
calls in illegal situations should be ignored - but have never been
enforced.

```
  /// This function must be called within the scope of the
  /// [PlatformDispatcher.onBeginFrame] or [PlatformDispatcher.onDrawFrame]
  /// callbacks being invoked.
  ///
  /// If this function is called a second time during a single
  /// [PlatformDispatcher.onBeginFrame]/[PlatformDispatcher.onDrawFrame]
  /// callback sequence or called outside the scope of those callbacks, the call
  /// will be ignored.
```

This rule is very important to implementing multi-view without having to
introduce new APIs. However, currently these illegal calls are not
ignored, and historically many tests (especially integration tests) were
unknowingly running based on this fact. @goderbauer did great work by
eliminating these cases in g3, and it's time for us to make sure these
calls are ignored.

Most effort of this PR goes to unit testing the changes. Some part of
`Shell::Create` is extracted into a static function to avoid duplicate
code.

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I added new tests to check the change I am making or feature I am
adding, or Hixie said the PR is test-exempt. See [testing the engine]
for instructions on writing and running engine tests.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I signed the [CLA].
- [ ] 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
[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
2023-09-06 12:56:42 -07:00