diff --git a/sites/docs/src/_includes/docs/platform-view-perf.md b/sites/docs/src/_includes/docs/platform-view-perf.md deleted file mode 100644 index 931c645f662..00000000000 --- a/sites/docs/src/_includes/docs/platform-view-perf.md +++ /dev/null @@ -1,44 +0,0 @@ -## Performance - -Platform views in Flutter come with performance trade-offs. - -For example, in a typical Flutter app, the Flutter UI is composed -on a dedicated raster thread. This allows Flutter apps to be fast, -as the main platform thread is rarely blocked. - -While a platform view is rendered with hybrid composition, -the Flutter UI is composed from the platform thread, -which competes with other tasks like handling OS or plugin messages. - -Prior to Android 10, hybrid composition copied each Flutter frame -out of the graphic memory into main memory, and then copied it back -to a GPU texture. As this copy happens per frame, the performance of -the entire Flutter UI might be impacted. In Android 10 or above, the -graphics memory is copied only once. - -Virtual display, on the other hand, -makes each pixel of the native view -flow through additional intermediate graphic buffers, -which cost graphic memory and drawing performance. - -For complex cases, there are some techniques that -can be used to mitigate these issues. - -For example, you could use a placeholder texture -while an animation is happening in Dart. -In other words, if an animation is slow while a -platform view is rendered, -then consider taking a screenshot of the -native view and rendering it as a texture. - -For more information, see: - -* [`TextureLayer`][] -* [`TextureRegistry`][] -* [`FlutterTextureRegistry`][] -* [`FlutterImageView`][] - -[`FlutterImageView`]: {{site.api}}/javadoc/io/flutter/embedding/android/FlutterImageView.html -[`FlutterTextureRegistry`]: {{site.api}}/ios-embedder/protocol_flutter_texture_registry-p.html -[`TextureLayer`]: {{site.api}}/flutter/rendering/TextureLayer-class.html -[`TextureRegistry`]: {{site.api}}/javadoc/io/flutter/view/TextureRegistry.html diff --git a/sites/docs/src/content/platform-integration/android/platform-views.md b/sites/docs/src/content/platform-integration/android/platform-views.md index ed0eb30ed37..ef0635f3c60 100644 --- a/sites/docs/src/content/platform-integration/android/platform-views.md +++ b/sites/docs/src/content/platform-integration/android/platform-views.md @@ -31,19 +31,27 @@ visit [Hosting native macOS views][]. Platform Views on Android have several implementations. They come with tradeoffs both in terms of performance and fidelity. -## Hybrid composition {: #hybrid-composition } +### Choosing an implementation + +The following matrix summarizes the different implementations and their trade-offs: + +| Mode | Benefits | Considerations | Enabler | +| :--- | :--- | :--- | :--- | +| **Texture layer** | • Good Flutter performance
• Full widget transforms work | • Janky during quick scrolling
• SurfaceViews lose accessibility and text magnifier breaks | Default behavior or standard `AndroidView` | +| **Hybrid composition** | • Full native fidelity
• Correct accessibility and SurfaceView support | • Causes thread merging of raster & platform, which degrades Flutter FPS
• Platform View -> Renders to texture -> Uploads to Impeller -> Impeller composites Flutter content and Platform View content |• `PlatformViewLink` with `AndroidViewSurface`
• [`AndroidViewController` builds either a TLHC or an HC Platform View][AC] | +| **HCPP** (Experimental) | • Full fidelity and performance
• Solves original sync overhead | • Requires Android API 34+, Vulkan support, and use of the Impeller rendering engine
• Platform View -> Renders to native Android Surface, Impeller renders to native Android Surface, SurfaceFlinger composites the two together | • `` in `AndroidManifest.xml`
• `--enable-hcpp` local flag
•[`AndroidViewController` builds either a TLHC or an HC Platform View][AC] | + +{:.table .table-striped} + +[AC]: {{site.github}}/flutter/flutter/blob/master/dev/integration_tests/hybrid_android_views/lib/android_platform_view.dart + +## Hybrid composition {: #hybrid-composition } Platform Views are rendered as they are normally. Flutter content is rendered into a texture. SurfaceFlinger composes the Flutter content and the platform views. -* `+` best performance and fidelity of Android views. -* `-` Flutter performance suffers. -* `-` FPS of application will be lower. -* `-` Certain transformations that can be applied to Flutter widgets - won't work when applied to platform views. - -## Hybrid Composition++ (HCPP) {: #hcpp } +## Hybrid composition++ (HCPP) {: #hcpp } :::note This feature is experimental and is available starting from Flutter 3.44. @@ -58,7 +66,7 @@ It is currently available as an opt-in feature. * **Android API 34 or later**: Required for native transaction synchronization capabilities. -* **Vulkan Rendering**: The device must be capable of rendering with Vulkan. +* **Vulkan rendering**: The device must be capable of rendering with Vulkan. If these requirements are not met on the end-user device, Flutter will automatically fall back to the existing platform view strategy @@ -72,58 +80,62 @@ it's enabled through configuration rather than standard Dart initialization meth You can enable HCPP using one of the following methods: -1. **Command Line Flag (Run/Test)**: - Pass the `--enable-hcpp` flag to your `flutter run` or `flutter test` command: +1. **Command line flag (run/test)**: + Pass the `--enable-hcpp` flag to your `flutter run` or `flutter test` command: - ```bash - flutter run --enable-hcpp - ``` + ```bash + flutter run --enable-hcpp + ``` -:::note - This flag is intended for local execution and testing. - It **can't** be passed to the `flutter build` commands. - For release builds, use the manifest configuration - as shown in the next step. -::: + :::note + This flag is intended for local execution and testing. + **It can't be passed to the `flutter build` commands.** + For release builds, use the manifest configuration + as shown in the next step. + ::: -2. **AndroidManifest.xml**: - Include a `` tag inside the `` block of your - `AndroidManifest.xml`: +2. **AndroidManifest.xml**: + Include a `` tag inside the `` block of your + `AndroidManifest.xml`: - ```xml - - ``` + ```xml + + ``` ### Limitations and known issues -* **Complex Overlay Stacking**: +* **Complex overlay stacking**: Transparent platform views won't display correctly in layout stacks structured as: - Flutter canvas -> Platform View -> Overlay -> Transparent Platform View, + **Flutter canvas -> Platform View -> Overlay -> Transparent Platform View**, when all four of these layers intersect. -To create a platform view on Android, use the following steps. - -## Texture layer { #texturelayerhybridcomposition } +## Texture layer {: #texture-layer } Platform Views are rendered into a texture. Flutter draws the platform views (using the texture). Flutter content is rendered directly into a Surface. -* `+` good performance for Android Views -* `+` best performance for Flutter rendering. -* `+` all transformations work correctly. -* `-` quick scrolling (such as a web view) will be janky -* `-` SurfaceViews are problematic in this mode and will be moved into a virtual -display (breaking a11y) -* `-` Text magnifier will break unless Flutter is rendered into a TextureView. +This approach provides: + +* good performance for Android Views +* good performance for Flutter rendering +* all transformations work correctly + +However, this approach might cause: + +* jankiness on quick scrolling (such as a web view) +* broken accessibility for `SurfaceView`s +* broken text magnification unless Flutter is rendered + into a `TextureView` ## On the Dart side -On the Dart side, create a `Widget` -and add one of the following build implementations. +To create a platform view on Android, use the following steps. +First, on the Dart side, create a `Widget` and add one of the +following build implementations depending on your chosen strategy. ### Hybrid composition @@ -142,7 +154,7 @@ use the following instructions: import 'package:flutter/services.dart'; ``` -2. Implement a `build()` method: +2. Implement a `build` method: ```dart @@ -179,7 +191,7 @@ use the following instructions: } ``` -For more information, visit the API docs for: +For more information, visit the following API docs: * [`PlatformViewLink`][] * [`AndroidViewSurface`][] @@ -203,7 +215,7 @@ use the following instructions: import 'package:flutter/services.dart'; ``` -2. Implement a `build()` method: +2. Implement a `build` method: ```dart @@ -222,9 +234,7 @@ use the following instructions: } ``` -For more information, visit the API docs for: - -* [`AndroidView`][] +For more information, visit the [`AndroidView`][] API page. [`AndroidView`]: {{site.api}}/flutter/widgets/AndroidView-class.html @@ -485,19 +495,70 @@ android { ### Manual view invalidation Certain Android Views don't invalidate themselves when their content changes. -Some example views include `SurfaceView` and `SurfaceTexture`. -When your Platform View includes these views, you are required to -manually invalidate the view after they have been drawn to -(or more specifically: after the swap chain is flipped). -Manual view invalidation is done by calling `invalidate` on the View -or one of its parent views. +Some examples include `SurfaceView` and `SurfaceTexture`. +When your Platform View includes these views, +you must manually invalidate it after it has been drawn +(or, more specifically, after the swap chain is flipped). +Invalidate the view by calling `invalidate` on it or on one of its parents. [`AndroidViewSurface`]: {{site.api}}/flutter/widgets/AndroidViewSurface-class.html ### Issues -[Existing Platform View issues][] +Check out the [existing Platform View issues][] on GitHub. + +[existing Platform View issues]: {{site.github}}/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3A%22a%3A+platform-views + +## Performance + +Platform views in Flutter come with performance trade-offs. + +In a typical Flutter app, +the Flutter UI is composed on a dedicated raster thread, +while platform code runs on the UI/platform thread. +This separation keeps Flutter rendering fast and fluid. + +However, when a platform view is rendered on Android using hybrid +composition, Flutter merges the raster and UI threads into a single thread to +ensure correct synchronization between the native Android views and the Flutter canvas. +Because of this thread merging, rendering complex Flutter widgets +alongside a platform view can compete with OS messages and plugin interactions, +potentially causing lower application FPS and frame drops. + +Also, prior to Android 10, hybrid composition copied each Flutter frame +out of the graphic memory into main memory, +and then copied it back to a GPU texture. As this copy happens per frame, +the performance of the entire Flutter UI might be impacted. +In Android 10 or above, the graphics memory is copied only once. + +Hybrid Composition++ (HCPP) minimizes this overhead by using native +transaction synchronization on supported devices (Android API 34+ with Vulkan), +allowing superior performance without the heavy costs of original hybrid +composition. + +Virtual display, on the other hand, makes each pixel of the native view flow +through additional intermediate graphic buffers, +which cost graphic memory and drawing performance. +This can cause jank during high-frequency updates like fast scrolling. + +For complex cases, there are some techniques that +can be used to mitigate these issues. + +For example, you can use a placeholder texture +while an animation is happening in Dart. +In other words, if an animation is slow while a +platform view is rendered, +then consider taking a screenshot of the +native view and rendering it as a texture. + +For more information, visit the following API pages: -{% render "docs/platform-view-perf.md", site: site %} +* [`TextureLayer`][] +* [`TextureRegistry`][] +* [`FlutterTextureRegistry`][] +* [`FlutterImageView`][] -[Existing Platform View issues]: {{site.github}}/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3A%22a%3A+platform-views +[`FlutterImageView`]: {{site.api}}/javadoc/io/flutter/embedding/android/FlutterImageView.html +[`FlutterTextureRegistry`]: {{site.api}}/ios-embedder/protocol_flutter_texture_registry-p.html +[`TextureLayer`]: {{site.api}}/flutter/rendering/TextureLayer-class.html +[`TextureRegistry`]: {{site.api}}/javadoc/io/flutter/view/TextureRegistry.html