Browse Source

Merge branch 'master' into master

pull/12215/head
Max Katz 3 years ago
committed by GitHub
parent
commit
2a4f62a3b3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/Windows/Avalonia.Win32/WinRT/Composition/D2DEffects.cs
  2. 104
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs
  3. 30
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs
  4. 9
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs
  5. 72
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs
  6. 3
      src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs
  7. 23
      src/Windows/Avalonia.Win32/WinRT/WinRTPropertyValue.cs
  8. 13
      src/Windows/Avalonia.Win32/WindowImpl.cs

3
src/Windows/Avalonia.Win32/WinRT/Composition/D2DEffects.cs

@ -28,6 +28,9 @@ namespace Avalonia.Win32.WinRT.Composition
public static readonly Guid CLSID_D2D1Border = public static readonly Guid CLSID_D2D1Border =
new Guid(0x2A2D49C0, 0x4ACF, 0x43C7, 0x8C, 0x6A, 0x7C, 0x4A, 0x27, 0x87, 0x4D, 0x27); new Guid(0x2A2D49C0, 0x4ACF, 0x43C7, 0x8C, 0x6A, 0x7C, 0x4A, 0x27, 0x87, 0x4D, 0x27);
public static readonly Guid CLSID_D2D1Opacity =
new Guid("811d79a4-de28-4454-8094-c64685f8bd4c");
public static readonly Guid CLSID_D2D1Brightness = public static readonly Guid CLSID_D2D1Brightness =
new Guid(0x8CEA8D1E, 0x77B0, 0x4986, 0xB3, 0xB9, 0x2F, 0x0C, 0x0E, 0xAE, 0x78, 0x87); new Guid(0x8CEA8D1E, 0x77B0, 0x4986, 0xB3, 0xB9, 0x2F, 0x0C, 0x0E, 0xAE, 0x78, 0x87);

104
src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs

@ -52,6 +52,110 @@ namespace Avalonia.Win32.WinRT.Composition
_sources = null; _sources = null;
} }
} }
class BorderEffect : WinUIEffectBase
{
private readonly int _x;
private readonly int _y;
public override Guid EffectId => D2DEffects.CLSID_D2D1Border;
public override uint PropertyCount => 2;
public BorderEffect(int x, int y, params IGraphicsEffectSource[] _sources):base(_sources)
{
_x = x;
_y = y;
}
public override IPropertyValue? GetProperty(uint index)
{
if (index == 0)
return new WinRTPropertyValue((uint)_x);
if (index == 1)
return new WinRTPropertyValue((uint)_y);
return null;
}
}
class BlendEffect : WinUIEffectBase
{
private readonly int _mode;
public BlendEffect(int mode, params IGraphicsEffectSource[] _sources) : base(_sources)
{
_mode = mode;
}
public override Guid EffectId => D2DEffects.CLSID_D2D1Blend;
public override uint PropertyCount => 1;
public override IPropertyValue? GetProperty(uint index)
{
if (index == 0)
return new WinRTPropertyValue((uint)_mode);
return null;
}
}
class CompositeStepEffect : WinUIEffectBase
{
private readonly float _mode;
public CompositeStepEffect(int mode, params IGraphicsEffectSource[] _sources) : base(_sources)
{
_mode = mode;
}
public override Guid EffectId => D2DEffects.CLSID_D2D1Composite;
public override uint PropertyCount => 1;
public override IPropertyValue? GetProperty(uint index)
{
if (index == 0)
return new WinRTPropertyValue((uint)_mode);
return null;
}
}
class OpacityEffect : WinUIEffectBase
{
private readonly float _opacity;
public OpacityEffect(float opacity, params IGraphicsEffectSource[] _sources) : base(_sources)
{
_opacity = opacity;
}
public override Guid EffectId => D2DEffects.CLSID_D2D1Opacity;
public override uint PropertyCount => 1;
public override IPropertyValue? GetProperty(uint index)
{
if (index == 0)
return new WinRTPropertyValue(_opacity);
return null;
}
}
class ColorSourceEffect : WinUIEffectBase
{
private readonly float[] _color;
public ColorSourceEffect(float[] color)
{
_color = color;
}
public override Guid EffectId => D2DEffects.CLSID_D2D1Flood;
public override uint PropertyCount => 1;
public override IPropertyValue? GetProperty(uint index)
{
if (index == 0)
return new WinRTPropertyValue(_color);
return null;
}
}
internal class WinUIGaussianBlurEffect : WinUIEffectBase internal class WinUIGaussianBlurEffect : WinUIEffectBase
{ {

30
src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs

@ -12,7 +12,8 @@ internal class WinUiCompositedWindow : IDisposable
public EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo WindowInfo { get; } public EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo WindowInfo { get; }
private readonly WinUiCompositionShared _shared; private readonly WinUiCompositionShared _shared;
private readonly ICompositionRoundedRectangleGeometry? _compositionRoundedRectangleGeometry; private readonly ICompositionRoundedRectangleGeometry? _compositionRoundedRectangleGeometry;
private readonly IVisual? _mica; private readonly IVisual? _micaLight;
private readonly IVisual? _micaDark;
private readonly IVisual _blur; private readonly IVisual _blur;
private readonly IVisual _visual; private readonly IVisual _visual;
private PixelSize _size; private PixelSize _size;
@ -25,7 +26,8 @@ internal class WinUiCompositedWindow : IDisposable
{ {
_compositionRoundedRectangleGeometry?.Dispose(); _compositionRoundedRectangleGeometry?.Dispose();
_blur.Dispose(); _blur.Dispose();
_mica?.Dispose(); _micaLight?.Dispose();
_micaDark?.Dispose();
_visual.Dispose(); _visual.Dispose();
_surfaceBrush.Dispose(); _surfaceBrush.Dispose();
_target.Dispose(); _target.Dispose();
@ -50,14 +52,20 @@ internal class WinUiCompositedWindow : IDisposable
_target.SetRoot(containerVisual); _target.SetRoot(containerVisual);
_blur = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.BlurBrush); _blur = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.BlurBrush);
if (shared.MicaBrush != null) if (shared.MicaBrushLight != null)
{ {
_mica = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.MicaBrush); _micaLight = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.MicaBrushLight);
containerChildren.InsertAtTop(_mica); containerChildren.InsertAtTop(_micaLight);
}
if (shared.MicaBrushDark != null)
{
_micaDark = WinUiCompositionUtils.CreateBlurVisual(shared.Compositor, shared.MicaBrushDark);
containerChildren.InsertAtTop(_micaDark);
} }
_compositionRoundedRectangleGeometry = _compositionRoundedRectangleGeometry =
WinUiCompositionUtils.ClipVisual(shared.Compositor, backdropCornerRadius, _blur, _mica); WinUiCompositionUtils.ClipVisual(shared.Compositor, backdropCornerRadius, _blur, _micaLight, _micaDark);
containerChildren.InsertAtTop(_blur); containerChildren.InsertAtTop(_blur);
using var spriteVisual = shared.Compositor.CreateSpriteVisual(); using var spriteVisual = shared.Compositor.CreateSpriteVisual();
@ -68,9 +76,6 @@ internal class WinUiCompositedWindow : IDisposable
using var compositionBrush = _surfaceBrush.QueryInterface<ICompositionBrush>(); using var compositionBrush = _surfaceBrush.QueryInterface<ICompositionBrush>();
spriteVisual.SetBrush(compositionBrush); spriteVisual.SetBrush(compositionBrush);
_target.SetRoot(containerVisual); _target.SetRoot(containerVisual);
} }
public void SetSurface(ICompositionSurface surface) => _surfaceBrush.SetSurface(surface); public void SetSurface(ICompositionSurface surface) => _surfaceBrush.SetSurface(surface);
@ -79,12 +84,13 @@ internal class WinUiCompositedWindow : IDisposable
{ {
lock (_shared.SyncRoot) lock (_shared.SyncRoot)
{ {
_blur.SetIsVisible(blurEffect == BlurEffect.Acrylic _blur.SetIsVisible(blurEffect == BlurEffect.Acrylic
|| blurEffect == BlurEffect.Mica && _mica == null ? || (blurEffect == BlurEffect.MicaLight && _micaLight == null) ||
(blurEffect == BlurEffect.MicaDark && _micaDark == null) ?
1 : 1 :
0); 0);
_mica?.SetIsVisible(blurEffect == BlurEffect.Mica ? 1 : 0); _micaLight?.SetIsVisible(blurEffect == BlurEffect.MicaLight ? 1 : 0);
_micaDark?.SetIsVisible(blurEffect == BlurEffect.MicaDark ? 1 : 0);
} }
} }

9
src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs

@ -9,7 +9,8 @@ internal class WinUiCompositionShared : IDisposable
public ICompositor5 Compositor5 { get; } public ICompositor5 Compositor5 { get; }
public ICompositorDesktopInterop DesktopInterop { get; } public ICompositorDesktopInterop DesktopInterop { get; }
public ICompositionBrush BlurBrush { get; } public ICompositionBrush BlurBrush { get; }
public ICompositionBrush? MicaBrush { get; } public ICompositionBrush? MicaBrushLight { get; }
public ICompositionBrush? MicaBrushDark { get; }
public object SyncRoot { get; } = new(); public object SyncRoot { get; } = new();
public static readonly Version MinWinCompositionVersion = new(10, 0, 17134); public static readonly Version MinWinCompositionVersion = new(10, 0, 17134);
@ -21,14 +22,16 @@ internal class WinUiCompositionShared : IDisposable
Compositor = compositor.CloneReference(); Compositor = compositor.CloneReference();
Compositor5 = compositor.QueryInterface<ICompositor5>(); Compositor5 = compositor.QueryInterface<ICompositor5>();
BlurBrush = WinUiCompositionUtils.CreateAcrylicBlurBackdropBrush(compositor); BlurBrush = WinUiCompositionUtils.CreateAcrylicBlurBackdropBrush(compositor);
MicaBrush = WinUiCompositionUtils.CreateMicaBackdropBrush(compositor); MicaBrushLight = WinUiCompositionUtils.CreateMicaBackdropBrush(compositor, 242, 0.6f);
MicaBrushDark = WinUiCompositionUtils.CreateMicaBackdropBrush(compositor, 32, 0.8f);
DesktopInterop = compositor.QueryInterface<ICompositorDesktopInterop>(); DesktopInterop = compositor.QueryInterface<ICompositorDesktopInterop>();
} }
public void Dispose() public void Dispose()
{ {
BlurBrush.Dispose(); BlurBrush.Dispose();
MicaBrush?.Dispose(); MicaBrushLight?.Dispose();
MicaBrushDark?.Dispose();
DesktopInterop.Dispose(); DesktopInterop.Dispose();
Compositor.Dispose(); Compositor.Dispose();
Compositor5.Dispose(); Compositor5.Dispose();

72
src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs

@ -1,3 +1,4 @@
using System;
using System.Numerics; using System.Numerics;
using MicroCom.Runtime; using MicroCom.Runtime;
@ -5,16 +6,72 @@ namespace Avalonia.Win32.WinRT.Composition;
internal static class WinUiCompositionUtils internal static class WinUiCompositionUtils
{ {
public static ICompositionBrush? CreateMicaBackdropBrush(ICompositor compositor) public static ICompositionBrush? CreateMicaBackdropBrush(ICompositor compositor, float color, float opacity)
{ {
if (Win32Platform.WindowsVersion.Build < 22000) if (Win32Platform.WindowsVersion.Build < 22000)
return null; return null;
using var backDropParameterFactory =
NativeWinRTMethods.CreateActivationFactory<ICompositionEffectSourceParameterFactory>(
"Windows.UI.Composition.CompositionEffectSourceParameter");
var tint = new[] { color / 255f, color / 255f, color / 255f, 255f / 255f };
using var tintColorEffect = new ColorSourceEffect(tint);
using var tintOpacityEffect = new OpacityEffect(1.0f, tintColorEffect);
using var tintOpacityEffectFactory = compositor.CreateEffectFactory(tintOpacityEffect);
using var tintOpacityEffectBrushEffect = tintOpacityEffectFactory.CreateBrush();
using var tintOpacityEffectBrush = tintOpacityEffectBrushEffect.QueryInterface<ICompositionBrush>();
using var luminosityColorEffect = new ColorSourceEffect(tint);
using var luminosityOpacityEffect = new OpacityEffect(opacity, luminosityColorEffect);
using var luminosityOpacityEffectFactory = compositor.CreateEffectFactory(luminosityOpacityEffect);
using var luminosityOpacityEffectBrushEffect = luminosityOpacityEffectFactory.CreateBrush();
using var luminosityOpacityEffectBrush =
luminosityOpacityEffectBrushEffect.QueryInterface<ICompositionBrush>();
using var compositorWithBlurredWallpaperBackdropBrush = using var compositorWithBlurredWallpaperBackdropBrush =
compositor.QueryInterface<ICompositorWithBlurredWallpaperBackdropBrush>(); compositor.QueryInterface<ICompositorWithBlurredWallpaperBackdropBrush>();
using var blurredWallpaperBackdropBrush = using var blurredWallpaperBackdropBrush =
compositorWithBlurredWallpaperBackdropBrush?.TryCreateBlurredWallpaperBackdropBrush(); compositorWithBlurredWallpaperBackdropBrush?.TryCreateBlurredWallpaperBackdropBrush();
return blurredWallpaperBackdropBrush?.QueryInterface<ICompositionBrush>(); using var micaBackdropBrush = blurredWallpaperBackdropBrush?.QueryInterface<ICompositionBrush>();
using var backgroundParameterAsSource =
GetParameterSource("Background", backDropParameterFactory, out var backgroundHandle);
using var foregroundParameterAsSource =
GetParameterSource("Foreground", backDropParameterFactory, out var foregroundHandle);
using var luminosityBlendEffect =
new BlendEffect(23, backgroundParameterAsSource, foregroundParameterAsSource);
using var luminosityBlendEffectFactory = compositor.CreateEffectFactory(luminosityBlendEffect);
using var luminosityBlendEffectBrush = luminosityBlendEffectFactory.CreateBrush();
using var luminosityBlendEffectBrush1 = luminosityBlendEffectBrush.QueryInterface<ICompositionBrush>();
luminosityBlendEffectBrush.SetSourceParameter(backgroundHandle, micaBackdropBrush);
luminosityBlendEffectBrush.SetSourceParameter(foregroundHandle, luminosityOpacityEffectBrush);
using var backgroundParameterAsSource1 =
GetParameterSource("Background", backDropParameterFactory, out var backgroundHandle1);
using var foregroundParameterAsSource1 =
GetParameterSource("Foreground", backDropParameterFactory, out var foregroundHandle1);
using var colorBlendEffect =
new BlendEffect(22, backgroundParameterAsSource1, foregroundParameterAsSource1);
using var colorBlendEffectFactory = compositor.CreateEffectFactory(colorBlendEffect);
using var colorBlendEffectBrush = colorBlendEffectFactory.CreateBrush();
colorBlendEffectBrush.SetSourceParameter(backgroundHandle1, luminosityBlendEffectBrush1);
colorBlendEffectBrush.SetSourceParameter(foregroundHandle1, tintOpacityEffectBrush);
// colorBlendEffectBrush.SetSourceParameter(backgroundHandle, micaBackdropBrush);
using var micaBackdropBrush1 = colorBlendEffectBrush.QueryInterface<ICompositionBrush>();
return micaBackdropBrush1.CloneReference();
} }
public static ICompositionBrush CreateAcrylicBlurBackdropBrush(ICompositor compositor) public static ICompositionBrush CreateAcrylicBlurBackdropBrush(ICompositor compositor)
@ -97,4 +154,15 @@ internal static class WinUiCompositionUtils
brush?.Dispose(); brush?.Dispose();
} }
} }
private static IGraphicsEffectSource GetParameterSource(string name,
ICompositionEffectSourceParameterFactory backDropParameterFactory, out IntPtr handle)
{
var backdropString = new HStringInterop(name);
var backDropParameter =
backDropParameterFactory.Create(backdropString.Handle);
var backDropParameterAsSource = backDropParameter.QueryInterface<IGraphicsEffectSource>();
handle = backdropString.Handle;
return backDropParameterAsSource;
}
} }

3
src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs

@ -4,7 +4,8 @@
{ {
None, None,
Acrylic, Acrylic,
Mica MicaLight,
MicaDark
} }
internal interface IBlurHost internal interface IBlurHost

23
src/Windows/Avalonia.Win32/WinRT/WinRTPropertyValue.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Avalonia.Win32.WinRT namespace Avalonia.Win32.WinRT
@ -16,7 +17,15 @@ namespace Avalonia.Win32.WinRT
UInt32 = u; UInt32 = u;
Type = PropertyType.UInt32; Type = PropertyType.UInt32;
} }
public WinRTPropertyValue(float[] uiColor)
{
Type = PropertyType.SingleArray;
_singleArray = uiColor;
}
private readonly float[]? _singleArray;
public PropertyType Type { get; } public PropertyType Type { get; }
public int IsNumericScalar { get; } public int IsNumericScalar { get; }
public byte UInt8 { get; } public byte UInt8 { get; }
@ -62,7 +71,17 @@ namespace Avalonia.Win32.WinRT
public unsafe ulong* GetUInt64Array(uint* __valueSize) => throw NotImplemented; public unsafe ulong* GetUInt64Array(uint* __valueSize) => throw NotImplemented;
public unsafe float* GetSingleArray(uint* __valueSize) => throw NotImplemented; public unsafe float* GetSingleArray(uint* __valueSize)
{
if (_singleArray == null)
throw NotImplemented;
*__valueSize = (uint)_singleArray.Length;
var allocCoTaskMem = Marshal.AllocCoTaskMem(_singleArray.Length * Unsafe.SizeOf<float>());
Marshal.Copy(_singleArray, 0, allocCoTaskMem, _singleArray.Length);
float* s = (float*)allocCoTaskMem;
return s;
}
public unsafe double* GetDoubleArray(uint* __valueSize) => throw NotImplemented; public unsafe double* GetDoubleArray(uint* __valueSize) => throw NotImplemented;

13
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -106,6 +106,7 @@ namespace Avalonia.Win32
private static POINTER_PEN_INFO[]? s_historyPenInfos; private static POINTER_PEN_INFO[]? s_historyPenInfos;
private static POINTER_INFO[]? s_historyInfos; private static POINTER_INFO[]? s_historyInfos;
private static MOUSEMOVEPOINT[]? s_mouseHistoryInfos; private static MOUSEMOVEPOINT[]? s_mouseHistoryInfos;
private PlatformThemeVariant _currentThemeVariant;
public WindowImpl() public WindowImpl()
{ {
@ -474,7 +475,12 @@ namespace Avalonia.Win32
return; return;
SetUseHostBackdropBrush(false); SetUseHostBackdropBrush(false);
_blurHost?.SetBlur(BlurEffect.Mica); _blurHost?.SetBlur(_currentThemeVariant switch
{
PlatformThemeVariant.Light => BlurEffect.MicaLight,
PlatformThemeVariant.Dark => BlurEffect.MicaDark,
_ => throw new ArgumentOutOfRangeException()
});
} }
private void SetAccentState(AccentState state) private void SetAccentState(AccentState state)
@ -778,6 +784,7 @@ namespace Avalonia.Win32
public unsafe void SetFrameThemeVariant(PlatformThemeVariant themeVariant) public unsafe void SetFrameThemeVariant(PlatformThemeVariant themeVariant)
{ {
_currentThemeVariant = themeVariant;
if (Win32Platform.WindowsVersion.Build >= 22000) if (Win32Platform.WindowsVersion.Build >= 22000)
{ {
var pvUseBackdropBrush = themeVariant == PlatformThemeVariant.Dark ? 1 : 0; var pvUseBackdropBrush = themeVariant == PlatformThemeVariant.Dark ? 1 : 0;
@ -786,6 +793,10 @@ namespace Avalonia.Win32
(int)DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, (int)DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE,
&pvUseBackdropBrush, &pvUseBackdropBrush,
sizeof(int)); sizeof(int));
if (TransparencyLevel == WindowTransparencyLevel.Mica)
{
SetTransparencyMica(Win32Platform.WindowsVersion);
}
} }
} }

Loading…
Cancel
Save