Fixes https://github.com/flutter/flutter/issues/101569
This block of code was originally introduced in https://github.com/flutter/engine/pull/15560 , but removing it does not have any affect on the software text editing controls in GBoard.
Before this change
* shift + arrow right/left selection would collapse after releasing the shift key.
* shift + mouse click to expand selection would collapse after releasing the shift key.
After this change
* shift key up no longer collapses the selection.
Similar to https://github.com/flutter/engine/pull/41733 and
https://github.com/flutter/engine/pull/41782, this causes the macos
embedding to wait until it hears that the scheduler binding has
registered itself before proceeding to send termination requests to the
framework.
This allows applications that don't use the framework (just use
`dart:ui` directly) to exit automatically when the last window is
closed. Without this change, the last window closes, but the app does
not exit.
Depends on framework PR https://github.com/flutter/flutter/pull/126075
landing first.
This change adds a C++ client wrapper to Windows's "force redraw" C API. This API can be used to schedule a frame.
Part of https://github.com/flutter/flutter/issues/119415
## Background
The Windows runner has a race at startup:
1. **Platform thread**: creates a hidden window
2. **Platform thread**: launches the Flutter engine
3. **UI/Raster threads**: renders the first frame
4. **Platform thread**: Registers a callback to show the window once the next frame has been rendered.
Steps 3 and 4 happen in parallel and it is possible for step 3 to complete before step 4 starts. In this scenario, the next frame callback is never called and the window is never shown.
The Windows runner will be updated to call the "force redraw" API after it registers the next frame callback. If step 3 hasn't completed yet, the "force redraw" will no-op as a frame is already scheduled. If step 3 has already completed, the "force redraw" will schedule another frame, which will call the next frame callback and show the window.
See this discussion below on why we cannot avoid changing the Windows runner to fix this issue: https://github.com/flutter/engine/pull/42061#issuecomment-1550080722
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
A mistake was introduced in https://github.com/flutter/engine/pull/39498 where the maskViews are already recycles each frame.
Sometimes a PlatformView does not need to be re-composite: (https://github.com/flutter/engine/blob/main/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm#L398-L401), so the mask view for such PlatformView should not be recycled.
This PR changed the `recycleMaskViews` API to allow individual maskviews to be recycled. `ApplyMutator` then only recycle the maskView for that particular PlatformView.
The MaskViewPool is also reworked to be simpler.
- The pool now contains a single set of mask views, there is no index counter needed.
- When a maskView is needed, try to get it from the pool.
- If pool is empty, create a new view.
- If pool has an available maskview, remove it from the pool.
- When a PlatformView starts to `applyMutator`, it removes current the maskView, insert the maskView to the pool.
- When the above PlatformView needs to a maskView, it grabs one from the pool.
fixes: https://github.com/flutter/flutter/issues/125620
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Fixes b/282290672
Google Testing currently does not support vulkan, and constructors like
this need to be behind a flag.
## 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.
- [ ] 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.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I signed the [CLA].
- [x] All existing and new tests are passing.
This optimization avoids recording unnecessary render operations that will not affect the output and also eliminates the need for "draw detection" mechanisms like `DlOpSpy` and `CanvasSpy` by remembering if any non-transparent operations were included. The `DlOpSpy` unit tests were updated to check if the results from that object match the new `DisplayList::affects_transparent_surface()` method.
Fixes https://github.com/flutter/flutter/issues/125338
In addition, this change will unblock some other Issues:
- https://github.com/flutter/flutter/issues/125318
- https://github.com/flutter/flutter/issues/125403
Noticed this while working on https://github.com/flutter/flutter/issues/124181
In Impeller right now, Android creates a context for each surface - but in Skia, Android creates one context and shares it across surfaces. For the multiple-engine scenario this matters. This also makes it possible for Android to provide the impeller::Context independently of surface creation.
## Description
In https://github.com/flutter/engine/pull/41702, the default state of the focus bit is "false", assuming that Android will send an `onWindowFocusChanged(true)` when the window is first focused, but there appear to be some cases where that doesn't happen.
This change puts the initial state back to what it used to be: in the absence of focus change events, entering the "onResume" Android state will report the `resumed` state in Flutter. Before this PR, and after https://github.com/flutter/engine/pull/41702, if no focus events were received, it would default to `inactive`.
## Tests
- Updated tests to match.
These tests are flaky. Until they've been deflaked, disable the
following two tests:
* FlutterEngineTest.BackgroundIsBlack
* FlutterEngineTest.CanOverrideBackgroundColor
Issue: https://github.com/flutter/flutter/issues/124677
The original code creates an internal `class` which is alarming:
`NSClassFromString(@"_UIVisualEffectBackdropView")`
This PR removes such usage.
*List which issues are fixed by this PR. You must list at least one issue.*
Fixes https://github.com/flutter/flutter/issues/124008
*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
As we move the Dart FIDL bindings we need to stop calling FIDL methods
from Dart in the Flutter repo. This only affects some integration tests.
This moves the FIDL calls into C++ and uses platform messages to make
the functionality available to the Dart tests.
Remove reference to unused fuchsia.sys.Environment protocol in test
Realm setup. Besides being unused,
the reference was not correctly matched by an #include, nor a GN build
dependency.
Bug: fxbug.dev/81285
Fixes https://github.com/flutter/flutter/issues/123307 - for Android, iOS, and Web, for the main display only (https://github.com/flutter/flutter/issues/125938 tracks supporting multiple displays, https://github.com/flutter/flutter/issues/125939 for desktop).
Desktop will need to be implemented for this, but given priority for a couple of our customers targetting foldable devices on Android I'm inclined to get this in before desktop can be finished.
The main concern for this right now is that on some Android foldable devices, setting a preferred orientation will cause letterboxing and the `MediaQuery` will _never_ get the full screen size when unfolded. This causes apps to think the screen is smaller than it is, as they've mainly been using `MediaQueryData.size` to figure this out. Android's recommendation is to not set a preferred orientation, and if you must to use the new method introduced in `ViewUtil.java` to calculate the maximal window size.
Removes the physical model layer and associated engine code. This was already deprecated and removed in the framework. By removing it in the engine, we can also remove the need for layer tree diff/paint/preroll to have the device pixel ratio. This will simplify some of the multi-view work
Fixes https://github.com/flutter/flutter/issues/125720
## Description
This reverts commit e49577708d9d5315fa6c001d7dc20ee80d04cd35 to re-land #41094 because the Google test failures have been fixed. There are no changes to the original PR, since the fixes were in the Google code.
Typically the AndroidShellHolder's apk_asset_provider_ is set by AndroidShellHolder::Launch when the DartExecutor runs the engine's entrypoint.
But if the engine was started by Spawn, then the apk_asset_provider_ was not being set. This would cause a crash if the resulting engine was later used to spawn another engine.
Fixes https://github.com/flutter/flutter/issues/122364
Switching the calls to dispatch into an Impeller Dispatcher to use a cull rect to enable pre-culling of the out-of-bounds ops.
This change showed an improvement of around 2x on the rendering performance of the non-intersecting platform view benchmark, but that was measured without the recent changes to the destructive blend modes in Impeller renderer.
DisposeView happens every frame before laying out PlatformViews, with the order specified in `composition_order_`. Because `view_to_dispose_` is determined on UI thread and `composition_order_` is determined on the platform thread, there could be a race if the dart code on the UI thread runs faster than the rasterizer on the Platform thread, causing a view in `view_to_dispose_` is still in the `composition_order_`.
This PR delays the views in the `composition_order_` being disposed and wait for the next frame to dispose them.
fixes https://github.com/flutter/flutter/issues/125223
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
## Description
This incorporates additional signal from `Activity.onWindowFocusChanged` to help decide if the application is `resumed` or `inactive`.
When the user pulls down the notification shade or opens the app switcher in iOS, then iOS sends a notification to the application that it no longer has input focus (is no longer "active" in Apple terminology).
However, Android (at least on a Pixel) doesn't send `onPause` and `onResume` events for these things, as one might expect. Instead, this PR changes things so that we listen to `Activity.onWindowFocusChanged` and see if any of the windows still have focus.
If it doesn't have focus, then the lifecycle switches to `inactive` (even if `onPause` hasn't been called), and if it does have focus (and `onResume` hasn't been called) then we should go to `resumed`.
State changes are determined and deduped in the `LifecycleChannel` class.
Here's the old state table:
| Android State | Flutter state |
| ------------- | ------------- |
| Resumed | resumed |
| Paused | inactive |
| Stopped | paused |
| Detached | detached |
Here's the new state table:
| Android State | Window focused | Flutter state |
| ------------- | ------------- | ------------- |
| Resumed | true | resumed |
| Resumed | false | _inactive_ * |
| Paused | true | inactive |
| Paused | false | inactive |
| Stopped | true | paused |
| Stopped | false | paused |
| Detached | true | detached |
| Detached | false | detached |
* = This is the relevant change in this PR.
("Window focused" means one or more windows managed by Flutter are focused)
The `inactive` state is for when the application is running and visible, but doesn't have the input focus. An example where this currently happens are when a phone call is in progress on top of the app, or on some OEMs when going into the app switcher (I've tested on Realme and it does that, at least). With the PR, it will also go into `inactive` when the app has lost input focus, but is still in the Android `onResume` state. This means that on phones that don't pause the app when they go into the app switcher or the notification window shade (Pixel, others), the app will go into `inactive` when it didn't before. If developers weren't doing anything special in the `inactive` state before, then this PR will have no change for them. If they were, they will go into that state more often (but more consistently across OEMs).
## Related Issues
- Fixes https://github.com/flutter/flutter/issues/124591
## Tests
- Added unit tests for handling `onWindowFocusChanged`.
Implements partial repaint for Impeller.
Fixes https://github.com/flutter/flutter/issues/124526
The new code that manages the damage regions is more or less a copy paste from the existing Skia implementation. Compared to Skia, there are a few differences:
Normally Impeller wants to use the drawable as the resolve texture for the root MSAA pass. Unfortunately this will unconditonally clear that texture. Thus to do a partial repaint, we have to allocate a separate texture to resolve to and then blit into the drawable.
The blit seems to take about 500ns for a full screen on an iPhone 13. That implies that partial repaint is likely not worth doing if the screen is significantly changed. Thus I've added code in compositor_context.cc that computes the percentage of width or height that is part of the dirty rect. Above a threshold of (abitrarily chosen) 70%, we just render as normal. This should mean there is only a very minor hit from performing the diff on screens that are highly changed.
The other special case, is that sometimes we get damage rects that are empty - that is the drawable is already completely up to date with what we want to render. IN that case I shortcircuit all of the impeller code and just present immediately. I previously tried returning without a present but this resulted in Xcode reporting dropped frames. One caveat here is that if you use the XCode frame debugger and attempt to capture a frame where we early present, then it will claim it couldn't capture any command buffers (because we didn't create any).
To facilitate all of this, I added some additonal plumbing so that the impeller surface can get the clip rect from the submit info. Additionally, rather than using a clip rect impeller will translate and then shrink the root surface texture. This reduces memory usage compared to just clippling.
Reverts https://github.com/flutter/engine/pull/40895.
Resolves https://github.com/flutter/flutter/issues/120399 (again).
A bunch of frames get pumped on the main thread _without a transaction_
just before unmerging occurs (I don't know why this happens), and so
checking the current thread to determine whether we need to present with
a transaction or not isn't sufficient. In the prior fix, after the
unmerge, the raster thread would hang for one second while waiting for
the next drawable to get freed up (happens on the second raster thread
frame post-unmerge), and then subsequent presents would just do nothing
for a while, but eventually recover.
`presentsWithTransaction` works whether the `CATransaction` stack is
empty or not, and so the only difference here is that
`presentsWithTransaction` is always turned on and `presentDrawable` is
always avoided (otherwise it tries to present too early and nothing
renders when platform views are present).