Win32PlatformOptions.UseCompositionSwapchain - #22115
Conversation
…der thread Adds an opaque CompositionTarget.TopLevelSpecificSceneInfo bag (with the corresponding ITopLevelImpl property and changed callback) that travels through the composition transport and arrives in RenderTargetSceneInfo. The Win32 backend publishes the theme variant through it. The WinUI/DComp composited window render targets now apply blur/mica visual state in BeginDraw, based on the transparency level and theme variant from the scene info, inside the same transaction as the frame. The UI-thread ICompositionEffectsSurface.SetBlur path is removed, so effect changes can no longer race the render thread and produce frames with mismatched alpha mode and blur state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TrfgSxPjyUvvKsAPFZoLR1
When enabled with the WinUIComposition or DirectComposition composition mode, the window content is rendered into a DXGI flip-model swapchain created via CreateSwapChainForComposition and attached as the content of the window's visual, instead of a composition drawing surface. This allows DWM to use optimized presentation modes (independent flip) for fullscreen windows and reduces presentation latency. The swapchain uses Present(0, 0) without ALLOW_TEARING, and is recreated when the transparency level changes alpha mode between IGNORE and PREMULTIPLIED. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TrfgSxPjyUvvKsAPFZoLR1
| var desc = new DXGI_SWAP_CHAIN_DESC1 | ||
| { | ||
| Width = (uint)size.Width, | ||
| Height = (uint)size.Height, | ||
| Format = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM, | ||
| SampleDesc = { Count = 1, Quality = 0 }, | ||
| BufferUsage = DxgiRenderTarget.DXGI_USAGE_RENDER_TARGET_OUTPUT, | ||
| BufferCount = 2, | ||
| Scaling = DXGI_SCALING.DXGI_SCALING_STRETCH, | ||
| // FLIP_DISCARD is not available on Windows 8.x | ||
| SwapEffect = Win32Platform.WindowsVersion >= PlatformConstants.Windows10 ? | ||
| DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_DISCARD : | ||
| DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, | ||
| // Premultiplied alpha increases the DWM composition cost and prevents optimized | ||
| // presentation modes, so it's only used when the window is actually transparent, | ||
| // see https://github.com/AvaloniaUI/Avalonia/issues/20643 | ||
| AlphaMode = isTransparency ? | ||
| DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_PREMULTIPLIED : | ||
| DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_IGNORE | ||
| }; |
There was a problem hiding this comment.
nit: there is some duplication with WinUI embedded backend -
Avalonia/src/Windows/Avalonia.Win32/OpenGl/Angle/SwapChainGlSurface.cs
Lines 108 to 119 in a61d80b
I think it's fine to keep these separated, winui one is angle+winui specific. But just FYI.
There was a problem hiding this comment.
I suppose WinUI backend could implement ISwapchainVisualHost and reuse part
| /// WinUI composition path, looser visual synchronization during interactive resize. | ||
| /// The default value is null, which lets the framework decide (currently: disabled). | ||
| /// </summary> | ||
| public bool? UseCompositionSwapchain { get; set; } |
There was a problem hiding this comment.
Do we deprecate Win32CompositionMode.LowLatencyDxgiSwapChain?
| /// WinUI composition path, looser visual synchronization during interactive resize. | ||
| /// The default value is null, which lets the framework decide (currently: disabled). | ||
| /// </summary> | ||
| public bool? UseCompositionSwapchain { get; set; } |
There was a problem hiding this comment.
Alternative API:
public enum Win32CompositionMode
{
WinUIComposition = 1,
DirectComposition = 2,
+ [Obsolete("Use WinUICompositionSwapchain or DirectCompositionSwapchain")]
LowLatencyDxgiSwapChain = 3,
RedirectionSurface = 4,
+ WinUICompositionSwapchain = 5,
+ DirectCompositionSwapchain = 6,
}There was a problem hiding this comment.
Not sure if it's really better, but what do you think.
UseCompositionSwapchain on its own doesn't make sense without composition mode. And less root options API pollution. But then we are only limited to enums in composition mode. With this another API we would also lose "null default" state, but not sure if it's necessary.
This PR introduces
Win32PlatformOptions.UseCompositionSwapchainthat usesCreateSwapchainForCompositioninstead of our existing frugal "dear-DWM-give-us-a-texture-chunk-to-render-into" approach. This enables Direct/Independent Flip for our primary supported WinUI and DirectComposition modes instead of "low latency swapchain" mode we've attached via duct tape a while ago.Merge after #22114