For each clip scope, draw opaque items in reverse order and
translucent/backdrop-independent items in their original order
afterwards. Clips are treated as translucent by the parent scope.
Respects clips, subpass collapse, and the clear color optimization.
Now also fixes: https://github.com/flutter/flutter/issues/153737
Being able to reorder rendering commands leads to optimization opportunities in the graphics package. A graphics package being fed from a DisplayList either has to take the commands in the order given or implement their own storage format for the rendering data.
With this new dispatching mechanism, the graphics package can both query basic information about the recorded ops and even dispatch them by the index into the list. Query information includes either the "category" of the op (clip/transform/render, etc.) or a specific op type enum. The package can dispatch some categories (or ops) immediately and remember other categories (or ops) along with their state for dispatching later.
Make sure the old dispatcher cannot be used if the new dispatcher is enabled. Migrate tests using old canvas to new canvas, mostly to make deleting the old one easier...
Part of DL interop. Currently experiencing some ... issues with blur radius/sigma.
EDIT: was rrect_blur vs gaussian: fixed now.
Part of https://github.com/flutter/flutter/issues/142054
Reland because of CI issue?
Reverts: flutter/engine#54519
Initiated by: jonahwilliams
Reason for reverting: post submit golden issues.
Original PR Author: jonahwilliams
Reviewed By: {chinmaygarde}
This change reverts the following previous change:
Part of DL interop. Currently experiencing some ... issues with blur radius/sigma.
EDIT: was rrect_blur vs gaussian: fixed now.
Part of https://github.com/flutter/flutter/issues/142054
Being able to reorder rendering commands leads to optimization opportunities in the graphics package. A graphics package being fed from a DisplayList either has to take the commands in the order given or implement their own storage format for the rendering data.
With this new dispatching mechanism, the graphics package can both query basic information about the recorded ops and even dispatch them by the index into the list. Query information includes either the "category" of the op (clip/transform/render, etc.) or a specific op type enum. The package can dispatch some categories (or ops) immediately and remember other categories (or ops) along with their state for dispatching later.
Fixes https://github.com/flutter/flutter/issues/152780
Fixes https://github.com/flutter/flutter/issues/152794
Problems:
* If point scale is < 1, we discarded it too early by computing circle divisions with the rounded scale. Since we multiply the scale by the transform _after_ rounding, we may end up generating too many points in some circumstances.
* Tessellator used max basis XYZ instead of max basis XY. The latter will never allow scaling factors less than 1 as Flutter canvas scale does not impact Z, only transform layers do.
* Computation of max basis required squaring the scaling factor, which would cause us to hit float::inf too early. For translate scale just take the max of m[0] and m[5].
* Draw points minimum circumference is 1, so the min radius should be 0.5
Allows using an EGL surface as a flutter backing store. Way more convenient for GBM than hacking gbm bo's into GL FBOs.
This resolves https://github.com/flutter/flutter/issues/58363
Currently, the embedder API assumes that the compositor (if it exists) will let flutter render into FBOs or Textures and then composite the whole thing onto the actual (EGL) window surface. I think this assumption is also documented a bit in https://github.com/flutter/flutter/issues/38466
However, in my case, I want let the hardware do the composition (using the linux KMS API), and render each flutter layer into it's own EGL surface.
It's possible to hack around this by creating your own GBM BOs, importing those as EGL images, then importing those as GL Render Buffers and attaching those to GL FBOs and that works (tested it). However, that's basically reimplementing 50% of the whole GBM/EGL "window" system integration for no reason.
This PR adds:
1. To the embedder API:
- a new kind of OpenGL Backing store: `FlutterOpenGLSurface`
- consisting of just a `make_current` and destruction callback (plus userdata)
- the make_current callback should make the target surface current, i.e. `eglMakeCurrent(..., surf, surf)`
- will be called by the engine before rendering onto the backing store
2. Some wiring to call make_current before rendering into the backing store
## TODO:
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Remove the need to merge raster and platform thread in the presence of platform views by defering UIView mutation and presentation of flutter views into separate platform thread task. Fixes priority inversion problem cause by platform thread blocking on drawable aquisition.
Open questions:
* Fixed ~What is a better interface for handling the partial submit with impeller. (TBD)~
* Fixed ~Update: We Don't | How do we fix this for Skia~ Fixed
* Fixed ~Update: Done, we post a task to the platform thread. Is there a shorter term solution for creating overlay layers on the raster thread.~ Fixed
* Fixed ~Update: seems to. Does this perform well enough (independent of platform/ui thread merge and w/ thread merge).~ Fixed
Fixes https://github.com/flutter/flutter/issues/142841
part of https://github.com/flutter/flutter/issues/150525
Developers can control the backend in the following ways:
* **Do nothing**: Impeller with Vulkan is used where Vulkan is available with a fallback to Skia with OpenGL.
* **In `AndroidManifest.xml`, specify `io.flutter.embedding.android.EnableImpeller` as `false`**: Skia with OpenGL is used.
* **On the command line, specify `--no-enable-impeller`**: Skia with OpenGL is used.
Manifest options will take priority command line options when there is a conflict. This matches iOS behavior per https://github.com/flutter/flutter/issues/124049 (closed as WAI).
Fixes https://github.com/flutter/flutter/issues/149360
Part of https://github.com/flutter/flutter/issues/147883.
Excluding Fuchsia and the Web SDK, the remaining scripts are:
```sh
$ ./tools/find_pubspecs_to_workspacify.sh
/Users/matanl/Developer/engine/src/flutter/impeller/tessellator/dart/pubspec.yaml
/Users/matanl/Developer/engine/src/flutter/sky/packages/sky_engine/pubspec.yaml
/Users/matanl/Developer/engine/src/flutter/shell/vmservice/pubspec.yaml
/Users/matanl/Developer/engine/src/flutter/lib/snapshot/pubspec.yaml
/Users/matanl/Developer/engine/src/flutter/lib/gpu/pubspec.yaml
/Users/matanl/Developer/engine/src/flutter/lib/web_ui/pubspec.yaml
/Users/matanl/Developer/engine/src/flutter/flutter_frontend_server/pubspec.yaml
```
These could be the trickiest, so I'm doing them separately.
Replaces and closes https://github.com/flutter/engine/pull/53997.
This PR migrates the following packages to the pub workspace:
- testing/benchmark
- testing/dart
- testing/litetest
- testing/pkg_test_demo
- testing/scenario_app
- testing/skia_gold_client
- testing/symbols
- tools/golden_tests_harvester
- tools/pkg/process_fakes
It also makes minor changes to the Dart build rules in order to resolve the root package_config, instead of per-package.
I am _not_ totally confident of the `_embedder.yaml` change, but I also can't explain what is needed to continue analyzing `lib/ui` without analysis failures that all of the symbols in `dart:nativewrappers` are missing.
This removes support for "unobstructed platform views" on iOS - instead prefering to use the Android strategy of minimizing overlay layers, as this is generally more performant.
Fixes 2 problems recently uncovered in the DisplayList verbose comparison test mechanism:
- The verbose compare methods never asserted a test failure, relying on the caller to do so from their return value - but they also did not prompt the caller to check the return value. So a `[[nodiscard]]` is added to remind test writers that they need to assert on the return value
- As a result of the above, some bad tests were recently added to the tree that were failing but did not assert a test failure. Now that the `[[nodiscard]]` is added, they failed to compile and had to have asserts added.
A secondary problem is that those non-failing tests were inadvertently cherry-picked from a reverted PR that is being reintroduced in incremental sections so as to avoid large scale golden image failures. The tests depend on parts of that PR that haven't been pulled forward yet (but will soon be) so those tests shouldn't have been added in the first place (and were failing, but not causing a gtest failure because of their missing asserts). They remain here, but their results are reversed to indicate the current state of affairs (they assert that the missing functionality isn't in place yet). Their assertions will be reverted when/as the missing functionality is pulled forward in a more incremental (responsible) way.
New flags on SaveLayerOptions will report if a saveLayer result is unbounded because a rendering operation within its contents did not have a definable bounds and there was no clip installed at the time (consider DrawPaint for example). A similar flag is found on DisplayList objects which reports if their top level had an unbounded operation.
This decouples the Impeller on-by-default effort from the release schedule and [plugin migrations](https://github.com/flutter/flutter/issues/151018).
The plugin migration documented in [go/impeller-plugin-migration][plugin-migration] is still recommended and facilitates zero-copy texture transfers between OpenGL and Vulkan. To recap, the plugin migration is to move away from the OpenGL-only SurfaceTexture APIs in the plugin interface.
This patch facilitates rendering OpenGL textures in a Vulkan renderer using texture trampolining using a single device-device transfer on all devices that support Impeller using the Vulkan renderer.
The performance of this approach is more than acceptable but at the cost of an additional texture allocation and will serve as a fallback to the for any remaining unmigrated plugins (all first-party plugins will already be migrated when the Impeller is on by default and we are following up on the migration of the major third-party plugins as well).
This is a straight improvement to the current state of things were unmigrated plugins will render an empty quad.
The Linux embedder had a number of handlers for Flutter channels that
were named plugin/handler/manager. Rename these all to handler to be
consistent and reduce confusion with Flutter plugins (which these don't
use the infrastructure for).
Converts several AIKS golden tests to use DisplayList as the mechanism.
In order to convert some of the tests, new factory methods were added to DlColor and tested with new unit tests (an earlier golden test conversion PR had a version of this as well).
Also, a new DisplayList record op was created for ClipOval to handle the AIKS clipping golden tests, but this new recording op is not used from Flutter `ui` code (no plumbing to call it from `lib/ui/painting` or to convert any other DisplayList call to use the new record). An earlier attempt to add the new recording op caused a large number of golden changes upstream so this version will only be used for internal tests and support to use it from apps will follow in more targeted PRs to better manage golden changes. This PR should not result in any changes to goldens outside of internal engine tests.
The Dart SDK's `package:async_helper/async_minitest.dart` was never intended for new tests, it was a drop-in polyfill for the legacy `package:unit_test` that some Dart SDK tests were using. The tests should never have used that package, and migrating them to `package:test` was not an option, so the `async_minitest.dart` file was the minimal polyfill that made all the tests run.
Since then, new tests have been written using the file, and to stop that, the file will now become deprecated, and (hopefully some day) removed.
If the Flutter engine wants to keep using the file, they should own their own copy of it, which is what this change does.
(Also migrates off the to-be-deprecated `assertStatementsEnabled` property of `package:expect/expect.dart`, moved to the new `asserts` from `package:expect/variations.dart`.)
Fixes https://github.com/flutter/flutter/issues/151355
The coverage pad introduced by renderToSnapshot is being picked up by drawVertices with texture coordinates. The pad is showing up in the final results, which can appear to be a gap between elements.
Additionally: if the coverage computed from the texture coordinates does not include the origin, then make sure the coverage used for the snapshot is translated onscreen.
Part of https://github.com/flutter/flutter/issues/143953.
Because there are so many boundary cases, i.e. tests failed uploading artifacts to LUCI, I was _not_ planning on atomically deleting and replacing `run_ios_tests.sh`, and want to give a chance for the iOS team to try the converted code and verify it works the way they expect.
I'm also happy to just slam it on, but defer to y'all. _It works on my machine_.
---
```sh
dart run testing/scenario_app/bin/run_ios_tests.dart
```
Reverts flutter/engine#53642
This change causes 10k golden updates internally and we need to land this out of band (go/lssc). There is also an existing issue with one particular client screenshot test - see b/350129213 for more details.
This typo was discovered while converting the AIKS tests to DisplayList - the new test executes correctly, but the old test generated bad goldens due to this typo. Fixing the typo to fix the golden prior to landing the test conversion.
The fix should be covered by existing tests - in fact the change is correcting an already bad golden test to correct behavior.
Reverts flutter/engine#53622
There were some golden changes which might be minor, but they weren't expected. Also, I noticed a problem in reducing drawPath down to drawRect and drawOval - that should not be done if the path has the inverse fill flag set...
Impeller supports `ClipOval` and will detect oval paths and rrects and use that call instead when appropriate. Adding support for `ClipOval` to DisplayList allows that optimization code to be moved up into the recording process.
The Vertices objects are already allocated in a shared object by default so copying them inline into the recording buffer is usually a waste of time rather than reusing the memory allocated for the shared object by recording a reference. Note that the shared DlVertices objects already inline all of their data so we have good data locality as it is without further copying the data into the buffer.
Might help with https://github.com/flutter/flutter/issues/150513