From a78a1143f776356d191ad14014cbe26d6ba7be0d Mon Sep 17 00:00:00 2001 From: "Shams Zakhour (ignore Sfshaza)" Date: Tue, 5 May 2026 12:59:00 -0700 Subject: [PATCH 1/3] Cleaning up the Hosting native Android views page --- .../src/_includes/docs/platform-view-perf.md | 40 ++++----- .../android/platform-views.md | 84 ++++++++++--------- 2 files changed, 67 insertions(+), 57 deletions(-) diff --git a/sites/docs/src/_includes/docs/platform-view-perf.md b/sites/docs/src/_includes/docs/platform-view-perf.md index 931c645f662..5464c028d57 100644 --- a/sites/docs/src/_includes/docs/platform-view-perf.md +++ b/sites/docs/src/_includes/docs/platform-view-perf.md @@ -2,24 +2,26 @@ 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. +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. + +**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** (used by the texture layer mode), on the other hand, +avoids thread merging but forces every pixel of the native Android view to flow +through additional intermediate graphic buffers, which increases graphic memory +usage and 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. @@ -31,7 +33,7 @@ platform view is rendered, then consider taking a screenshot of the native view and rendering it as a texture. -For more information, see: +For more information, visit: * [`TextureLayer`][] * [`TextureRegistry`][] 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..947f38f4c86 100644 --- a/sites/docs/src/content/platform-integration/android/platform-views.md +++ b/sites/docs/src/content/platform-integration/android/platform-views.md @@ -31,18 +31,25 @@ 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** | • Best Flutter performance
• Full widget transforms work | • Janky during quick scrolling
• SurfaceViews break | Default behavior or `AndroidView` | +| **Hybrid Composition** | • Full native fidelity
• Correct a11y and SurfaceViews | • Causes thread merging, which degrades Flutter FPS | `PlatformViewLink` with `AndroidViewSurface` | +| **Hybrid Composition++ (HCPP)** (Experimental) | • Full fidelity and performance
• Solves original sync overhead | • Requires Android API 34+ and Vulkan support | `` in `AndroidManifest.xml` | + +{:.table .table-striped} + + +## 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 } :::note @@ -58,7 +65,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,7 +79,7 @@ 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)**: +1. **Command line flag (run/test)**: Pass the `--enable-hcpp` flag to your `flutter run` or `flutter test` command: ```bash @@ -81,7 +88,7 @@ You can enable HCPP using one of the following methods: :::note This flag is intended for local execution and testing. - It **can't** be passed to the `flutter build` commands. + **It can't be passed to the `flutter build` commands.** For release builds, use the manifest configuration as shown in the next step. ::: @@ -98,34 +105,37 @@ You can enable HCPP using one of the following methods: ### 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 +* best performance for Flutter rendering +* all transformations work correctly + +However, this approach might cause: + +* jankiness on quick scrolling (such as a web view) +* broken a11y if `SurfaceView`s are moved into a virtual display +* broken text magnification unless 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 +### Hybrid Composition In your Dart file, for example `native_view_example.dart`, @@ -142,7 +152,7 @@ use the following instructions: import 'package:flutter/services.dart'; ``` -2. Implement a `build()` method: +2. Implement a `build` method: ```dart @@ -179,7 +189,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 +213,7 @@ use the following instructions: import 'package:flutter/services.dart'; ``` -2. Implement a `build()` method: +2. Implement a `build` method: ```dart @@ -222,9 +232,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 +493,19 @@ 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 +Some examples include `SurfaceView` and `SurfaceTexture`. +When your Platform View includes these views, you must +manually invalidate the view after it's 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. [`AndroidViewSurface`]: {{site.api}}/flutter/widgets/AndroidViewSurface-class.html ### Issues -[Existing Platform View issues][] +Check out the [existing Platform View issues][] on GitHub. {% render "docs/platform-view-perf.md", site: site %} -[Existing Platform View issues]: {{site.github}}/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3A%22a%3A+platform-views +[existing Platform View issues]: {{site.github}}/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3A%22a%3A+platform-views From 015943814554a01326a877f00d3f9d98d2c06a26 Mon Sep 17 00:00:00 2001 From: "Shams Zakhour (ignore Sfshaza)" Date: Tue, 5 May 2026 13:07:00 -0700 Subject: [PATCH 2/3] Incorporating feedback --- .../platform-integration/android/platform-views.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 947f38f4c86..59784dfc70b 100644 --- a/sites/docs/src/content/platform-integration/android/platform-views.md +++ b/sites/docs/src/content/platform-integration/android/platform-views.md @@ -38,8 +38,8 @@ The following matrix summarizes the different implementations and their trade-of | Mode | Benefits | Considerations | Enabler | | :--- | :--- | :--- | :--- | | **Texture layer** | • Best Flutter performance
• Full widget transforms work | • Janky during quick scrolling
• SurfaceViews break | Default behavior or `AndroidView` | -| **Hybrid Composition** | • Full native fidelity
• Correct a11y and SurfaceViews | • Causes thread merging, which degrades Flutter FPS | `PlatformViewLink` with `AndroidViewSurface` | -| **Hybrid Composition++ (HCPP)** (Experimental) | • Full fidelity and performance
• Solves original sync overhead | • Requires Android API 34+ and Vulkan support | `` in `AndroidManifest.xml` | +| **Hybrid Composition** | • Full native fidelity
• Correct accessibility and SurfaceViews | • Causes thread merging, which degrades Flutter FPS | `PlatformViewLink` with `AndroidViewSurface` | +| **Hybrid Composition++ (HCPP)** (Experimental) | • Full fidelity and performance
• Solves original sync overhead | • Requires Android API 34+ and Vulkan support | `` and `PlatformViewLink` in `AndroidManifest.xml` | {:.table .table-striped} @@ -126,8 +126,9 @@ This approach provides: However, this approach might cause: * jankiness on quick scrolling (such as a web view) -* broken a11y if `SurfaceView`s are moved into a virtual display -* broken text magnification unless rendered into a `TextureView` +* broken accessibility for `SurfaceView`s +* broken text magnification unless Flutter is rendered + into a `TextureView` ## On the Dart side From 39505d45e075af24842a88f9de5ca1d2fbc3f85e Mon Sep 17 00:00:00 2001 From: "Shams Zakhour (ignore Sfshaza)" Date: Tue, 5 May 2026 20:58:25 -0700 Subject: [PATCH 3/3] Incorporated feedback --- .../src/_includes/docs/platform-view-perf.md | 46 ------------- .../android/platform-views.md | 69 ++++++++++++++++--- 2 files changed, 60 insertions(+), 55 deletions(-) delete mode 100644 sites/docs/src/_includes/docs/platform-view-perf.md 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 5464c028d57..00000000000 --- a/sites/docs/src/_includes/docs/platform-view-perf.md +++ /dev/null @@ -1,46 +0,0 @@ -## 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. - -**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** (used by the texture layer mode), on the other hand, -avoids thread merging but forces every pixel of the native Android view to flow -through additional intermediate graphic buffers, which increases graphic memory -usage and 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 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, visit: - -* [`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 59784dfc70b..bdcbb9e680c 100644 --- a/sites/docs/src/content/platform-integration/android/platform-views.md +++ b/sites/docs/src/content/platform-integration/android/platform-views.md @@ -37,9 +37,9 @@ The following matrix summarizes the different implementations and their trade-of | Mode | Benefits | Considerations | Enabler | | :--- | :--- | :--- | :--- | -| **Texture layer** | • Best Flutter performance
• Full widget transforms work | • Janky during quick scrolling
• SurfaceViews break | Default behavior or `AndroidView` | -| **Hybrid Composition** | • Full native fidelity
• Correct accessibility and SurfaceViews | • Causes thread merging, which degrades Flutter FPS | `PlatformViewLink` with `AndroidViewSurface` | -| **Hybrid Composition++ (HCPP)** (Experimental) | • Full fidelity and performance
• Solves original sync overhead | • Requires Android API 34+ and Vulkan support | `` and `PlatformViewLink` in `AndroidManifest.xml` | +| **Texture layer** | • Best 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, which degrades Flutter FPS | `PlatformViewLink` with `AndroidViewSurface` | +| **HCPP** (Experimental) | • Full fidelity and performance
• Solves original sync overhead | • Requires Android API 34+ and Vulkan support | • `` in `AndroidManifest.xml`
• `--enable-hcpp` local flag | {:.table .table-striped} @@ -495,11 +495,10 @@ android { Certain Android Views don't invalidate themselves when their content changes. Some examples include `SurfaceView` and `SurfaceTexture`. -When your Platform View includes these views, you must -manually invalidate the view after it's been drawn to +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). -Manual view invalidation is done by calling `invalidate` on the view -or one of its parent views. +Invalidate the view by calling `invalidate` on it or on one of its parents. [`AndroidViewSurface`]: {{site.api}}/flutter/widgets/AndroidViewSurface-class.html @@ -507,6 +506,58 @@ or one of its parent views. Check out the [existing Platform View issues][] on GitHub. -{% render "docs/platform-view-perf.md", site: site %} - [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 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, visit the following API pages: + +* [`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