Conversation
Contributor
There was a problem hiding this comment.
Code Review
This pull request refactors FlutterMetalLayer to inherit directly from CAMetalLayer instead of CALayer, removing custom display link logic and introducing a blit copy from the IOSurface-backed Flutter texture to the native drawable. It also restricts wide gamut support to devices supporting MTLGPUFamilyApple3. Feedback highlights a potential thread-blocking issue when acquiring drawables during a resize, suggesting a size and format check beforehand, and a potential crash on iOS 12 due to the use of supportsFamily:, recommending a selector check.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR removes an additional one-frame presentation delay on iOS while preserving Flutter's existing platform-view compatibility.
FlutterMetalLayercurrently subclassesCALayerand emulates theCAMetalLayerinterface. Flutter renders into IOSurface-backed Metal textures and presents each completed frame by assigning its IOSurface toCALayer.contents.While this supports the Core Animation transaction used for platform-view composition, the
CALayer.contentsupdate introduces an additional display interval before the Flutter frame becomes visible.This PR changes
FlutterMetalLayerto subclassCAMetalLayerand uses a nativeCAMetalDrawablefor final presentation, while retaining Flutter's IOSurface-backed rendering path.The updated presentation flow is:
flutterPrepareForPresent:, the layer acquires a nativeCAMetalDrawable.This allows the Flutter frame to use the native
CAMetalLayerpresentation path without giving up the IOSurface lifecycle required by the existing platform-view composition architecture.Encoding the copy on the same command buffer preserves GPU ordering without requiring a CPU wait. The native drawable is also acquired during preparation rather than at the beginning of rendering, keeping its lifetime relatively short.
This change additionally removes the need for
FlutterMetalLayerto:CAMetalLayerinterface from aCALayersubclass;isKindOfClass:to behave as aCAMetalLayer;CALayer.contentsasynchronously on the main thread; andCADisplayLinkworkaround for ProMotion presentation.If a resize causes the Flutter render target and native drawable to have different dimensions or pixel formats, the frame is not copied.
Platform-view compatibility
The recording below demonstrates that Flutter and UIKit content continue to be composed and updated together using the new presentation path.
video.mp4
It covers platform-view interaction, animation, creation, removal, recreation, and periods without continuous Flutter animation.
This recording is intended to demonstrate platform-view compatibility rather than measure presentation latency.
Wide-gamut compatibility
A real
CAMetalLayervalidates its pixel format against the capabilities of its Metal device. Extended-range formats are therefore enabled only when the device supports the required Apple GPU family.The related tests have been updated to account for the default color-space behavior of a real
CAMetalLayerand simulator GPUs that do not support extended-range formats.Investigation
The latency measurements, reduction process, alternative presentation experiments, and physical-device testing that led to this implementation are documented in #191543.
This PR extracts only the final presentation-side change from that investigation. The unrelated pointer-delivery, VSync, autorelease-pool, and experimental presentation changes explored there are not included.
Related issues
Related to #110431 and #175790.
Pre-launch Checklist
///).