This adds a gn flag (--backtrace, --no-backtrace) that defaults to
enabling backtraces, which drives a gn variable `enable_backtrace` which
is defaulted true for debug builds.
Backtrace collection is supported on Windows, and on POSIX-like
operating systems via execinfo.h. execinfo support exists in Android,
macOS/iOS, and in glibc and uclibc on Linux. musl libc notably does not
include execinfo support, so this provides an escape hatch to build with
backtrace_stub.cc for situations in which compile time support doesn't
exist.
Proposed as an alternative to
https://github.com/flutter/engine/pull/40958 by @selfisekai.
Issue: https://github.com/flutter/flutter/issues/124285
Fixes https://github.com/flutter/flutter/issues/124269
Manually verified this is safe on an iPhone 11.
We're not creating/encoding command buffers in this path so it's ok.
AFAICT the test I added would fail if we started doing that because it
doesn't provide any real command buffer interfaces. Most of the code
here is related to tests.
(this is attempt 4; details below)
Remove obsolete object caches and introduce a simpler way to manage
native objects:
* Remove the unused `SynchronousSkiaObjectCache`.
* Introduce new library `native_memory.dart` that's smaller and simpler
than `skia_object_cache.dart`.
* Introduce two types of native object references:
* `UniqueRef` a reference with a unique Dart object owner.
* `CountedRef` a ref-counted reference with multiple Dart object owners.
* All native references use GC (via `FinalizationRegistry`) as a
back-up.
* The new library removes everything related to object resurrection that
was needed only in browsers that didn't support `FinalizationRegistry`.
All browsers support it now.
* Remove the ad hoc `SkParagraph` cache that predates the introduction
of `Paragraph.dispose`.
* Rewrite `CkParagraph` in terms of `UniqueRef`.
* Rewrite `CkImage` in terms of `CountedRef`; delete `SkiaObjectBox`.
This PR does not migrate all objects from the old
`skia_object_cache.dart` to `native_memory.dart`. That would be too big
of a change. The migration can be done in multiple smaller PRs.
This also removes a few unnecessary relayouts observed in
https://github.com/flutter/flutter/issues/120921, but not all of them
(more details in
https://github.com/flutter/flutter/issues/120921#issuecomment-1481958762)
## About attempt 4
More info about the revert of attempt 3 in
https://github.com/flutter/engine/pull/40937.
In this attempt I check that the browser supports `FinalizationRegistry`
before registering the object. This will allow the code to run in older
browsers, but there will be no protection from memory leaks when the app
fails to dispose of the respective objects.
## Benchmarks
Now that this landed in flutter/flutter I have some benchmark numbers
from the devicelab. The `text_out_of_picture_bounds` benchmark dropped
by 3-4x (lower is better):
<img width="358" alt="Screenshot 2023-04-04 at 6 13 06 PM"
src="https://user-images.githubusercontent.com/211513/229956170-a5399ed3-c779-4af0-babb-ea40440f96ff.png">
The repro provided in https://github.com/flutter/flutter/issues/123204
dropped from 110ms/frame to 10ms/frame.
Moves application termination handling to FlutterAppDelegate.
Previously, we required macOS applications using Flutter to ensure their
main application class was FlutterApplication. Instead, we now do all
handling in FlutterAppDelegate and FlutterEngine.
There are two termination workflows to consider:
* Termination requested from framework side: In this case, then engine
receives a `System.exitApplication` method call, and starts the app
termination workflow via `[FlutterEngine
requestApplicationTermination:exitType:result]`.
* Termination requested from macOS (e.g. Cmd-Q): In this case,
`FlutterAppDelegate`'s `applicationShouldTerminate:` handler is invoked
by AppKit, and the delegate starts the app termination workflow via
`[FlutterEngine requestApplicationTermination:exitType:result]`.
In either case, at this point, if the request is not cancellable, the
app immediately exits. If it is cancellable, the embedder sends a
`System.requestAppExit` method channel invocation to the framework,
which responds with either `exit` or `cancel`. In the case of `exit` we
immediately exit, otherwise we do nothing and the app continues running.
This is a minor refactoring of the original approach we took in:
https://github.com/flutter/engine/pull/39836
This does not remove the FlutterApplication class, since the framework
migration from NSApplication to FlutterApplication still depends on it.
A followup patch with replace the migration with a reverse migration
will land, then FlutterApplication will be removed.
Issue: https://github.com/flutter/flutter/issues/30735
No new tests since this refactors existing behaviour while retaining the
same app semantics as before.
(this is attempt 3; details below)
Remove obsolete object caches and introduce a simpler way to manage
native objects:
* Remove the unused `SynchronousSkiaObjectCache`.
* Introduce new library `native_memory.dart` that's smaller and simpler
than `skia_object_cache.dart`.
* Introduce two types of native object references:
* `UniqueRef` a reference with a unique Dart object owner.
* `CountedRef` a ref-counted reference with multiple Dart object owners.
* All native references use GC (via `FinalizationRegistry`) as a
back-up.
* The new library removes everything related to object resurrection that
was needed only in browsers that didn't support `FinalizationRegistry`.
All browsers support it now.
* Remove the ad hoc `SkParagraph` cache that predates the introduction
of `Paragraph.dispose`.
* Rewrite `CkParagraph` in terms of `UniqueRef`.
* Rewrite `CkImage` in terms of `CountedRef`; delete `SkiaObjectBox`.
This PR does not migrate all objects from the old
`skia_object_cache.dart` to `native_memory.dart`. That would be too big
of a change. The migration can be done in multiple smaller PRs.
This also removes a few unnecessary relayouts observed in
https://github.com/flutter/flutter/issues/120921, but not all of them
(more details in
https://github.com/flutter/flutter/issues/120921#issuecomment-1481958762)
## About attempt 3
More about [attempt 2
here](https://github.com/flutter/engine/pull/40862).
In this attempt 3 I'm replacing the `factory` with a top-level function.
Reverts flutter/engine#40886
This renders incorrectly when applied directly to contents instead of as
a filter, essentially due to some transform mis handling.
The code only works when the snapshot has an identity transform, which
is only true as a subpass