During the implementation of custom compositor integration, the embedder gets
callbacks on the render thread to prepare render targets (framebuffers,
textures, etc) for the engine to render into, callbacks to present these render
targets along with platform managed contents, and, callbacks to collect render
targets once they can no longer be recycled by the engine in subsequent frames.
During these callbacks, the engine mandates the OpenGL state on the render
thread be preserved. This restriction has been the source of hard to isolate
issues where the embedder trampled on the OpenGL bindings state in the callback
but failed to restore state before control went back to the engine. Due to the
nature of the OpenGL API, such errors are easy to make and overlook. This patch
lifts the restriction from the embedder. Embedders may now freely work with the
OpenGL state in custom compositor callbacks and the engine will make sure to
disregard OpenGL bindings when control flows back to it.
Disregarding current OpenGL state has a certain performance penalty and the
majority of this patch handles refactoring various engine embedder components
such that this happens only once per frame. The most trivial version of this
patch would reset context bindings on every transition of control flow from the
embedder to the engine. However, that naive approach would have necessitated
more than 50 binding resets in existing unit-test cases (depending on the number
of platform view interleaving levels and render target recycling hit rates). In
this implementation, bindings will be reset only once per frame and this does
not depend on the number of platform views in the scene.
The majority of this patch is a refactoring of engine subsystems used in
`ExternalViewEmbedder::SubmitFrame` which is thoroughly documented with each
opportunity for the embedder to invalidate OpenGL state tagged.
The refactoring also enables the implementation of the following optimizations
to engine behavior which should aid in reducing the memory needed for the
creation of render targets. These optimization include:
* The engine will only ask the embedder for render targets in which it expects
to render into. This was a quirk in the way in which root and non-root render
targets were handled. The engine could require the embedder to create a render
target but then realize it didn’t have anything to render into it. In the
presentation callback, it would skip that render target. But the embedder
still had to allocate that extra render target. This will no longer be the
case and should reduce memory use.
* The engine may now skip always realizing (via the embedder render target
creation callback) and presenting the root render target. This was also a side
effect of the same quirk. Previously, the engine would always ask the embedder
to present the root render target even if it was empty. Since this is no
longer the case, few render targets should be allocated which will reduce
memory consumption.
* The engine will now ask the embedder to collect unused render targets before
it asks it to create new ones. The previous behavior was to ask the embedder
for new targets and then collect old ones. This would cause spikes in memory
use when the size of the render targets would change. These memory use spikes
should now be troughs.
* The previous render target cache also considered the platform view ID in cache
viability considerations (instead of just the size of the render target). This
was a bug which has been fixed. This should lead to better cache utilization
in some situations.
These optimizations are now codified in unit-tests and the updated test
expectations are a result of these optimizations now being in place.
* Fixes https://github.com/flutter/flutter/issues/50751
* Fixes https://github.com/flutter/flutter/issues/46911
* Fixes https://github.com/flutter/flutter/issues/43778
* Fixes b/146142979
Compiling with clang on Windows fails here with a warning about implicit
cast from function pointer to object pointer. Rather than disable that
warning, this makes it an explicit cast. Since this is just test output,
it's not critical that this be a completely safe operation.
Part of #16256
This was only necessary when the Engine had to build in multiple buildroots
where the sources where checked out at different paths relative to the
buildroot. This is no longer the case and there are already cases GN rules
have been written that mix and match variable usage with the direct
specification of the path to the Flutter sources relative to the sole buildroot.
This condition may arise when the embedder passes in a path to a non-existent
dylib. Instead of crashing, the embedder will now return an error response.
Fixes https://github.com/flutter/flutter/issues/49732
This is in the same vein as https://github.com/flutter/engine/pull/16081 but
includes holding the mutex when updating all members in the Captures struct
instead of just when tracking thread IDs.
This was introduced in
ef31000576.
The assertion was originally written to check that more than 4 threads were
managed by the engine (UI, Platform, GPU, IO + ConcurrentWQWorkers). However,
the assertion actually only checked the count of workers in the ConcurrentWQ. As
written, this assertion would fail on all hosts with a hardware concurrency of
less than 4. Remove the assertion. The engine threads count and its assertions
already check callbacks on workers. So this check was incorrect and redundant.
`FlutterEnginePostCallbackOnAllNativeThreads` schedule a callback to be run on
all engine managed threads. The engine will attempt to service this callback the
next time the message loops for each managed thread is idle. Since the engine
manages the entire lifecycle of multiple threads, there is no opportunity for
the embedders to finely tune the priorities of threads directly, or, perform
other thread specific configuration (for example, setting thread names for
tracing). This callback gives embedders a chance to affect such tuning.
Fixesflutter/flutter#49551
Fixes b/143774406
Fixes b/148278215
Fixes b/148278931
Tonic used to be used by multiple consumers outside of Flutter Engine. Due to
this, it has an unnecessary abstraction layer as well as utilities duplicated in
FML and other engine subsystems. The sole user of Tonic is now the Flutter
Engine. It is intended that the Flutter Engine team now owns this subsystem,
remove unnecessary utilities and document the headers. This is the first step in
the transition. No history is being imported as the initial history was already
lost in the transition of this component to fuchsia.googlesource. As this
component was unmaintained there, I could see no additional value in importing
the history of the patches there.
No functional change. Just moved the repo from //third_party to
//flutter/third_party and updates GN refs.
The mutator list sent to the embedder is in reverse order from the
MutatorsStack. The root display transformation then needs to be appended
at the end of the list.
Given that these transforms are applied to a layer in display space the
list needs to be reversed as well such that transforms can be applied in
the right order to get from display space to surface space.
Bug: b/143612326
This reverts commit 6919709e47661c5cd48d9b0d3bfde986b9c1af84.
On top of the revert, it reverted a commit in the PR:
https://github.com/flutter/engine/pull/14024
This reverts commit ea67e5b0b930ebf552bc7dbd678a35ee6a129c39.
This is a non-breaking addition to the stable Flutter Embedder API and exposes a
subset of the functionality provided by Dart_PostCObject API in a stable and
tested manner to custom embedder implementations.
Send port acquisition can currently be done as described in the unit-test but
there may be opportunities to extend this API in the future to access ports more
easily or create ports from the native side.
The following capabilities of the the Dart_PostCObject API are explicitly NOT
exposed:
* Object arrays: This allows callers to create complex object graphs but only
using the primitives specified in the native API. I could find no current use
case for this and would have made the implementation a lot more complex. This
is something we can add in the future if necessary however.
* Capabilities and ports: Again no use cases and I honestly I didn’t understand
how to use capabilities. If needed, these can be added at a later point by
appending to the union.
Fixes https://github.com/flutter/flutter/issues/46624
Fixes b/145982720
* Revert "Add flow test fixtures and tests (#13986)"
This reverts commit 32915132bacdfd0d631421b23bb6a6d5db1095ab.
* Revert "Dynamically determine whether to use offscreen surface based on need (#13976)"
This reverts commit a13401ce86b3019c39154d56644b7b9eb4a5bbe5.
This reverts commit 7552e9370527aae8df06b43dcb6b313d9ebdb365.
This is being reverted because it caused flutter/flutter#45098
(images don't load on iOS).
This is a duplicate of flutter/engine#13360 with the test switched to use the software backend instead of the GL backend.
After some debugging and testing on another GL embedder I think the issue with the test is some bug having to do with the GL implementation in the test harness specifically.
Fixesflutter/flutter#38903
The earlier assumption was that the render target would be re-materialized per frame. The render target needs its own picture recorder to be create per frame as well. When render targets are cached in the registry, an existing target will be reused. But submitting the previous frame would have discarded the recorder already. The layer tree paint would then attempt to dererence a null canvas causing a crash at runtime.
Added tests to ensure that this does not happen both with and without a custom compositor specified by the embedder. I am going to rework this code so that the external view embedders thinks of render target access on a per frame basis but that is a larger change. This smaller patchset should unblock broken builds.
Fixes b/144093523
Previously the cache was disabled on whether or not PlatformViews were
globally enabled. Instead track their existence in the view hierarchy
and only disable RasterCache if a PlatformView is actually present.
This used to only be handled correctly for non-root layer backing stores. This
was mostly a side effect of the fact that we used recording canvases instead of
rendering directly into the backing store. We now use recording canvases
consistently.
Fixes b/143464703
Fixes https://github.com/flutter/flutter/issues/43732
This exposes platform_view_id on the embedder API's FlutterSemanticNode.
In 40e0467f60dd2174af5b3edf8bd2752eb6251bf1 (#8055), platformViewId was
added to SemanticsNode. This field is non-zero when the SemanticsNode
represents a platform view and is typically used by embedders as a means
of identifying locations where a platform view's 'native' accessibility
tree should be injected into the platform-specific accessibility tree
constructed by the embedder.
Due to the intended use of this field, the Flutter framework is meant to
enforce that this node has a child count of zero.