44 Commits

Author SHA1 Message Date
Chinmay Garde
92abb22c64
Reland "Lift restriction that embedders may not trample the render thread OpenGL context in composition callbacks." (#16711)
This reverts commit ef9e7b1a1365c07ab0df2e2016c4442c3963c2c7 with the following changes to accommodate an embedder for whom the original optimizations caused issues:

* Ensure stable order in the backing stores presented to the embedder. This is a pessimization that will be reverted when the embedder migrates. Tracked in  https://github.com/flutter/flutter/issues/51228
* Forego the optimization where the unused layers would be collected before allocation of new layers needs to happen. This is a pessimization that will be reverted when the embedder migrates. Tracked in  https://github.com/flutter/flutter/issues/51229

More context in b/146142979.
2020-02-24 11:48:32 -08:00
Chinmay Garde
ef9e7b1a13
Revert "Lift restriction that embedders may not trample the render thread OpenGL context in composition callbacks. (#16653)" (#16674)
This reverts commit 110c1c9adf0f580d16c8252e3b37992af93e9cea.
2020-02-18 18:59:21 -08:00
Chinmay Garde
110c1c9adf
Lift restriction that embedders may not trample the render thread OpenGL context in composition callbacks. (#16653)
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
2020-02-18 12:51:49 -08:00
dnicoara
1d6766f9dd Fix embedder mutation order (#15566)
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
2020-01-15 10:35:15 -08:00
Chinmay Garde
f05832153b
Allow embedders to post Dart objects on send ports from the native side. (#14477)
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
2019-12-13 17:28:21 -08:00
Chinmay Garde
03f45a1edd
Verify embedders can convert clip rects from mutation stack into surface space. (#14483)
Add a test to verify behavior discussed in b/143612326
2019-12-13 15:28:01 -08:00
Chinmay Garde
0a40f3d784
Assert that arc end caps on canvases with root surface transformations are drawn correctly. (#14359)
Verifies that the Skia commit https://skia-review.googlesource.com/c/skia/+/259174 has been pulled into the engine. This should have happened in the roll https://github.com/flutter/engine/pull/14345.

Fixes https://github.com/flutter/flutter/issues/46691
Fixes b/142280381
2019-12-11 15:17:34 -08:00
Chinmay Garde
9f6401362d
Don't crash but warn when the scene builder specifies no layers. (#14008) 2019-11-25 15:38:41 -08:00
Chinmay Garde
75ea3e2445
Expose the platform view mutator stack to custom compositors. (#13731)
This allows custom compositors to affect scene builder modifications made
to the platform view.

Fixes https://github.com/flutter/flutter/issues/44211
Fixes b/143612326
2019-11-19 10:35:41 -08:00
Chinmay Garde
6bab64e6dc
Fix test to account for pixel ratio transformations being framework responsibility. (#13850)
This incorrect assumption led to the introduction of a failure on an external embedder. Also dries up the section that copies the picture to the embedder managed render targets.

Fixes https://github.com/flutter/flutter/issues/43906
Fixes https://b.corp.google.com/issues/143529469
2019-11-14 12:15:33 -08:00
Michael Klimushyn
8a99d10748
Turn on RasterCache based on view hierarchy (#13762)
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. 

Fixes flutter/flutter#38903
2019-11-08 17:14:50 -08:00
Chinmay Garde
7590336bbc
Create a new picture recorder even when the embedder supplied render target is recycled. (#13744)
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
2019-11-07 19:53:51 -08:00
Chinmay Garde
d59b1583b0
Ensure that the device pixel ratio is taken into account with window metrics in physical pixels. (#13708)
This was originally patched in https://github.com/flutter/engine/pull/13193 but
the unit-tests were written under the mistaken assumption (that has been
documented already) that the Flutter window metrics used logical pixel
coordinates. That mistake has been corrected and additional tests to verify
rendering intent has been added.

Fixes https://github.com/flutter/flutter/issues/43906
Fixes https://b.corp.google.com/issues/143529469
2019-11-06 11:16:18 -08:00
Michael Klimushyn
e609577d12
Revert "Turn on RasterCache based on view hierarchy (#13360)" (#13442)
This caused EmbedderTest.VerifyB143464703 to fail after merging into
master.

```
../../flutter/shell/platform/embedder/tests/embedder_unittests.cc:3111: Failure
Value of: ImageMatchesFixture("verifyb143464703.png", renderered_scene)
  Actual: false
Expected: true
[  FAILED  ] EmbedderTest.VerifyB143464703 (2507 ms)
```

This reverts commit 3ad3bc76a5825210603d4afd12013de8ba7d7668.
2019-10-30 11:25:29 -07:00
Michael Klimushyn
3ad3bc76a5
Turn on RasterCache based on view hierarchy (#13360)
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.
2019-10-30 10:45:15 -07:00
Chinmay Garde
e3aff2c982
Make sure root surface transformations survive resetting the matrix directly in Flow. (#13405)
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
2019-10-29 17:44:57 -07:00
Chris Bracken
4f300e618f
Expose platform view ID on embedder semantics node (#13345)
This exposes platform_view_id on the embedder API's FlutterSemanticNode.

In bd0f9085e5bdbac74cc6e611f758768f15ad5415 (#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.
2019-10-24 19:42:32 -07:00
Chinmay Garde
b5a33d4d6a
Allow embedders to update preferrred locales. (#13238)
This was previously only possible by sending an undocumented payload over an engine managed channel.
2019-10-22 17:50:01 -07:00
Chinmay Garde
c92613bc49
Re-land "Custom compositor layers must take into account the device pixel ratio."
This reverts commit 6c2381da6070f9e96825841e77e9ffeb376d6aa9 and applies iOS fixes.
2019-10-17 14:07:51 -07:00
Chinmay Garde
6c2381da60
Revert "Custom compositor layers must take into account the device pixel ratio. (#13193)" (#13211)
This reverts commit e53d10c3456ccac1bffabc78a16fd6ce680d0074.
2019-10-17 12:59:27 -07:00
Chinmay Garde
e53d10c345
Custom compositor layers must take into account the device pixel ratio. (#13193)
The contents rendered into the backing stores are already correctly scaled.
The initial implementation assumed this also held true for the metrics obtained
via embedded view parameters.

Fixes b/142699417
2019-10-17 12:04:13 -07:00
Chinmay Garde
03d1bba6d8
Add a unit-test to verify that root surface transformation affect platform view coordinates. (#12783)
See b/141980393 for details.

In the issue, the embedder (assumed to render Flutter contents of size 800 x 600 [1]) is meant to be displayed on its side. To achieve this, it specifies a root surface transformation that translates the surface by its width (or height when it held in the correct viewing position) and then rotates it counter-clockwise by 90 degrees. This test verifies that the Flutter Engine accounts for those transformations in the custom compositor platform view coodinates.

[1] The actual size is something different. 800x600 is for illustrative purposes.
2019-10-08 11:30:00 -07:00
Chinmay Garde
1c7300ed1e
Account for root surface transformation on the surfaces managed by the external view embedder. (#11384)
The earlier design speculated that embedders could affect the same
transformations on the layers post engine compositor presentation but before
final composition.

However, the linked issue points out that this design is not suitable for use
with hardware overlay planes. When rendering to the same, to affect the
transformation before composition, embedders would have to render to an
off-screen render target and then apply the transformation before presentation.
This patch negates the need for that off-screen render pass.

To be clear, the previous architecture is still fully viable. Embedders still
have full control over layer transformations before composition. This is an
optimization for the hardware overlay planes use-case.

Fixes b/139758641
2019-09-17 15:16:59 -07:00
Amir Hardon
a34f9a811c
Skip empty platform view overlays. (#11427)
This change sets up a "spying canvas" to try and detect empty canvases.
When using platform views with a custom embedder, if a platform view
overlay canvas is known to be empty we skip creating a compositor layer
for that overlay.
2019-08-26 11:40:49 -07:00
Chinmay Garde
fcc158fd3f
Wire up software rendering in the test compositor. (#11392) 2019-08-22 20:27:34 -07:00
Chinmay Garde
9b1f6d37a7
When using a custom compositor, ensure the root canvas is flushed. (#11310)
The root canvas is managed by the external view embedder when using a custom
compositor. Due to this, frame submission on the surface will not end up
flushing the same (because the surface doesn’t have it to begin with). Fixed
with tests.
2019-08-20 17:06:57 -07:00
Chinmay Garde
e8f954409d
Allow embedder controlled composition of Flutter layers. (#10195)
This patch allows embedders to split the Flutter layer tree into multiple
chunks. These chunks are meant to be composed one on top of another. This gives
embedders a chance to interleave their own contents between these chunks.

The Flutter embedder API already provides hooks for the specification of
textures for the Flutter engine to compose within its own hierarchy (for camera
feeds, video, etc..). However, not all embedders can render the contents of such
sources into textures the Flutter engine can accept. Moreover, this composition
model may have overheads that are non-trivial for certain use cases. In such
cases, the embedder may choose to specify multiple render target for Flutter to
render into instead of just one.

The use of this API allows embedders to perform composition very similar to the
iOS embedder. This composition model is used on that platform for the embedding
of UIKit view such and web view and map views within the Flutter hierarchy.
However, do note that iOS also has threading configurations that are currently
not available to custom embedders.

The embedder API updates in this patch are ABI stable and existing embedders
will continue to work are normal. For embedders that want to enable this
composition mode, the API is designed to make it easy to opt into the same in an
incremental manner.

Rendering of contents into the “root” rendering surface remains unchanged.
However, now the application can push “platform views” via a scene builder.
These platform views need to handled by a FlutterCompositor specified in a new
field at the end of the FlutterProjectArgs struct.

When a new platform view in introduced within the layer tree, the compositor
will ask the embedder to create a new render target for that platform view.
Render targets can currently be OpenGL framebuffers, OpenGL textures or software
buffers. The type of the render target returned by the embedder must be
compatible with the root render surface. That is, if the root render surface is
an OpenGL framebuffer, the render target for each platform view must either be a
texture or a framebuffer in the same OpenGL context. New render target types as
well as root renderers for newer APIs like Metal & Vulkan can and will be added
in the future. The addition of these APIs will be done in an ABI & API stable
manner.

As Flutter renders frames, it gives the embedder a callback with information
about the position of the various platform views in the effective hierarchy.
The embedder is then meant to put the contents of the render targets that it
setup and had previously given to the engine onto the screen (of course
interleaving the contents of the platform views).

Unit-tests have been added that test not only the structure and properties of
layer hierarchy given to the compositor, but also the contents of the texels
rendered by a test compositor using both the OpenGL and software rendering
backends.

Fixes b/132812775
Fixes flutter/flutter#35410
2019-08-13 14:53:19 -07:00
Pierre Champion
66092d5b02 SendPlatformMessage allow null message value (#9781) 2019-07-16 11:38:33 -07:00
Chinmay Garde
b132baa447
Ensure that platform messages without response handles can be dispatched. (#9698) 2019-07-06 14:57:36 -07:00
Chinmay Garde
b84f89b44b
Allow embedders to add callbacks for responses to platform messages from the framework. (#9655)
Fixes https://github.com/flutter/flutter/issues/18852
2019-07-03 15:44:39 -07:00
Jason Simmons
b3fe3e95d4 Fix a race in the embedder accessibility unit test (#9585) 2019-06-30 12:50:44 -07:00
Dan Field
2b1f9925e4
new lints (#8849)
Dart lints added:
* Avoid optional new
* Avoid optional const
* Prefer single quotes
* Prefer default assignment `=`
2019-05-07 16:10:21 -07:00
Chinmay Garde
8d56284cda
Remove the standalone a11y test runners and merge its tests into embedder_unittests. (#8338)
Also cleans up the a11y unittests to use the new builder API and avoids polluting the global namespace with state for assertions.
2019-03-28 11:22:06 -07:00
Chinmay Garde
cb8eb801a4
Allow embedders to specify their own task runner interfaces. (#8273)
Currently, all Flutter threads are managed by the engine itself. This works for
all threads except the platform thread. On this thread, the engine cannot see
the underlying event multiplexing mechanism. Using the new task runner
interfaces, the engine can relinquish the task of setting up the event
multiplexing mechanism and instead have the embedder provide one for it during
setup.

This scheme is only wired up for the platform thread. But, the eventual goal
is to expose this message loop interoperability for all threads.
2019-03-27 16:16:59 -07:00
Chinmay Garde
3a3f707d5a
Reland "Allow specification of std::functions as native entrypoints from Dart code." (#8329)
This reverts commit 7e77d5c484a08cc1c189619e80ae71a7f1df62fb after fixing Windows issues.
2019-03-27 12:22:48 -07:00
Chinmay Garde
7e77d5c484
Revert "Allow specification of std::functions as native entrypoints from Dart code. (#8309)" (#8312)
This reverts commit 400a86a62efd3c8504672b8a63323cc837282135.
2019-03-26 13:49:41 -07:00
Chinmay Garde
400a86a62e
Allow specification of std::functions as native entrypoints from Dart code. (#8309)
This allows for the specification of std::functions (using EmbedderContext::NativeEntry) with their captures as native entrypoints. Earlier, only C functions we allowed which meant that there were no captures and assertions had to use globals which could introduce bugs when used with gtest_repeat.
2019-03-26 12:56:23 -07:00
Chinmay Garde
78de8dcb42
Enable lambda like native callbacks in tests and add support for custom entrypoints. (#8299) 2019-03-26 11:29:08 -07:00
Chris Bracken
99f3f7a9c2
Fix incorrect transformation matrix (#8001)
Previously the transformation matrix returned on semantics nodes was
fetched by matrix col,row (incorrectly). This uses the SkMatrix
constants instead and adds a test.
2019-02-28 19:19:06 -08:00
Chris Bracken
abe9826a9d
Add accessibility semantics support to embedder (#7891)
Flutter's accessibility APIs consist of three main calls from the
embedder to the Dart application:

  1. FlutterEngineUpdateSemanticsEnabled: enables/disables semantics support.

  2. FlutterEngineUpdateAccessibilityFeatures: sets embedder-specific
     accessibility features.

  3. FlutterEngineDispatchSemanticsAction: dispatches an action (tap,
     long-press, scroll, etc.) to a semantics node.

and two main callbacks triggered by Dart code:

  1. FlutterUpdateSemanticsNodeCallback: notifies the embedder of
     updates to the properties of a given semantics node.

  2. FlutterUpdateSemanticsCustomActionCallback: notifies the embedder
     of updates to custom semantics actions registered in Dart code.

In the Flutter framework, when accessibility is first enabled, the
embedder will receive a stream of update callbacks notifying the
embedder of the full semantics tree. On further changes in the Dart
application, only updates will be sent.
2019-02-20 18:59:29 -08:00
Chris Bracken
67cd7d4d3b
Compile embedder unit test Dart to kernel (#7231)
As of the migration to Dart 2, it has been necessary to compile Dart to
kernel prior to execution. The embedder currently requires that the
resulting kernel file be named `kernel_blob.bin` and be located at the
root of the assets directory passed to the embedder API.

This patch updates the test_fixtures build rule to perform a kernel
compile using frontend_server, outputting `kernel_blob.bin` to
`fixtures/test_target_name` directory, and updates the embedder
unittests to specify the kernel file rather than the Dart source file.

Since the kernel compiler requires a `main()` function to be defined, it
also updates `simple_main.dart` from runtime_unittests to define
`main()` rather than `simple_main()`.

This also updates all existing sub-targets to be testonly.

This relands commit ac9e521a1ddbb99816a93d92ce9fb70e950b3763, which was
reverted in commit 494112582932af98b282617d7a34b1fbb8c90307. Rather than
running as prebuilt_dart_action, we use dart_action to ensure the
frontend snapshot it compatible with the VM on which it's executed.
2018-12-16 12:23:18 -08:00
Chris Bracken
4941125829
Revert "Compile embedder unit test Dart to kernel (#7227)" (#7230)
This reverts commit ac9e521a1ddbb99816a93d92ce9fb70e950b3763.

This broke dynamic release mode builds of
//flutter/runtime:runtime_fixtures_kernel (likely all product-mode
builds).
2018-12-15 14:43:26 -08:00
Chris Bracken
ac9e521a1d
Compile embedder unit test Dart to kernel (#7227)
Compile embedder unit test Dart to kernel

As of the migration to Dart 2, it has been necessary to compile Dart to
kernel prior to execution. The embedder currently requires that the
resulting kernel file be named `kernel_blob.bin` and be located at the
root of the assets directory passed to the embedder API.

This patch updates the test_fixtures build rule to perform a kernel
compile using frontend_server, outputting `kernel_blob.bin` to
`fixtures/test_target_name` directory, and updates the embedder
unittests to specify the kernel file rather than the Dart source file.

Since the kernel compiler requires a `main()` function to be defined, it
also updates `simple_main.dart` from runtime_unittests to define
`main()` rather than `simple_main()`.

This also updates all existing sub-targets to be testonly.
2018-12-15 13:59:58 -08:00
Chinmay Garde
f781f928d1
Test that the embedder can be launched and shut down correctly. (#4281) 2017-10-30 14:15:32 -07:00