From 8572ee247aee319774fec198538cf361b67f0325 Mon Sep 17 00:00:00 2001 From: lindexi Date: Thu, 5 Mar 2026 10:15:29 +0800 Subject: [PATCH] Add the dynamic Transparency alpha mode support to DirectComposited --- .../DComposition/DirectCompositedWindow.cs | 11 ++++- .../DirectCompositedWindowSurface.cs | 49 ++++++++++++++++--- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/Windows/Avalonia.Win32/DComposition/DirectCompositedWindow.cs b/src/Windows/Avalonia.Win32/DComposition/DirectCompositedWindow.cs index 8935e8bcbf..de8caa85cc 100644 --- a/src/Windows/Avalonia.Win32/DComposition/DirectCompositedWindow.cs +++ b/src/Windows/Avalonia.Win32/DComposition/DirectCompositedWindow.cs @@ -1,6 +1,6 @@ using System; -using System.Numerics; using System.Threading; +using Avalonia.Controls; using Avalonia.OpenGL.Egl; using Avalonia.Reactive; using MicroCom.Runtime; @@ -51,4 +51,13 @@ internal class DirectCompositedWindow : IDisposable Monitor.Exit(_shared.SyncRoot); }); } + + public bool IsTransparency => _transparencyLevel != WindowTransparencyLevel.None; + + public void SetTransparencyLevel(WindowTransparencyLevel transparencyLevel) + { + _transparencyLevel = transparencyLevel; + } + + private WindowTransparencyLevel _transparencyLevel; } diff --git a/src/Windows/Avalonia.Win32/DComposition/DirectCompositedWindowSurface.cs b/src/Windows/Avalonia.Win32/DComposition/DirectCompositedWindowSurface.cs index e1b0a87aaa..15e0f60c3c 100644 --- a/src/Windows/Avalonia.Win32/DComposition/DirectCompositedWindowSurface.cs +++ b/src/Windows/Avalonia.Win32/DComposition/DirectCompositedWindowSurface.cs @@ -1,10 +1,15 @@ using System; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; + using Avalonia.Controls; +using Avalonia.Controls.Shapes; using Avalonia.OpenGL.Egl; using Avalonia.Platform; using Avalonia.Win32.DirectX; using Avalonia.Win32.Interop; +using Avalonia.Win32.WinRT; + using MicroCom.Runtime; namespace Avalonia.Win32.DComposition; @@ -26,6 +31,7 @@ internal class DirectCompositedWindowSurface : IDirect3D11TexturePlatformSurface { _window ??= new DirectCompositedWindow(_info, _shared); SetBlur(_blurEffect); + _window.SetTransparencyLevel(_windowTransparencyLevel); return new DirectCompositedWindowRenderTarget(context, d3dDevice, _shared, _window); } @@ -47,8 +53,11 @@ internal class DirectCompositedWindowSurface : IDirect3D11TexturePlatformSurface public void SetTransparencyLevel(WindowTransparencyLevel transparencyLevel) { - + _windowTransparencyLevel = transparencyLevel; + _window?.SetTransparencyLevel(transparencyLevel); } + + private WindowTransparencyLevel _windowTransparencyLevel; } internal class DirectCompositedWindowRenderTarget : IDirect3D11TextureRenderTarget @@ -56,11 +65,13 @@ internal class DirectCompositedWindowRenderTarget : IDirect3D11TextureRenderTarg private static readonly Guid IID_ID3D11Texture2D = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); private readonly IPlatformGraphicsContext _context; + private readonly DirectCompositionShared _shared; private readonly DirectCompositedWindow _window; - private readonly IDCompositionVirtualSurface _surface; + private IDCompositionVirtualSurface _surface; private bool _lost; private PixelSize _size; private readonly IUnknown _d3dDevice; + private bool _isSurfaceSupportTransparency; public DirectCompositedWindowRenderTarget( IPlatformGraphicsContext context, IntPtr d3dDevice, @@ -69,13 +80,25 @@ internal class DirectCompositedWindowRenderTarget : IDirect3D11TextureRenderTarg _d3dDevice = MicroComRuntime.CreateProxyFor(d3dDevice, false).CloneReference(); _context = context; + _shared = shared; _window = window; - using (var surfaceFactory = shared.Device.CreateSurfaceFactory(_d3dDevice)) - { - _surface = surfaceFactory.CreateVirtualSurface(1, 1, DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_PREMULTIPLIED); - } + CreateSurface(window); + } + + [MemberNotNull(nameof(_surface))] + private void CreateSurface(DirectCompositedWindow window) + { + using var surfaceFactory = _shared.Device.CreateSurfaceFactory(_d3dDevice); + + const uint initialSize = 1; + var alphaMode = window.IsTransparency ? + DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_PREMULTIPLIED : + DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_IGNORE; + _isSurfaceSupportTransparency = window.IsTransparency; + + _surface = surfaceFactory.CreateVirtualSurface(initialSize, initialSize, DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM, + alphaMode); } public void Dispose() @@ -94,9 +117,19 @@ internal class DirectCompositedWindowRenderTarget : IDirect3D11TextureRenderTarg bool needsEndDraw = false; try { + bool forceResize = false; + if (_window.IsTransparency != _isSurfaceSupportTransparency) + { + _surface.Dispose(); + + CreateSurface(_window); + + forceResize = true; + } + var size = _window.WindowInfo.Size; var scale = _window.WindowInfo.Scaling; - if (_size != size) + if (forceResize || _size != size) { _surface.Resize((ushort)size.Width, (ushort)size.Height); _size = size;