Repository navigation
Conversation
71333df to
bd2a3b5
Compare
There was a problem hiding this comment.
Code Review
This pull request introduces support for presenting empty frames (frames with no layers) on macOS. It updates FlutterCompositor, FlutterSurfaceManager, FlutterView, and ResizeSynchronizer to handle empty frames without reporting a zero frame size, which previously caused issues during window resizing. Specifically, an empty frame now unblocks the resize synchronizer regardless of the target size it is waiting for. Unit tests have been added to verify this behavior. I have no feedback to provide.
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
bd2a3b5 to
6ac7d4b
Compare
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
|
Unfortunately this got stale and the macOS build fails. @edde746 any chance you'll have time to update the PR? |
`FlutterSurfaceManager` derived the committed frame size from the presented surfaces, starting at `CGSizeZero`. A frame with nothing to rasterize has no layers, so it committed a size of (0, 0), which never matches the size `ResizeSynchronizer.beginResize` waits for. Every resize step blocked the platform thread for the full one second timeout and logged "Resize timed out". Such a frame displays nothing that could be out of sync with the window, so `FlutterCompositor` now presents it with `presentEmptyFrameAtTime:notify:`, which commits it as an empty frame and unblocks a pending resize whatever size that resize waits for. Windows does the same in `FlutterWindowsView::OnEmptyFrameGenerated`. The empty frame is keyed on the frame having no layers, not on it presenting no surfaces. A frame whose only layer is a platform view also presents no surfaces, but that platform view is on screen and is positioned from the frame being committed, so it stays on the existing path. An empty frame reports the view's current size to `FlutterViewContentDelegate`, since it has no content size of its own. Reporting zero would resize a window sized to its contents down to nothing. The delegate still has to be notified, because `viewDidUpdateContents:withSize:` is what reveals a window waiting for its first frame. Measured with the sample and probe from the issue, 20 resize steps: 1021.04 ms mean per step and 20 timeouts before, 9.44 ms and none after.
6ac7d4b to
835da96
Compare
|
Rebased onto master and switched the empty-frame notification to |
knopp
left a comment
There was a problem hiding this comment.
Re-reviewing this - I am wondering why do we need to present methods, why not handle empty surfaces list instead?
|
An empty An empty frame has no size, so it unblocks If you prefer keying on |
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
Keep a one-pixel Flutter backing store alive on macOS so each resize can synchronize immediately. This is a temporary workaround until flutter/flutter#191862 is merged and available in Plezy's Flutter SDK. flutter/flutter#191862
FlutterSurfaceManagerderives the committed frame size from the presented surfaces, starting atCGSizeZero(GetRequiredFrameSize). A frame with nothing to rasterize has no layers at all, because the embedder's layer builder only adds a backing store layer whenHasEngineRenderedContents()is true. The committed size is then(0, 0), which never matches the sizeResizeSynchronizer.beginResizewaits for, so every resize step blocked the platform thread for the full one second timeout and loggedResize timed out.Such a frame displays nothing that could be out of sync with the window, so
FlutterCompositornow presents it with a newpresentEmptyFrameAtTime:notify:, which reachesResizeSynchronizeras an empty frame and unblocks a pending resize whatever size that resize waits for. Windows does the same inOnEmptyFrameGenerated, covered there byTestEmptyFrameResizes.The empty frame is keyed on the frame having no layers, not on it presenting no surfaces. A frame whose only layer is a platform view also presents no surfaces, but that platform view is on screen and is positioned from the frame being committed, so unblocking on it would leave the platform view at the pre-resize geometry. Those frames keep their existing behavior and still stall, measured at 1017.10 ms per resize step with this PR versus 1019.15 ms without it. That case needs the frame's real size to synchronize against, which the embedder does not currently give the macOS compositor, so I left it out of this PR and filed #191865 for it.
An empty frame reports the view's current size to
FlutterViewContentDelegate, since it has no content size of its own. Reporting zero, as the old code did, would shrink a window sized to its contents to nothing. The delegate still has to be notified, sinceviewDidUpdateContents:withSize:is what reveals a window waiting for its first frame.FlutterSurfaceManagerDelegateis not a public framework header, so its new required method is not an API change for embedders.Verification
Sample and probe from the issue, 20 resize steps through
-[FlutterView setFrameSize:], localmac_debug_unopt_arm64engine atde37392db47, macOS 27.0.1 arm64:Resize timed outflutter_desktop_darwin_unittests(240 tests) andflutter_desktop_darwin_swift_unittests(5 tests) pass, and clang-tidy is clean. Each new test was confirmed to fail with the corresponding part of the fix reverted.Fixes #190075
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.