From 92880f6d037de3a5e62f770a32bda4a33edc92bc Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 25 Jun 2020 17:32:02 -0300 Subject: [PATCH 001/115] force dx11 --- samples/ControlCatalog.NetCore/Program.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index 5df8c1be64..06cf3e6b61 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using Avalonia; using Avalonia.Dialogs; +using Avalonia.OpenGL; using Avalonia.ReactiveUI; namespace ControlCatalog.NetCore @@ -65,6 +66,10 @@ namespace ControlCatalog.NetCore EnableMultitouch = true, AllowEglInitialization = true }) + .With(new AngleOptions + { + AllowedPlatformApis = new System.Collections.Generic.List { AngleOptions.PlatformApi.DirectX11} + }) .UseSkia() .UseReactiveUI() .UseManagedSystemDialogs() From 459e9db2fb04a05abbf830363db5fed73eed64c3 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 25 Jun 2020 17:35:43 -0300 Subject: [PATCH 002/115] add Composition interfaces. --- .../Avalonia.Win32/Avalonia.Win32.csproj | 1 + .../Composition/CompositionHost.cs | 145 ++++++++++++ .../Avalonia.Win32/Composition/D2DEffects.cs | 91 ++++++++ .../GRAPHICS_EFFECT_PROPERTY_MAPPING.cs | 18 ++ .../Composition/GaussianBlurEffect.cs | 79 +++++++ .../Composition/ICompositorDesktopInterop.cs | 14 ++ .../Composition/ICompositorDesktopInterop1.cs | 69 ++++++ .../Composition/ICompositorInterop.cs | 139 +++++++++++ .../Composition/IGraphicsEffectD2D1Interop.cs | 24 ++ .../IGraphicsEffectD2D1Interop1.cs | 217 ++++++++++++++++++ src/Windows/Avalonia.Win32/WindowImpl.cs | 2 + 11 files changed, 799 insertions(+) create mode 100644 src/Windows/Avalonia.Win32/Composition/CompositionHost.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/D2DEffects.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/GRAPHICS_EFFECT_PROPERTY_MAPPING.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/ICompositorDesktopInterop.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/ICompositorDesktopInterop1.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/ICompositorInterop.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs diff --git a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj index 49700710e9..34f71daf52 100644 --- a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj +++ b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs new file mode 100644 index 0000000000..223c208829 --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -0,0 +1,145 @@ +using System; +using System.Runtime.InteropServices; +using Avalonia.OpenGL.Angle; +using Windows.UI.Composition; +using WinRT; + +namespace Avalonia.Win32 +{ + class CompositionHost + { + internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE + { + DQTAT_COM_NONE = 0, + DQTAT_COM_ASTA = 1, + DQTAT_COM_STA = 2 + }; + + internal enum DISPATCHERQUEUE_THREAD_TYPE + { + DQTYPE_THREAD_DEDICATED = 1, + DQTYPE_THREAD_CURRENT = 2, + }; + + [StructLayout(LayoutKind.Sequential)] + internal struct DispatcherQueueOptions + { + public int dwSize; + + [MarshalAs(UnmanagedType.I4)] + public DISPATCHERQUEUE_THREAD_TYPE threadType; + + [MarshalAs(UnmanagedType.I4)] + public DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType; + }; + + [DllImport("coremessaging.dll", EntryPoint = "CreateDispatcherQueueController", CharSet = CharSet.Unicode)] + internal static extern IntPtr CreateDispatcherQueueController(DispatcherQueueOptions options, out IntPtr dispatcherQueueController); + + public static CompositionHost Instance { get; } = new CompositionHost(); + + private Compositor _compositor; + private Windows.System.DispatcherQueueController _dispatcherQueueController; + private Windows.UI.Composition.Desktop.DesktopWindowTarget _target; + + private CompositionHost() + { + } + + public void AddElement(float size, float x, float y) + { + if (_target.Root != null) + { + var visuals = _target.Root.As().Children; + + var visual = _compositor.CreateSpriteVisual(); + + var element = _compositor.CreateSpriteVisual(); + var rand = new Random(); + + element.Brush = _compositor.CreateColorBrush(new Windows.UI.Color { A = 255, R = (byte)(rand.NextDouble() * 255), G = (byte)(rand.NextDouble() * 255), B = (byte)(rand.NextDouble() * 255) }); + element.Size = new System.Numerics.Vector2(size, size); + element.Offset = new System.Numerics.Vector3(x, y, 0.0f); + + var animation = _compositor.CreateVector3KeyFrameAnimation(); + var bottom = (float)600 - element.Size.Y; + animation.InsertKeyFrame(1, new System.Numerics.Vector3(element.Offset.X, bottom, 0)); + + animation.Duration = TimeSpan.FromSeconds(2); + animation.DelayTime = TimeSpan.FromSeconds(3); + element.StartAnimation("Offset", animation); + visuals.InsertAtTop(element); + + visuals.InsertAtTop(visual); + } + } + + public void Initialize(IntPtr hwnd) + { + EnsureDispatcherQueue(); + if (_dispatcherQueueController != null) + _compositor = new Windows.UI.Composition.Compositor(); + + CreateDesktopWindowTarget(hwnd); + CreateCompositionRoot(); + + var interop = _compositor.As(); + + var display = Win32GlManager.EglFeature.Display as AngleWin32EglDisplay; + + var gDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); + + gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100,100), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); + + } + + public void CreateBlur() + { + var effect = new GaussianBlurEffect(); + var effectFactory = _compositor.CreateEffectFactory(effect); + var blurBrush = effectFactory.CreateBrush(); + + var backDropBrush = _compositor.CreateBackdropBrush(); + + blurBrush.SetSourceParameter("backdrop", backDropBrush); + + var visual = _compositor.CreateSpriteVisual(); + + visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); + visual.Brush = blurBrush; + + _target.Root = visual; + } + + void CreateCompositionRoot() + { + var root = _compositor.CreateContainerVisual(); + root.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); + //root.Offset = new System.Numerics.Vector3(0, 0, 0); + _target.Root = root; + } + + void CreateDesktopWindowTarget(IntPtr window) + { + var interop = _compositor.As(); + + interop.CreateDesktopWindowTarget(window, false, out var windowTarget); + _target = Windows.UI.Composition.Desktop.DesktopWindowTarget.FromAbi(windowTarget); + } + + void EnsureDispatcherQueue() + { + if (_dispatcherQueueController == null) + { + DispatcherQueueOptions options = new DispatcherQueueOptions(); + options.apartmentType = DISPATCHERQUEUE_THREAD_APARTMENTTYPE.DQTAT_COM_STA; + options.threadType = DISPATCHERQUEUE_THREAD_TYPE.DQTYPE_THREAD_CURRENT; + options.dwSize = Marshal.SizeOf(typeof(DispatcherQueueOptions)); + + CreateDispatcherQueueController(options, out var queue); + _dispatcherQueueController = Windows.System.DispatcherQueueController.FromAbi(queue); + } + } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/D2DEffects.cs b/src/Windows/Avalonia.Win32/Composition/D2DEffects.cs new file mode 100644 index 0000000000..1c761ee082 --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/D2DEffects.cs @@ -0,0 +1,91 @@ +using System; + + +namespace Avalonia.Win32 +{ + class D2DEffects + { + public static readonly Guid CLSID_D2D12DAffineTransform = new Guid(0x6AA97485, 0x6354, 0x4CFC, 0x90, 0x8C, 0xE4, 0xA7, 0x4F, 0x62, 0xC9, 0x6C); + + public static readonly Guid CLSID_D2D13DPerspectiveTransform = new Guid(0xC2844D0B, 0x3D86, 0x46E7, 0x85, 0xBA, 0x52, 0x6C, 0x92, 0x40, 0xF3, 0xFB); + + public static readonly Guid CLSID_D2D13DTransform = new Guid(0xE8467B04, 0xEC61, 0x4B8A, 0xB5, 0xDE, 0xD4, 0xD7, 0x3D, 0xEB, 0xEA, 0x5A); + + public static readonly Guid CLSID_D2D1ArithmeticComposite = new Guid(0xFC151437, 0x049A, 0x4784, 0xA2, 0x4A, 0xF1, 0xC4, 0xDA, 0xF2, 0x09, 0x87); + + public static readonly Guid CLSID_D2D1Atlas = new Guid(0x913E2BE4, 0xFDCF, 0x4FE2, 0xA5, 0xF0, 0x24, 0x54, 0xF1, 0x4F, 0xF4, 0x08); + + public static readonly Guid CLSID_D2D1BitmapSource = new Guid(0x5FB6C24D, 0xC6DD, 0x4231, 0x94, 0x4, 0x50, 0xF4, 0xD5, 0xC3, 0x25, 0x2D); + + public static readonly Guid CLSID_D2D1Blend = new Guid(0x81C5B77B, 0x13F8, 0x4CDD, 0xAD, 0x20, 0xC8, 0x90, 0x54, 0x7A, 0xC6, 0x5D); + + public static readonly Guid CLSID_D2D1Border = new Guid(0x2A2D49C0, 0x4ACF, 0x43C7, 0x8C, 0x6A, 0x7C, 0x4A, 0x27, 0x87, 0x4D, 0x27); + + public static readonly Guid CLSID_D2D1Brightness = new Guid(0x8CEA8D1E, 0x77B0, 0x4986, 0xB3, 0xB9, 0x2F, 0x0C, 0x0E, 0xAE, 0x78, 0x87); + + public static readonly Guid CLSID_D2D1ColorManagement = new Guid(0x1A28524C, 0xFDD6, 0x4AA4, 0xAE, 0x8F, 0x83, 0x7E, 0xB8, 0x26, 0x7B, 0x37); + + public static readonly Guid CLSID_D2D1ColorMatrix = new Guid(0x921F03D6, 0x641C, 0x47DF, 0x85, 0x2D, 0xB4, 0xBB, 0x61, 0x53, 0xAE, 0x11); + + public static readonly Guid CLSID_D2D1Composite = new Guid(0x48FC9F51, 0xF6AC, 0x48F1, 0x8B, 0x58, 0x3B, 0x28, 0xAC, 0x46, 0xF7, 0x6D); + + public static readonly Guid CLSID_D2D1ConvolveMatrix = new Guid(0x407F8C08, 0x5533, 0x4331, 0xA3, 0x41, 0x23, 0xCC, 0x38, 0x77, 0x84, 0x3E); + + public static readonly Guid CLSID_D2D1Crop = new Guid(0xE23F7110, 0x0E9A, 0x4324, 0xAF, 0x47, 0x6A, 0x2C, 0x0C, 0x46, 0xF3, 0x5B); + + public static readonly Guid CLSID_D2D1DirectionalBlur = new Guid(0x174319A6, 0x58E9, 0x49B2, 0xBB, 0x63, 0xCA, 0xF2, 0xC8, 0x11, 0xA3, 0xDB); + + public static readonly Guid CLSID_D2D1DiscreteTransfer = new Guid(0x90866FCD, 0x488E, 0x454B, 0xAF, 0x06, 0xE5, 0x04, 0x1B, 0x66, 0xC3, 0x6C); + + public static readonly Guid CLSID_D2D1DisplacementMap = new Guid(0xEDC48364, 0x417, 0x4111, 0x94, 0x50, 0x43, 0x84, 0x5F, 0xA9, 0xF8, 0x90); + + public static readonly Guid CLSID_D2D1DistantDiffuse = new Guid(0x3E7EFD62, 0xA32D, 0x46D4, 0xA8, 0x3C, 0x52, 0x78, 0x88, 0x9A, 0xC9, 0x54); + + public static readonly Guid CLSID_D2D1DistantSpecular = new Guid(0x428C1EE5, 0x77B8, 0x4450, 0x8A, 0xB5, 0x72, 0x21, 0x9C, 0x21, 0xAB, 0xDA); + + public static readonly Guid CLSID_D2D1DpiCompensation = new Guid(0x6C26C5C7, 0x34E0, 0x46FC, 0x9C, 0xFD, 0xE5, 0x82, 0x37, 0x6, 0xE2, 0x28); + + public static readonly Guid CLSID_D2D1Flood = new Guid(0x61C23C20, 0xAE69, 0x4D8E, 0x94, 0xCF, 0x50, 0x07, 0x8D, 0xF6, 0x38, 0xF2); + + public static readonly Guid CLSID_D2D1GammaTransfer = new Guid(0x409444C4, 0xC419, 0x41A0, 0xB0, 0xC1, 0x8C, 0xD0, 0xC0, 0xA1, 0x8E, 0x42); + + public static readonly Guid CLSID_D2D1GaussianBlur = new Guid(0x1FEB6D69, 0x2FE6, 0x4AC9, 0x8C, 0x58, 0x1D, 0x7F, 0x93, 0xE7, 0xA6, 0xA5); + + public static readonly Guid CLSID_D2D1Scale = new Guid(0x9DAF9369, 0x3846, 0x4D0E, 0xA4, 0x4E, 0xC, 0x60, 0x79, 0x34, 0xA5, 0xD7); + + public static readonly Guid CLSID_D2D1Histogram = new Guid(0x881DB7D0, 0xF7EE, 0x4D4D, 0xA6, 0xD2, 0x46, 0x97, 0xAC, 0xC6, 0x6E, 0xE8); + + public static readonly Guid CLSID_D2D1HueRotation = new Guid(0x0F4458EC, 0x4B32, 0x491B, 0x9E, 0x85, 0xBD, 0x73, 0xF4, 0x4D, 0x3E, 0xB6); + + public static readonly Guid CLSID_D2D1LinearTransfer = new Guid(0xAD47C8FD, 0x63EF, 0x4ACC, 0x9B, 0x51, 0x67, 0x97, 0x9C, 0x03, 0x6C, 0x06); + + public static readonly Guid CLSID_D2D1LuminanceToAlpha = new Guid(0x41251AB7, 0x0BEB, 0x46F8, 0x9D, 0xA7, 0x59, 0xE9, 0x3F, 0xCC, 0xE5, 0xDE); + + public static readonly Guid CLSID_D2D1Morphology = new Guid(0xEAE6C40D, 0x626A, 0x4C2D, 0xBF, 0xCB, 0x39, 0x10, 0x01, 0xAB, 0xE2, 0x02); + + public static readonly Guid CLSID_D2D1OpacityMetadata = new Guid(0x6C53006A, 0x4450, 0x4199, 0xAA, 0x5B, 0xAD, 0x16, 0x56, 0xFE, 0xCE, 0x5E); + + public static readonly Guid CLSID_D2D1PointDiffuse = new Guid(0xB9E303C3, 0xC08C, 0x4F91, 0x8B, 0x7B, 0x38, 0x65, 0x6B, 0xC4, 0x8C, 0x20); + + public static readonly Guid CLSID_D2D1PointSpecular = new Guid(0x09C3CA26, 0x3AE2, 0x4F09, 0x9E, 0xBC, 0xED, 0x38, 0x65, 0xD5, 0x3F, 0x22); + + public static readonly Guid CLSID_D2D1Premultiply = new Guid(0x06EAB419, 0xDEED, 0x4018, 0x80, 0xD2, 0x3E, 0x1D, 0x47, 0x1A, 0xDE, 0xB2); + + public static readonly Guid CLSID_D2D1Saturation = new Guid(0x5CB2D9CF, 0x327D, 0x459F, 0xA0, 0xCE, 0x40, 0xC0, 0xB2, 0x08, 0x6B, 0xF7); + + public static readonly Guid CLSID_D2D1Shadow = new Guid(0xC67EA361, 0x1863, 0x4E69, 0x89, 0xDB, 0x69, 0x5D, 0x3E, 0x9A, 0x5B, 0x6B); + + public static readonly Guid CLSID_D2D1SpotDiffuse = new Guid(0x818A1105, 0x7932, 0x44F4, 0xAA, 0x86, 0x08, 0xAE, 0x7B, 0x2F, 0x2C, 0x93); + + public static readonly Guid CLSID_D2D1SpotSpecular = new Guid(0xEDAE421E, 0x7654, 0x4A37, 0x9D, 0xB8, 0x71, 0xAC, 0xC1, 0xBE, 0xB3, 0xC1); + + public static readonly Guid CLSID_D2D1TableTransfer = new Guid(0x5BF818C3, 0x5E43, 0x48CB, 0xB6, 0x31, 0x86, 0x83, 0x96, 0xD6, 0xA1, 0xD4); + + public static readonly Guid CLSID_D2D1Tile = new Guid(0xB0784138, 0x3B76, 0x4BC5, 0xB1, 0x3B, 0x0F, 0xA2, 0xAD, 0x02, 0x65, 0x9F); + + public static readonly Guid CLSID_D2D1Turbulence = new Guid(0xCF2BB6AE, 0x889A, 0x4AD7, 0xBA, 0x29, 0xA2, 0xFD, 0x73, 0x2C, 0x9F, 0xC9); + + public static readonly Guid CLSID_D2D1UnPremultiply = new Guid(0xFB9AC489, 0xAD8D, 0x41ED, 0x99, 0x99, 0xBB, 0x63, 0x47, 0xD1, 0x10, 0xF7); + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/GRAPHICS_EFFECT_PROPERTY_MAPPING.cs b/src/Windows/Avalonia.Win32/Composition/GRAPHICS_EFFECT_PROPERTY_MAPPING.cs new file mode 100644 index 0000000000..f5d5fc4ad3 --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/GRAPHICS_EFFECT_PROPERTY_MAPPING.cs @@ -0,0 +1,18 @@ +namespace Windows.Graphics.Effects.Interop +{ + public enum GRAPHICS_EFFECT_PROPERTY_MAPPING + { + GRAPHICS_EFFECT_PROPERTY_MAPPING_UNKNOWN, + GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT, + GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORX, + GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORY, + GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORZ, + GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORW, + GRAPHICS_EFFECT_PROPERTY_MAPPING_RECT_TO_VECTOR4, + GRAPHICS_EFFECT_PROPERTY_MAPPING_RADIANS_TO_DEGREES, + GRAPHICS_EFFECT_PROPERTY_MAPPING_COLORMATRIX_ALPHA_MODE, + GRAPHICS_EFFECT_PROPERTY_MAPPING_COLOR_TO_VECTOR3, + GRAPHICS_EFFECT_PROPERTY_MAPPING_COLOR_TO_VECTOR4 + }; +} + diff --git a/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs b/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs new file mode 100644 index 0000000000..19595e8977 --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs @@ -0,0 +1,79 @@ +using System; +using Windows.Graphics.Effects; +using Windows.Graphics.Effects.Interop; +using Windows.UI.Composition; + + +namespace Avalonia.Win32 +{ + class GaussianBlurEffect : IGraphicsEffect, IGraphicsEffectSource, global::Windows.Graphics.Effects.Interop.IGraphicsEffectD2D1Interop + { + enum D2D1_GAUSSIANBLUR_OPTIMIZATION + { + D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED, + D2D1_GAUSSIANBLUR_OPTIMIZATION_BALANCED, + D2D1_GAUSSIANBLUR_OPTIMIZATION_QUALITY, + D2D1_GAUSSIANBLUR_OPTIMIZATION_FORCE_DWORD + }; + + enum D2D1_BORDER_MODE + { + D2D1_BORDER_MODE_SOFT, + D2D1_BORDER_MODE_HARD, + D2D1_BORDER_MODE_FORCE_DWORD + }; + + enum D2D1GaussianBlurProp + { + D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, + D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION, + D2D1_GAUSSIANBLUR_PROP_BORDER_MODE, + D2D1_GAUSSIANBLUR_PROP_FORCE_DWORD + }; + + public string Name { get; set; } + + public Guid EffectId => D2DEffects.CLSID_D2D1GaussianBlur; + + public uint PropertyCount => 3; + + public uint SourceCount => 1; + + public uint GetNamedPropertyMapping(string name, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + throw new NotImplementedException(); + } + + public object GetProperty(uint index) + { + switch ((D2D1GaussianBlurProp)index) + { + case D2D1GaussianBlurProp.D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION: + return 30.0f; + + case D2D1GaussianBlurProp.D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION: + return (UInt32)D2D1_GAUSSIANBLUR_OPTIMIZATION.D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED; + + case D2D1GaussianBlurProp.D2D1_GAUSSIANBLUR_PROP_BORDER_MODE: + return (UInt32)D2D1_BORDER_MODE.D2D1_BORDER_MODE_HARD; + } + + return null; + } + + private IGraphicsEffectSource _source = new CompositionEffectSourceParameter("backdrop"); + + public IGraphicsEffectSource GetSource(uint index) + { + if (index == 0) + { + return _source; + } + else + { + return null; + } + } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/ICompositorDesktopInterop.cs b/src/Windows/Avalonia.Win32/Composition/ICompositorDesktopInterop.cs new file mode 100644 index 0000000000..1d4cd3450f --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/ICompositorDesktopInterop.cs @@ -0,0 +1,14 @@ +using System; +using System.Runtime.InteropServices; +using WinRT; + +namespace Windows.UI.Composition.Desktop +{ + [WindowsRuntimeType] + [Guid("29E691FA-4567-4DCA-B319-D0F207EB6807")] + public interface ICompositorDesktopInterop + { + void CreateDesktopWindowTarget(IntPtr hwndTarget, bool isTopmost, out IntPtr test); + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/ICompositorDesktopInterop1.cs b/src/Windows/Avalonia.Win32/Composition/ICompositorDesktopInterop1.cs new file mode 100644 index 0000000000..1c3f06d679 --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/ICompositorDesktopInterop1.cs @@ -0,0 +1,69 @@ +using WinRT; + +namespace ABI.Windows.UI.Composition.Desktop +{ + using global::System; + using global::System.Runtime.InteropServices; + + [Guid("29E691FA-4567-4DCA-B319-D0F207EB6807")] + internal class ICompositorDesktopInterop : global::Windows.UI.Composition.Desktop.ICompositorDesktopInterop + + { + [Guid("29E691FA-4567-4DCA-B319-D0F207EB6807")] + public struct Vftbl + { + public delegate int _CreateDesktopWindowTarget(IntPtr thisPtr, IntPtr hwndTarget, byte isTopMost, out IntPtr desktopWindowTarget); + + internal global::WinRT.Interop.IUnknownVftbl IUnknownVftbl; + public _CreateDesktopWindowTarget CreateDesktopWindowTarget; + + + public static readonly Vftbl AbiToProjectionVftable; + public static readonly IntPtr AbiToProjectionVftablePtr; + + static Vftbl() + { + AbiToProjectionVftable = new Vftbl + { + IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl, + CreateDesktopWindowTarget = Do_Abi_Create_Desktop_Window_Target + }; + AbiToProjectionVftablePtr = Marshal.AllocHGlobal(Marshal.SizeOf()); + Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false); + } + + private static int Do_Abi_Create_Desktop_Window_Target(IntPtr thisPtr, IntPtr hwndTarget, byte isTopMost, out IntPtr desktopWindowTarget) + { + try + { + ComWrappersSupport.FindObject(thisPtr).CreateDesktopWindowTarget(hwndTarget, isTopMost != 0, out desktopWindowTarget); + return 0; + } + catch (Exception ex) + { + desktopWindowTarget = IntPtr.Zero; + return Marshal.GetHRForException(ex); + } + } + } + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator ICompositorDesktopInterop(IObjectReference obj) => (obj != null) ? new ICompositorDesktopInterop(obj) : null; + protected readonly ObjectReference _obj; + public IObjectReference ObjRef { get => _obj; } + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public ICompositorDesktopInterop(IObjectReference obj) : this(obj.As()) { } + internal ICompositorDesktopInterop(ObjectReference obj) + { + _obj = obj; + } + + public void CreateDesktopWindowTarget(IntPtr hwndTarget, bool isTopmost, out IntPtr test) + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.CreateDesktopWindowTarget(ThisPtr, hwndTarget, isTopmost ? (byte)1 : (byte)0, out test)); + } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/ICompositorInterop.cs b/src/Windows/Avalonia.Win32/Composition/ICompositorInterop.cs new file mode 100644 index 0000000000..d9b25e497e --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/ICompositorInterop.cs @@ -0,0 +1,139 @@ +using System; +using System.Runtime.InteropServices; +using WinRT; + +namespace Windows.UI.Composition.Interop +{ + [WindowsRuntimeType] + [Guid("25297D5C-3AD4-4C9C-B5CF-E36A38512330")] + public interface ICompositorInterop + { + ICompositionSurface CreateCompositionSurfaceForHandle(IntPtr swapChain); + + ICompositionSurface CreateCompositionSurfaceForSwapChain(IntPtr swapChain); + + CompositionGraphicsDevice CreateGraphicsDevice(IntPtr renderingDevice); + } +} + +namespace ABI.Windows.UI.Composition.Interop +{ + using global::System; + using global::System.Runtime.InteropServices; + using global::Windows.UI.Composition; + + [Guid("25297D5C-3AD4-4C9C-B5CF-E36A38512330")] + internal class ICompositorInterop : global::Windows.UI.Composition.Interop.ICompositorInterop + + { + [Guid("25297D5C-3AD4-4C9C-B5CF-E36A38512330")] + public struct Vftbl + { + public delegate int _CreateCompositionSurfaceForHandle(IntPtr ThisPtr, IntPtr swapChain, out IntPtr result); + public delegate int _CreateCompositionSurfaceForSwapChain(IntPtr ThisPtr, IntPtr swapChain, out IntPtr result); + public delegate int _CreateGraphicsDevice(IntPtr ThisPtr, IntPtr renderingDevice, out IntPtr result); + + internal global::WinRT.Interop.IUnknownVftbl IUnknownVftbl; + public _CreateCompositionSurfaceForHandle CreateCompositionSurfaceForHandle; + public _CreateCompositionSurfaceForSwapChain CreateCompositionSurfaceForSwapChain; + public _CreateGraphicsDevice CreateGraphicsDevice; + + + public static readonly Vftbl AbiToProjectionVftable; + public static readonly IntPtr AbiToProjectionVftablePtr; + + static Vftbl() + { + AbiToProjectionVftable = new Vftbl + { + IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl, + + CreateCompositionSurfaceForHandle = Do_Abi_Create_Composition_Surface_For_Handle, + CreateCompositionSurfaceForSwapChain = Do_Abi_Create_Composition_Surface_For_SwapChain, + CreateGraphicsDevice= Do_Abi_Create_Graphics_Device + }; + AbiToProjectionVftablePtr = Marshal.AllocHGlobal(Marshal.SizeOf()); + Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false); + } + + private static int Do_Abi_Create_Composition_Surface_For_Handle(IntPtr thisPtr, IntPtr swapChain, out IntPtr surface) + { + try + { + surface = IntPtr.Zero; + //surface = ComWrappersSupport.FindObject(thisPtr).CreateCompositionSurfaceForHandle(swapChain); + return 0; + } + catch (Exception ex) + { + surface = IntPtr.Zero; + return Marshal.GetHRForException(ex); + } + } + + private static int Do_Abi_Create_Composition_Surface_For_SwapChain(IntPtr thisPtr, IntPtr swapChain, out IntPtr surface) + { + try + { + surface = IntPtr.Zero; + //surface = ComWrappersSupport.FindObject(thisPtr).CreateCompositionSurfaceForSwapChain(swapChain); + return 0; + } + catch (Exception ex) + { + surface = IntPtr.Zero; + return Marshal.GetHRForException(ex); + } + } + + private static int Do_Abi_Create_Graphics_Device(IntPtr thisPtr, IntPtr renderingDevice, out IntPtr graphicsDevice) + { + try + { + graphicsDevice = ComWrappersSupport.FindObject(thisPtr).CreateGraphicsDevice(renderingDevice).ThisPtr; + return 0; + } + catch (Exception ex) + { + graphicsDevice = IntPtr.Zero; + return Marshal.GetHRForException(ex); + } + } + } + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator ICompositorInterop(IObjectReference obj) => (obj != null) ? new ICompositorInterop(obj) : null; + protected readonly ObjectReference _obj; + public IObjectReference ObjRef { get => _obj; } + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public ICompositorInterop(IObjectReference obj) : this(obj.As()) { } + internal ICompositorInterop(ObjectReference obj) + { + _obj = obj; + } + + public ICompositionSurface CreateCompositionSurfaceForHandle(IntPtr swapChain) + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.CreateCompositionSurfaceForHandle(ThisPtr, swapChain, out var compositionSurface)); + + return null; + } + + public ICompositionSurface CreateCompositionSurfaceForSwapChain(IntPtr swapChain) + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.CreateCompositionSurfaceForSwapChain(ThisPtr, swapChain, out var compositionSurface)); + + return null; + } + + public CompositionGraphicsDevice CreateGraphicsDevice(IntPtr renderingDevice) + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.CreateGraphicsDevice(ThisPtr, renderingDevice, out var graphicsDevice)); + + return CompositionGraphicsDevice.FromAbi(graphicsDevice); + } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop.cs b/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop.cs new file mode 100644 index 0000000000..74d3939a98 --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.InteropServices; +using WinRT; + +namespace Windows.Graphics.Effects.Interop +{ + [WindowsRuntimeType] + [Guid("2FC57384-A068-44D7-A331-30982FCF7177")] + public interface IGraphicsEffectD2D1Interop + { + Guid EffectId { get; } + + uint GetNamedPropertyMapping(string name, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping); + + object GetProperty(uint index); + + uint PropertyCount { get; } + + IGraphicsEffectSource GetSource(uint index); + + uint SourceCount { get; } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs b/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs new file mode 100644 index 0000000000..9d053c9e22 --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs @@ -0,0 +1,217 @@ +using WinRT; + +namespace ABI.Windows.Graphics.Effects.Interop +{ + using global::System; + using global::System.Runtime.InteropServices; + + [Guid("2FC57384-A068-44D7-A331-30982FCF7177")] + internal class IGraphicsEffectD2D1Interop : global::Windows.Graphics.Effects.Interop.IGraphicsEffectD2D1Interop + + { + [Guid("2FC57384-A068-44D7-A331-30982FCF7177")] + public struct Vftbl + { + public delegate int _GetEffectId(IntPtr thisPtr, out Guid guid); + public delegate int _GetNamedPropertyMapping(IntPtr thisPtr, IntPtr name, IntPtr index, IntPtr mapping); + public delegate int _GetProperty(IntPtr thisPtr, uint index, out IntPtr value); + public unsafe delegate int _GetPropertyCount(IntPtr thisPtr, uint* count); + public delegate int _GetSource(IntPtr thisPtr, uint index, out IntPtr source); + public delegate int _GetSourceCount(IntPtr thisPtr, out uint count); + + internal global::WinRT.Interop.IUnknownVftbl IUnknownVftbl; + public _GetEffectId GetEffectId; + public _GetNamedPropertyMapping GetNamedPropertyMapping; + public _GetPropertyCount GetPropertyCount; + public _GetProperty GetProperty; + public _GetSource GetSource; + public _GetSourceCount GetSourceCount; + + public static readonly Vftbl AbiToProjectionVftable; + public static readonly IntPtr AbiToProjectionVftablePtr; + + unsafe static Vftbl() + { + AbiToProjectionVftable = new Vftbl + { + IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl, + GetEffectId = Do_Abi_Get_Effect_Id, + GetNamedPropertyMapping = Do_Abi_Get_Property_Mapping, + GetPropertyCount = Do_Abi_Get_Property_Count, + GetProperty = Do_Abi_Get_Property, + GetSource = Do_Abi_Get_Source, + GetSourceCount = Do_Abi_Get_Source_Count + + }; + AbiToProjectionVftablePtr = Marshal.AllocHGlobal(Marshal.SizeOf()); + Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false); + } + + private static int Do_Abi_Get_Effect_Id(IntPtr thisPtr, out Guid guid) + { + guid = default; + + try + { + guid = ComWrappersSupport.FindObject(thisPtr).EffectId; + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex); + } + + return 0; + } + + private static int Do_Abi_Get_Property_Mapping(IntPtr thisPtr, IntPtr name, IntPtr index, IntPtr mapping) + { + try + { + ComWrappersSupport.FindObject(thisPtr).GetNamedPropertyMapping(MarshalString.FromAbi(name), out var mappingResult); + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex); + } + + return 0; + } + + private static int Do_Abi_Get_Property(IntPtr thisPtr, uint index, out IntPtr value) + { + value = default; + + try + { + value = MarshalInspectable.CreateMarshaler( + ComWrappersSupport.FindObject(thisPtr).GetProperty(index)) + .As(Guid.Parse("4BD682DD-7554-40E9-9A9B-82654EDE7E62")) + .GetRef(); + + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex); + } + + return 0; + } + + unsafe private static int Do_Abi_Get_Property_Count(IntPtr thisPtr, uint* count) + { + + try + { + var res = ComWrappersSupport.FindObject(thisPtr).PropertyCount; + + if (count != null) + { + *count = res; + } + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex); + } + + return 0; + } + + private static int Do_Abi_Get_Source(IntPtr thisPtr, uint index, out IntPtr value) + { + value = default; + + try + { + var source = ComWrappersSupport.FindObject(thisPtr).GetSource(index); + + value = MarshalInterface.FromManaged(source); + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex); + } + + return 0; + } + + private static int Do_Abi_Get_Source_Count(IntPtr thisPtr, out uint count) + { + count = default; + + try + { + count = ComWrappersSupport.FindObject(thisPtr).SourceCount; + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex); + } + + return 0; + } + } + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator IGraphicsEffectD2D1Interop(IObjectReference obj) => (obj != null) ? new IGraphicsEffectD2D1Interop(obj) : null; + protected readonly ObjectReference _obj; + public IObjectReference ObjRef { get => _obj; } + public IntPtr ThisPtr => _obj.ThisPtr; + + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public IGraphicsEffectD2D1Interop(IObjectReference obj) : this(obj.As()) { } + internal IGraphicsEffectD2D1Interop(ObjectReference obj) + { + _obj = obj; + } + + public Guid EffectId + { + get + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.GetEffectId(ThisPtr, out Guid guid)); + return guid; + } + } + + public uint PropertyCount + { + get + { + unsafe + { + uint count = default; + Marshal.ThrowExceptionForHR(_obj.Vftbl.GetPropertyCount(ThisPtr, &count)); + return count; + } + } + } + + public uint SourceCount + { + get + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.GetSourceCount(ThisPtr, out uint count)); + return count; + } + } + + public uint GetNamedPropertyMapping(string name, out global::Windows.Graphics.Effects.Interop.GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + throw new NotImplementedException(); + } + + public object GetProperty(uint index) + { + // Marshal.ThrowExceptionForHR(_obj.Vftbl.GetProperty(ThisPtr, index, out IntPtr value)); + throw new NotImplementedException(); + } + + public global::Windows.Graphics.Effects.IGraphicsEffectSource GetSource(uint index) + { + throw new NotImplementedException(); + } + } +} + diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 36398eb810..ab07bdebb3 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -599,6 +599,8 @@ namespace Avalonia.Win32 _scaling = dpix / 96.0; } } + + CompositionHost.Instance.Initialize(_hwnd); } private void CreateDropTarget() From bd2b283ad7d4df2e2088916823b174e6d37d9d24 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 25 Jun 2020 18:30:43 -0300 Subject: [PATCH 003/115] add drawing surface interop.. --- .../Composition/CompositionHost.cs | 21 ++- .../ICompositionDrawingSurfaceInterop.cs | 135 ++++++++++++++++++ .../IGraphicsEffectD2D1Interop1.cs | 2 +- 3 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 223c208829..a94fd82e1a 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using Avalonia.OpenGL.Angle; using Windows.UI.Composition; +using Windows.UI.Composition.Interop; using WinRT; namespace Avalonia.Win32 @@ -89,8 +90,24 @@ namespace Avalonia.Win32 var gDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); - gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100,100), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); - + var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100,100), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); + + var surfaceInterop = surface.As(); + + surfaceInterop.BeginDraw(new Windows.Foundation.Rect(0, 0, 100, 100), Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"), out var texture, new Windows.Foundation.Point(0, 0)); + surfaceInterop.EndDraw(); + + var brush = _compositor.CreateSurfaceBrush(surface); + + var visual = _compositor.CreateSpriteVisual(); + + visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); + visual.Brush = brush; + + _target.Root = visual; + + AddElement(100, 200, 200); + } public void CreateBlur() diff --git a/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs b/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs new file mode 100644 index 0000000000..fd9387b59e --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs @@ -0,0 +1,135 @@ +using System; +using System.Runtime.InteropServices; +using Windows.Foundation; +using WinRT; + +namespace Windows.UI.Composition.Interop +{ + [WindowsRuntimeType] + [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] + public interface ICompositionDrawingSurfaceInterop + { + void BeginDraw(Rect updateRect, Guid iid, out IntPtr updateObject, Point point); + + void EndDraw(); + + void Resize(Size sizePixels); + + void ResumeDraw(); + + void Scroll(Rect scrollRect, Rect clipRect, int offsetX, int offsetY); + + void SuspendDraw(); + } +} + +namespace ABI.Windows.UI.Composition.Interop +{ + using global::System; + using global::System.Runtime.InteropServices; + using global::Windows.UI.Composition; + + [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] + internal class ICompositionDrawingSurfaceInterop : global::Windows.UI.Composition.Interop.ICompositionDrawingSurfaceInterop + + { + [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] + public struct Vftbl + { + public delegate int _BeginDraw(IntPtr ThisPtr, Guid iid, out IntPtr updateObject, Point updateOffset); + public delegate int _EndDraw(IntPtr ThisPtr); + public delegate int _Resize(IntPtr ThisPtr, Size sizePixels); + public delegate int _ResumeDraw(IntPtr ThisPtr); + public delegate int _Scroll(IntPtr ThisPtr, Rect scrollRect, Rect clipRect, int offsetX, int offsetY); + public delegate int _SuspendDraw(IntPtr ThisPtr); + + internal global::WinRT.Interop.IUnknownVftbl IUnknownVftbl; + public _BeginDraw BeginDraw; + public _EndDraw EndDraw; + public _Resize Resize; + public _ResumeDraw ResumeDraw; + public _Scroll Scroll; + public _SuspendDraw SuspendDraw; + + public static readonly Vftbl AbiToProjectionVftable; + public static readonly IntPtr AbiToProjectionVftablePtr; + + static Vftbl() + { + AbiToProjectionVftable = new Vftbl + { + IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl, + + BeginDraw = Do_Abi_BeginDraw, + EndDraw = Do_Abi_EndDraw, + Resize = Do_Abi_Resize + + + }; + AbiToProjectionVftablePtr = Marshal.AllocHGlobal(Marshal.SizeOf()); + Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false); + } + + private static int Do_Abi_BeginDraw(IntPtr ThisPtr, Guid iid, out IntPtr updateObject, Point updateOffset) + { + updateObject = IntPtr.Zero; + return 0; + } + + private static int Do_Abi_EndDraw(IntPtr ThisPtr) + { + return 0; + } + + private static int Do_Abi_Resize(IntPtr ThisPtr, Size sizePixels) + { + return 0; + } + } + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator ICompositionDrawingSurfaceInterop(IObjectReference obj) => (obj != null) ? new ICompositionDrawingSurfaceInterop(obj) : null; + protected readonly ObjectReference _obj; + public IObjectReference ObjRef { get => _obj; } + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + + public ICompositionDrawingSurfaceInterop(IObjectReference obj) : this(obj.As()) { } + internal ICompositionDrawingSurfaceInterop(ObjectReference obj) + { + _obj = obj; + } + + public void BeginDraw(Rect updateRect, Guid iid, out IntPtr updateObject, Point point) + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.BeginDraw(ThisPtr, iid, out updateObject, point)); + } + + public void EndDraw() + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.EndDraw(ThisPtr)); + } + + public void Resize(Size sizePixels) + { + throw new NotImplementedException(); + } + + public void ResumeDraw() + { + throw new NotImplementedException(); + } + + public void Scroll(Rect scrollRect, Rect clipRect, int offsetX, int offsetY) + { + throw new NotImplementedException(); + } + + public void SuspendDraw() + { + throw new NotImplementedException(); + } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs b/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs index 9d053c9e22..8466b05fb5 100644 --- a/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs +++ b/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs @@ -122,7 +122,7 @@ namespace ABI.Windows.Graphics.Effects.Interop value = default; try - { + { var source = ComWrappersSupport.FindObject(thisPtr).GetSource(index); value = MarshalInterface.FromManaged(source); From 016935a0235844b0d0b1fed42735c26f22060b72 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 11:54:23 -0300 Subject: [PATCH 004/115] attached composition gl surface to composition tree. --- .../Composition/CompositionHost.cs | 67 +++++++++++++++++-- src/Windows/Avalonia.Win32/WindowImpl.cs | 11 +-- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index a94fd82e1a..961c3b0319 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using Avalonia.OpenGL; using Avalonia.OpenGL.Angle; using Windows.UI.Composition; using Windows.UI.Composition.Interop; @@ -7,6 +8,61 @@ using WinRT; namespace Avalonia.Win32 { + public class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase + { + private readonly EglDisplay _display; + private readonly EglContext _context; + private readonly IEglWindowGlPlatformSurfaceInfo _info; + private ICompositionDrawingSurfaceInterop _surfaceInterop; + + public CompositionEglGlPlatformSurface(EglContext context, IEglWindowGlPlatformSurfaceInfo info) : base() + { + _display = context.Display; + _context = context; + _info = info; + } + + public void AttachToCompositionTree(IntPtr hwnd) + { + _surfaceInterop = CompositionHost.Instance.Initialize(hwnd); + } + + public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() + { + var glSurface = _display.CreateWindowSurface(_info.Handle); + return new CompositionRenderTarget(_display, _context, glSurface, _surfaceInterop, _info); + } + + class CompositionRenderTarget : EglPlatformSurfaceRenderTargetBase + { + private readonly EglDisplay _display; + private readonly EglContext _context; + private readonly EglSurface _glSurface; + private readonly IEglWindowGlPlatformSurfaceInfo _info; + private PixelSize _initialSize; + private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; + + public CompositionRenderTarget(EglDisplay display, EglContext context, + EglSurface glSurface, ICompositionDrawingSurfaceInterop interopSurface, IEglWindowGlPlatformSurfaceInfo info) : base(display, context) + { + _display = display; + _context = context; + _glSurface = glSurface; + _surfaceInterop = interopSurface; + _info = info; + _initialSize = info.Size; + } + + public override void Dispose() => _glSurface.Dispose(); + + public override bool IsCorrupted => _initialSize != _info.Size; + + public override IGlPlatformSurfaceRenderingSession BeginDraw() => base.BeginDraw(_glSurface, _info); + } + } + + + class CompositionHost { internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE @@ -75,7 +131,7 @@ namespace Avalonia.Win32 } } - public void Initialize(IntPtr hwnd) + public ICompositionDrawingSurfaceInterop Initialize(IntPtr hwnd) { EnsureDispatcherQueue(); if (_dispatcherQueueController != null) @@ -90,13 +146,13 @@ namespace Avalonia.Win32 var gDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); - var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100,100), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); + var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100, 100), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); var surfaceInterop = surface.As(); - surfaceInterop.BeginDraw(new Windows.Foundation.Rect(0, 0, 100, 100), Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"), out var texture, new Windows.Foundation.Point(0, 0)); - surfaceInterop.EndDraw(); - + //surfaceInterop.BeginDraw(new Windows.Foundation.Rect(0, 0, 100, 100), Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"), out var texture, new Windows.Foundation.Point(0, 0)); + //surfaceInterop.EndDraw(); + var brush = _compositor.CreateSurfaceBrush(surface); var visual = _compositor.CreateSpriteVisual(); @@ -108,6 +164,7 @@ namespace Avalonia.Win32 AddElement(100, 200, 200); + return surfaceInterop; } public void CreateBlur() diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index ab07bdebb3..03d2a328a6 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -100,7 +100,12 @@ namespace Avalonia.Win32 _framebuffer = new FramebufferManager(_hwnd); if (Win32GlManager.EglFeature != null) - _gl = new EglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); + _gl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); + + if (_gl is CompositionEglGlPlatformSurface cgl) + { + cgl.AttachToCompositionTree(_hwnd); + } Screen = new ScreenImpl(); @@ -598,9 +603,7 @@ namespace Avalonia.Win32 { _scaling = dpix / 96.0; } - } - - CompositionHost.Instance.Initialize(_hwnd); + } } private void CreateDropTarget() From 203e346a4d855dba07d64173844434fa31fdd1f1 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 12:49:48 -0300 Subject: [PATCH 005/115] make begindraw work. --- .../Composition/CompositionHost.cs | 96 +++++++++++++++---- .../ICompositionDrawingSurfaceInterop.cs | 45 ++++++--- 2 files changed, 110 insertions(+), 31 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 961c3b0319..5f20d18faf 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -28,36 +28,99 @@ namespace Avalonia.Win32 } public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() - { - var glSurface = _display.CreateWindowSurface(_info.Handle); - return new CompositionRenderTarget(_display, _context, glSurface, _surfaceInterop, _info); + { + return new CompositionRenderTarget(_display, _context, _surfaceInterop, _info); } class CompositionRenderTarget : EglPlatformSurfaceRenderTargetBase { private readonly EglDisplay _display; - private readonly EglContext _context; - private readonly EglSurface _glSurface; + private readonly EglContext _context; private readonly IEglWindowGlPlatformSurfaceInfo _info; private PixelSize _initialSize; private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; - public CompositionRenderTarget(EglDisplay display, EglContext context, - EglSurface glSurface, ICompositionDrawingSurfaceInterop interopSurface, IEglWindowGlPlatformSurfaceInfo info) : base(display, context) + public CompositionRenderTarget(EglDisplay display, EglContext context, ICompositionDrawingSurfaceInterop interopSurface, IEglWindowGlPlatformSurfaceInfo info) : base(display, context) { _display = display; - _context = context; - _glSurface = glSurface; + _context = context; _surfaceInterop = interopSurface; _info = info; _initialSize = info.Size; } - public override void Dispose() => _glSurface.Dispose(); + public override bool IsCorrupted => _initialSize != _info.Size; + + public override IGlPlatformSurfaceRenderingSession BeginDraw() + { + var l = _context.Lock(); + + var iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); + var updateRect = new RECT { right = _info.Size.Width, bottom = _info.Size.Height }; + var offset = new POINT(); + + _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); + _surfaceInterop.BeginDraw( + ref updateRect, + ref iid, + out IntPtr texture, ref offset); - public override bool IsCorrupted => _initialSize != _info.Size; + var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture); - public override IGlPlatformSurfaceRenderingSession BeginDraw() => base.BeginDraw(_glSurface, _info); + var restoreContext = _context.MakeCurrent(surface); + + return new Session(_display, _context, null, _info, l, restoreContext, () => { }, true); + } + + public override void Dispose() + { + _surfaceInterop.EndDraw(); + base.Dispose(); + } + } + + class Session : IGlPlatformSurfaceRenderingSession + { + private readonly EglContext _context; + private readonly EglSurface _glSurface; + private readonly EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo _info; + private readonly EglDisplay _display; + private readonly IDisposable _lock; + private readonly IDisposable _restoreContext; + private readonly Action _onFinish; + + + public Session(EglDisplay display, EglContext context, + EglSurface glSurface, EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info, + IDisposable @lock, IDisposable restoreContext, Action onFinish, bool isYFlipped) + { + IsYFlipped = isYFlipped; + _context = context; + _display = display; + _glSurface = glSurface; + _info = info; + _lock = @lock; + _restoreContext = restoreContext; + _onFinish = onFinish; + } + + public void Dispose() + { + _context.GlInterface.Flush(); + _display.EglInterface.WaitGL(); + _glSurface?.SwapBuffers(); + _display.EglInterface.WaitClient(); + _display.EglInterface.WaitGL(); + _display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); + _restoreContext.Dispose(); + _lock.Dispose(); + _onFinish?.Invoke(); + } + + public IGlContext Context => _context; + public PixelSize Size => _info.Size; + public double Scaling => _info.Scaling; + public bool IsYFlipped { get; } } } @@ -146,12 +209,11 @@ namespace Avalonia.Win32 var gDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); - var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100, 100), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); - - var surfaceInterop = surface.As(); + var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100, 100), + Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, + Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); - //surfaceInterop.BeginDraw(new Windows.Foundation.Rect(0, 0, 100, 100), Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"), out var texture, new Windows.Foundation.Point(0, 0)); - //surfaceInterop.EndDraw(); + var surfaceInterop = surface.As(); var brush = _compositor.CreateSurfaceBrush(surface); diff --git a/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs b/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs index fd9387b59e..8fea5f293b 100644 --- a/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs +++ b/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs @@ -1,23 +1,39 @@ using System; using System.Runtime.InteropServices; -using Windows.Foundation; using WinRT; namespace Windows.UI.Composition.Interop { + public struct POINT + { + public int X; + public int Y; + } + + public struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + + public int Width => right - left; + public int Height => bottom - top; + } + [WindowsRuntimeType] [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] public interface ICompositionDrawingSurfaceInterop { - void BeginDraw(Rect updateRect, Guid iid, out IntPtr updateObject, Point point); + void BeginDraw(ref RECT updateRect, ref Guid iid, out IntPtr updateObject, ref POINT point); void EndDraw(); - void Resize(Size sizePixels); + void Resize(POINT sizePixels); void ResumeDraw(); - void Scroll(Rect scrollRect, Rect clipRect, int offsetX, int offsetY); + void Scroll(RECT scrollRect, RECT clipRect, int offsetX, int offsetY); void SuspendDraw(); } @@ -28,6 +44,7 @@ namespace ABI.Windows.UI.Composition.Interop using global::System; using global::System.Runtime.InteropServices; using global::Windows.UI.Composition; + using global::Windows.UI.Composition.Interop; [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] internal class ICompositionDrawingSurfaceInterop : global::Windows.UI.Composition.Interop.ICompositionDrawingSurfaceInterop @@ -36,11 +53,11 @@ namespace ABI.Windows.UI.Composition.Interop [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] public struct Vftbl { - public delegate int _BeginDraw(IntPtr ThisPtr, Guid iid, out IntPtr updateObject, Point updateOffset); + public delegate int _BeginDraw(IntPtr ThisPtr, ref RECT updateRect, ref Guid iid, out IntPtr updateObject, ref POINT updateOffset); public delegate int _EndDraw(IntPtr ThisPtr); - public delegate int _Resize(IntPtr ThisPtr, Size sizePixels); + public delegate int _Resize(IntPtr ThisPtr, POINT sizePixels); public delegate int _ResumeDraw(IntPtr ThisPtr); - public delegate int _Scroll(IntPtr ThisPtr, Rect scrollRect, Rect clipRect, int offsetX, int offsetY); + public delegate int _Scroll(IntPtr ThisPtr, RECT scrollRect, RECT clipRect, int offsetX, int offsetY); public delegate int _SuspendDraw(IntPtr ThisPtr); internal global::WinRT.Interop.IUnknownVftbl IUnknownVftbl; @@ -70,7 +87,7 @@ namespace ABI.Windows.UI.Composition.Interop Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false); } - private static int Do_Abi_BeginDraw(IntPtr ThisPtr, Guid iid, out IntPtr updateObject, Point updateOffset) + private static int Do_Abi_BeginDraw(IntPtr ThisPtr, ref RECT updateRect, ref Guid iid, out IntPtr updateObject, ref POINT updateOffset) { updateObject = IntPtr.Zero; return 0; @@ -81,7 +98,7 @@ namespace ABI.Windows.UI.Composition.Interop return 0; } - private static int Do_Abi_Resize(IntPtr ThisPtr, Size sizePixels) + private static int Do_Abi_Resize(IntPtr ThisPtr, POINT sizePixels) { return 0; } @@ -101,9 +118,9 @@ namespace ABI.Windows.UI.Composition.Interop _obj = obj; } - public void BeginDraw(Rect updateRect, Guid iid, out IntPtr updateObject, Point point) + public void BeginDraw(ref RECT updateRect, ref Guid iid, out IntPtr updateObject, ref POINT point) { - Marshal.ThrowExceptionForHR(_obj.Vftbl.BeginDraw(ThisPtr, iid, out updateObject, point)); + Marshal.ThrowExceptionForHR(_obj.Vftbl.BeginDraw(ThisPtr, ref updateRect, ref iid, out updateObject, ref point)); } public void EndDraw() @@ -111,9 +128,9 @@ namespace ABI.Windows.UI.Composition.Interop Marshal.ThrowExceptionForHR(_obj.Vftbl.EndDraw(ThisPtr)); } - public void Resize(Size sizePixels) + public void Resize(POINT sizePixels) { - throw new NotImplementedException(); + Marshal.ThrowExceptionForHR(_obj.Vftbl.Resize(ThisPtr, sizePixels)); } public void ResumeDraw() @@ -121,7 +138,7 @@ namespace ABI.Windows.UI.Composition.Interop throw new NotImplementedException(); } - public void Scroll(Rect scrollRect, Rect clipRect, int offsetX, int offsetY) + public void Scroll(RECT scrollRect, RECT clipRect, int offsetX, int offsetY) { throw new NotImplementedException(); } From 6adb1d062475ec8679ef01048bba24902c2c95b8 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 12:51:37 -0300 Subject: [PATCH 006/115] pass in wrapped surface to session. --- src/Windows/Avalonia.Win32/Composition/CompositionHost.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 5f20d18faf..02291d93ed 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -69,7 +69,7 @@ namespace Avalonia.Win32 var restoreContext = _context.MakeCurrent(surface); - return new Session(_display, _context, null, _info, l, restoreContext, () => { }, true); + return new Session(_display, _context, surface, _info, l, restoreContext, () => { }, true); } public override void Dispose() @@ -108,7 +108,7 @@ namespace Avalonia.Win32 { _context.GlInterface.Flush(); _display.EglInterface.WaitGL(); - _glSurface?.SwapBuffers(); + _glSurface.SwapBuffers(); _display.EglInterface.WaitClient(); _display.EglInterface.WaitGL(); _display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); From f5dd50e8ea855a8e903af1e872648b60c5e7de52 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 12:56:46 -0300 Subject: [PATCH 007/115] call enddraw. --- src/Windows/Avalonia.Win32/Composition/CompositionHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 02291d93ed..b82fbc7d1d 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -69,7 +69,7 @@ namespace Avalonia.Win32 var restoreContext = _context.MakeCurrent(surface); - return new Session(_display, _context, surface, _info, l, restoreContext, () => { }, true); + return new Session(_display, _context, surface, _info, l, restoreContext, () => { _surfaceInterop.EndDraw(); }, true); } public override void Dispose() From f0c2ff7394715407368979f5361f7746a032099e Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 13:02:03 -0300 Subject: [PATCH 008/115] call base.BeginDraw we dont need our own session class. --- .../Composition/CompositionHost.cs | 52 +------------------ 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index b82fbc7d1d..3837134643 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -69,58 +69,8 @@ namespace Avalonia.Win32 var restoreContext = _context.MakeCurrent(surface); - return new Session(_display, _context, surface, _info, l, restoreContext, () => { _surfaceInterop.EndDraw(); }, true); + return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); }, true); } - - public override void Dispose() - { - _surfaceInterop.EndDraw(); - base.Dispose(); - } - } - - class Session : IGlPlatformSurfaceRenderingSession - { - private readonly EglContext _context; - private readonly EglSurface _glSurface; - private readonly EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo _info; - private readonly EglDisplay _display; - private readonly IDisposable _lock; - private readonly IDisposable _restoreContext; - private readonly Action _onFinish; - - - public Session(EglDisplay display, EglContext context, - EglSurface glSurface, EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info, - IDisposable @lock, IDisposable restoreContext, Action onFinish, bool isYFlipped) - { - IsYFlipped = isYFlipped; - _context = context; - _display = display; - _glSurface = glSurface; - _info = info; - _lock = @lock; - _restoreContext = restoreContext; - _onFinish = onFinish; - } - - public void Dispose() - { - _context.GlInterface.Flush(); - _display.EglInterface.WaitGL(); - _glSurface.SwapBuffers(); - _display.EglInterface.WaitClient(); - _display.EglInterface.WaitGL(); - _display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); - _restoreContext.Dispose(); - _lock.Dispose(); - _onFinish?.Invoke(); - } - - public IGlContext Context => _context; - public PixelSize Size => _info.Size; - public double Scaling => _info.Scaling; - public bool IsYFlipped { get; } } } From 53f3bc6e7fe84fc0fb3bf9e5f11fd327664ff9ca Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 13:25:24 -0300 Subject: [PATCH 009/115] working rendering. --- .../Composition/CompositionHost.cs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 3837134643..d4bbb67a3b 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -28,14 +28,14 @@ namespace Avalonia.Win32 } public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() - { + { return new CompositionRenderTarget(_display, _context, _surfaceInterop, _info); } class CompositionRenderTarget : EglPlatformSurfaceRenderTargetBase { private readonly EglDisplay _display; - private readonly EglContext _context; + private readonly EglContext _context; private readonly IEglWindowGlPlatformSurfaceInfo _info; private PixelSize _initialSize; private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; @@ -43,7 +43,7 @@ namespace Avalonia.Win32 public CompositionRenderTarget(EglDisplay display, EglContext context, ICompositionDrawingSurfaceInterop interopSurface, IEglWindowGlPlatformSurfaceInfo info) : base(display, context) { _display = display; - _context = context; + _context = context; _surfaceInterop = interopSurface; _info = info; _initialSize = info.Size; @@ -53,8 +53,6 @@ namespace Avalonia.Win32 public override IGlPlatformSurfaceRenderingSession BeginDraw() { - var l = _context.Lock(); - var iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); var updateRect = new RECT { right = _info.Size.Width, bottom = _info.Size.Height }; var offset = new POINT(); @@ -67,8 +65,6 @@ namespace Avalonia.Win32 var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture); - var restoreContext = _context.MakeCurrent(surface); - return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); }, true); } } @@ -159,11 +155,11 @@ namespace Avalonia.Win32 var gDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); - var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100, 100), - Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, + var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100, 100), + Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); - var surfaceInterop = surface.As(); + var surfaceInterop = surface.As(); var brush = _compositor.CreateSurfaceBrush(surface); @@ -174,7 +170,7 @@ namespace Avalonia.Win32 _target.Root = visual; - AddElement(100, 200, 200); + //CreateBlur(); return surfaceInterop; } From e53dfc0d360cb1c34706ae81b54bda7aed65b4c2 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 14:02:51 -0300 Subject: [PATCH 010/115] add blur and avalonia surface visual ontop of blur. --- samples/ControlCatalog/MainWindow.xaml | 3 ++- .../Avalonia.Win32/Composition/CompositionHost.cs | 11 +++++++---- .../Avalonia.Win32/Interop/UnmanagedMethods.cs | 1 + src/Windows/Avalonia.Win32/WindowImpl.cs | 4 ++++ 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml index 76422bc130..c34e392d40 100644 --- a/samples/ControlCatalog/MainWindow.xaml +++ b/samples/ControlCatalog/MainWindow.xaml @@ -7,7 +7,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:ControlCatalog.ViewModels" xmlns:v="clr-namespace:ControlCatalog.Views" - x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}" Background="{DynamicResource SystemControlPageBackgroundAltHighBrush}"> + TransparencyLevelHint="Transparent" + x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}" Background="{x:Null}"> diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index d4bbb67a3b..874bdaaf69 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -155,7 +155,7 @@ namespace Avalonia.Win32 var gDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); - var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100, 100), + var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(0, 0), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); @@ -167,10 +167,13 @@ namespace Avalonia.Win32 visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); visual.Brush = brush; + //_target.Root = visual; - _target.Root = visual; + CreateBlur(); + + var visuals = _target.Root.As().Children; - //CreateBlur(); + visuals.InsertAtTop(visual); return surfaceInterop; } @@ -196,7 +199,7 @@ namespace Avalonia.Win32 void CreateCompositionRoot() { var root = _compositor.CreateContainerVisual(); - root.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); + root.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); //root.Offset = new System.Numerics.Vector3(0, 0, 0); _target.Root = root; } diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index b3b38db1ab..bef65a06d8 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -465,6 +465,7 @@ namespace Avalonia.Win32.Interop WS_VSCROLL = 0x200000, WS_EX_DLGMODALFRAME = 0x00000001, WS_EX_NOPARENTNOTIFY = 0x00000004, + WS_EX_NOREDIRECTIONBITMAP = 0x00200000, WS_EX_TOPMOST = 0x00000008, WS_EX_ACCEPTFILES = 0x00000010, WS_EX_TRANSPARENT = 0x00000020, diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 03d2a328a6..fdde128800 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -106,6 +106,10 @@ namespace Avalonia.Win32 { cgl.AttachToCompositionTree(_hwnd); } + else + { + CompositionHost.Instance.Initialize(_hwnd); + } Screen = new ScreenImpl(); From 1f9e395fabb55234e452cdfe94562774e950e61a Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 14:53:05 -0300 Subject: [PATCH 011/115] hack to clear window context, and only call interopsurface.resize when size actually changes. --- .../Composition/CompositionHost.cs | 33 +++++++++++++++++-- .../Composition/GaussianBlurEffect.cs | 2 +- src/Windows/Avalonia.Win32/WindowImpl.cs | 2 ++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 874bdaaf69..fd76e4a523 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -51,13 +51,42 @@ namespace Avalonia.Win32 public override bool IsCorrupted => _initialSize != _info.Size; + bool _firstRun = true; + POINT lastSize; public override IGlPlatformSurfaceRenderingSession BeginDraw() { + if (_firstRun) + { + _firstRun = false; + var windowSurface = new EglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, _info); + + using (var target = windowSurface.CreateGlRenderTarget()) + { + using (var session = target.BeginDraw()) + { + using (session.Context.MakeCurrent()) + { + var gl = _context.GlInterface; + gl.Viewport(0, 0, _info.Size.Width, _info.Size.Height); + gl.ClearStencil(0); + gl.ClearColor(0, 0, 0, 0); + gl.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_DEPTH_BUFFER_BIT); + gl.Flush(); + } + } + } + } + + var iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); var updateRect = new RECT { right = _info.Size.Width, bottom = _info.Size.Height }; var offset = new POINT(); - _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); + if (lastSize.X != _info.Size.Width || lastSize.Y != _info.Size.Height) + { + lastSize = new POINT { X = _info.Size.Width, Y = _info.Size.Height }; + _surfaceInterop.Resize(lastSize); + } _surfaceInterop.BeginDraw( ref updateRect, ref iid, @@ -65,7 +94,7 @@ namespace Avalonia.Win32 var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture); - return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); }, true); + return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); Marshal.Release(texture); surface.Dispose(); }, true); } } } diff --git a/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs b/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs index 19595e8977..4e1be3af1a 100644 --- a/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs +++ b/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs @@ -52,7 +52,7 @@ namespace Avalonia.Win32 return 30.0f; case D2D1GaussianBlurProp.D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION: - return (UInt32)D2D1_GAUSSIANBLUR_OPTIMIZATION.D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED; + return (UInt32)D2D1_GAUSSIANBLUR_OPTIMIZATION.D2D1_GAUSSIANBLUR_OPTIMIZATION_BALANCED; case D2D1GaussianBlurProp.D2D1_GAUSSIANBLUR_PROP_BORDER_MODE: return (UInt32)D2D1_BORDER_MODE.D2D1_BORDER_MODE_HARD; diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index fdde128800..151a998673 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -100,7 +100,9 @@ namespace Avalonia.Win32 _framebuffer = new FramebufferManager(_hwnd); if (Win32GlManager.EglFeature != null) + { _gl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); + } if (_gl is CompositionEglGlPlatformSurface cgl) { From 372f8e3938088ed882f006e32e1d7b083149a145 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 26 Jun 2020 15:29:35 -0300 Subject: [PATCH 012/115] 1 graphics device, 1 surface and visual tree per window. --- .../Composition/CompositionHost.cs | 49 +++++++++---------- src/Windows/Avalonia.Win32/WindowImpl.cs | 2 +- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index fd76e4a523..1735b22035 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -24,7 +24,7 @@ namespace Avalonia.Win32 public void AttachToCompositionTree(IntPtr hwnd) { - _surfaceInterop = CompositionHost.Instance.Initialize(hwnd); + _surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd); } public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() @@ -47,6 +47,8 @@ namespace Avalonia.Win32 _surfaceInterop = interopSurface; _info = info; _initialSize = info.Size; + lastSize = new POINT { X = _info.Size.Width, Y = _info.Size.Height }; + _surfaceInterop.Resize(lastSize); } public override bool IsCorrupted => _initialSize != _info.Size; @@ -85,7 +87,7 @@ namespace Avalonia.Win32 if (lastSize.X != _info.Size.Width || lastSize.Y != _info.Size.Height) { lastSize = new POINT { X = _info.Size.Width, Y = _info.Size.Height }; - _surfaceInterop.Resize(lastSize); + // _surfaceInterop.Resize(lastSize); } _surfaceInterop.BeginDraw( ref updateRect, @@ -135,17 +137,18 @@ namespace Avalonia.Win32 private Compositor _compositor; private Windows.System.DispatcherQueueController _dispatcherQueueController; - private Windows.UI.Composition.Desktop.DesktopWindowTarget _target; + private CompositionGraphicsDevice _graphicsDevice; private CompositionHost() { + Initialize(); } - public void AddElement(float size, float x, float y) + public void AddElement(CompositionTarget target, float size, float x, float y) { - if (_target.Root != null) + if (target.Root != null) { - var visuals = _target.Root.As().Children; + var visuals = target.Root.As().Children; var visual = _compositor.CreateSpriteVisual(); @@ -169,22 +172,24 @@ namespace Avalonia.Win32 } } - public ICompositionDrawingSurfaceInterop Initialize(IntPtr hwnd) + private void Initialize() { EnsureDispatcherQueue(); if (_dispatcherQueueController != null) _compositor = new Windows.UI.Composition.Compositor(); - CreateDesktopWindowTarget(hwnd); - CreateCompositionRoot(); - var interop = _compositor.As(); var display = Win32GlManager.EglFeature.Display as AngleWin32EglDisplay; - var gDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); + _graphicsDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); + } + + public ICompositionDrawingSurfaceInterop InitialiseWindowCompositionTree(IntPtr hwnd) + { + var target = CreateDesktopWindowTarget(hwnd); - var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(0, 0), + var surface = _graphicsDevice.CreateDrawingSurface(new Windows.Foundation.Size(0, 0), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); @@ -198,16 +203,16 @@ namespace Avalonia.Win32 visual.Brush = brush; //_target.Root = visual; - CreateBlur(); + target.Root = CreateBlur(); - var visuals = _target.Root.As().Children; + var visuals = target.Root.As().Children; visuals.InsertAtTop(visual); return surfaceInterop; } - public void CreateBlur() + public SpriteVisual CreateBlur() { var effect = new GaussianBlurEffect(); var effectFactory = _compositor.CreateEffectFactory(effect); @@ -222,23 +227,15 @@ namespace Avalonia.Win32 visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); visual.Brush = blurBrush; - _target.Root = visual; - } - - void CreateCompositionRoot() - { - var root = _compositor.CreateContainerVisual(); - root.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); - //root.Offset = new System.Numerics.Vector3(0, 0, 0); - _target.Root = root; + return visual; } - void CreateDesktopWindowTarget(IntPtr window) + CompositionTarget CreateDesktopWindowTarget(IntPtr window) { var interop = _compositor.As(); interop.CreateDesktopWindowTarget(window, false, out var windowTarget); - _target = Windows.UI.Composition.Desktop.DesktopWindowTarget.FromAbi(windowTarget); + return Windows.UI.Composition.Desktop.DesktopWindowTarget.FromAbi(windowTarget); } void EnsureDispatcherQueue() diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 151a998673..bcccdf4810 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -110,7 +110,7 @@ namespace Avalonia.Win32 } else { - CompositionHost.Instance.Initialize(_hwnd); + CompositionHost.Instance.InitialiseWindowCompositionTree(_hwnd); } Screen = new ScreenImpl(); From c22b71aa50cc0b74848be1db1723376a736f7b3a Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Thu, 6 Aug 2020 17:41:32 +0800 Subject: [PATCH 013/115] update build.ps1 to put downloaded dotnet in PATH --- build.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.ps1 b/build.ps1 index 57e2f80075..3672e82d3b 100644 --- a/build.ps1 +++ b/build.ps1 @@ -62,6 +62,8 @@ else { } else { ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } } + + $env:PATH="$DotNetDirectory;$env:PATH" } Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" From bcf502e1ca158db751519a8c69819a8aa983030a Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 03:41:52 -0700 Subject: [PATCH 014/115] texture offsets --- .../ControlCatalog.NetCore/Properties/launchSettings.json | 8 ++++++++ src/Avalonia.OpenGL/Angle/AngleEglInterface.cs | 8 ++++---- src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs | 4 ++-- src/Avalonia.OpenGL/EglConsts.cs | 4 ++++ src/Windows/Avalonia.Win32/Composition/CompositionHost.cs | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 samples/ControlCatalog.NetCore/Properties/launchSettings.json diff --git a/samples/ControlCatalog.NetCore/Properties/launchSettings.json b/samples/ControlCatalog.NetCore/Properties/launchSettings.json new file mode 100644 index 0000000000..cd8a2c824b --- /dev/null +++ b/samples/ControlCatalog.NetCore/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "ControlCatalog.NetCore": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs index 375b93c27c..ef0ddf65b6 100644 --- a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs +++ b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs @@ -7,8 +7,8 @@ namespace Avalonia.OpenGL.Angle { public class AngleEglInterface : EglInterface { - [DllImport("libegl.dll", CharSet = CharSet.Ansi)] - static extern IntPtr eglGetProcAddress(string proc); + [DllImport("libglesv2.dll", CharSet = CharSet.Ansi)] + static extern IntPtr EGL_GetProcAddress(string proc); public AngleEglInterface() : base(LoadAngle()) { @@ -20,10 +20,10 @@ namespace Avalonia.OpenGL.Angle if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) throw new PlatformNotSupportedException(); { - var disp = eglGetProcAddress("eglGetPlatformDisplayEXT"); + var disp = EGL_GetProcAddress("eglGetPlatformDisplayEXT"); if (disp == IntPtr.Zero) throw new OpenGlException("libegl.dll doesn't have eglGetPlatformDisplayEXT entry point"); - return eglGetProcAddress; + return EGL_GetProcAddress; } } diff --git a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs index 1a42ed90c2..af10211f15 100644 --- a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs +++ b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs @@ -78,11 +78,11 @@ namespace Avalonia.OpenGL.Angle return d3dDeviceHandle; } - public EglSurface WrapDirect3D11Texture(IntPtr handle) + public EglSurface WrapDirect3D11Texture(IntPtr handle, int offsetX, int offsetY) { if (PlatformApi != AngleOptions.PlatformApi.DirectX11) throw new InvalidOperationException("Current platform API is " + PlatformApi); - return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_NONE, EGL_NONE }); + return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_TEXTURE_OFFSET_X_ANGLE, offsetX, EGL_TEXTURE_OFFSET_Y_ANGLE, offsetY, EGL_NONE, EGL_NONE }); } } } diff --git a/src/Avalonia.OpenGL/EglConsts.cs b/src/Avalonia.OpenGL/EglConsts.cs index 8e44004f2d..c644df97bf 100644 --- a/src/Avalonia.OpenGL/EglConsts.cs +++ b/src/Avalonia.OpenGL/EglConsts.cs @@ -205,5 +205,9 @@ namespace Avalonia.OpenGL public const int EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200; public const int EGL_D3D_TEXTURE_ANGLE = 0x33A3; + + + public const int EGL_TEXTURE_OFFSET_X_ANGLE = 0x3490; + public const int EGL_TEXTURE_OFFSET_Y_ANGLE = 0x3491; } } diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 1735b22035..afd5ff4e39 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -94,7 +94,7 @@ namespace Avalonia.Win32 ref iid, out IntPtr texture, ref offset); - var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture); + var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture, offset.X, offset.Y); return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); Marshal.Release(texture); surface.Dispose(); }, true); } From e6cf04d4e1eb6f2955cf495a65c125ceb391111d Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 03:58:34 -0700 Subject: [PATCH 015/115] update egl properties for wrapped texture. --- src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs | 4 ++-- src/Avalonia.OpenGL/EglConsts.cs | 2 ++ src/Windows/Avalonia.Win32/Composition/CompositionHost.cs | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs index af10211f15..3b254d401a 100644 --- a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs +++ b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs @@ -78,11 +78,11 @@ namespace Avalonia.OpenGL.Angle return d3dDeviceHandle; } - public EglSurface WrapDirect3D11Texture(IntPtr handle, int offsetX, int offsetY) + public EglSurface WrapDirect3D11Texture(IntPtr handle, int offsetX, int offsetY, int width, int height) { if (PlatformApi != AngleOptions.PlatformApi.DirectX11) throw new InvalidOperationException("Current platform API is " + PlatformApi); - return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_TEXTURE_OFFSET_X_ANGLE, offsetX, EGL_TEXTURE_OFFSET_Y_ANGLE, offsetY, EGL_NONE, EGL_NONE }); + return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_TRUE, EGL_TEXTURE_OFFSET_X_ANGLE, offsetX, EGL_TEXTURE_OFFSET_Y_ANGLE, offsetY, EGL_NONE }); } } } diff --git a/src/Avalonia.OpenGL/EglConsts.cs b/src/Avalonia.OpenGL/EglConsts.cs index c644df97bf..5910e32ee1 100644 --- a/src/Avalonia.OpenGL/EglConsts.cs +++ b/src/Avalonia.OpenGL/EglConsts.cs @@ -209,5 +209,7 @@ namespace Avalonia.OpenGL public const int EGL_TEXTURE_OFFSET_X_ANGLE = 0x3490; public const int EGL_TEXTURE_OFFSET_Y_ANGLE = 0x3491; + + public const int EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE = 0x33A6; } } diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index afd5ff4e39..427655adf1 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -87,14 +87,14 @@ namespace Avalonia.Win32 if (lastSize.X != _info.Size.Width || lastSize.Y != _info.Size.Height) { lastSize = new POINT { X = _info.Size.Width, Y = _info.Size.Height }; - // _surfaceInterop.Resize(lastSize); + _surfaceInterop.Resize(lastSize); } _surfaceInterop.BeginDraw( ref updateRect, ref iid, out IntPtr texture, ref offset); - var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture, offset.X, offset.Y); + var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture, offset.X, offset.Y, _info.Size.Width, _info.Size.Height); return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); Marshal.Release(texture); surface.Dispose(); }, true); } From b6667530a25ae46916d11c4f76df83a3b0b7ba04 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 06:27:51 -0700 Subject: [PATCH 016/115] force ui thread rendering for now. --- src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs | 2 +- src/Windows/Avalonia.Win32/Win32Platform.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs index 3b254d401a..c1f0f376b1 100644 --- a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs +++ b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs @@ -82,7 +82,7 @@ namespace Avalonia.OpenGL.Angle { if (PlatformApi != AngleOptions.PlatformApi.DirectX11) throw new InvalidOperationException("Current platform API is " + PlatformApi); - return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_TRUE, EGL_TEXTURE_OFFSET_X_ANGLE, offsetX, EGL_TEXTURE_OFFSET_Y_ANGLE, offsetY, EGL_NONE }); + return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_TRUE, EGL_TEXTURE_OFFSET_X_ANGLE, offsetX, EGL_TEXTURE_OFFSET_Y_ANGLE, offsetY, EGL_NONE }); } } } diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index af6058d197..8840dcacef 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -88,7 +88,7 @@ namespace Avalonia.Win32 .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) .Bind().ToConstant(new RenderLoop()) - .Bind().ToConstant(new DefaultRenderTimer(60)) + .Bind().ToConstant(new UiThreadRenderTimer(60)) .Bind().ToSingleton() .Bind().ToConstant(s_instance) .Bind().ToSingleton() From 3e96718d90e2c8bad28ab4110a4464e4e418ada9 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 07:13:55 -0700 Subject: [PATCH 017/115] simplify hack to clear window. --- .../Composition/CompositionHost.cs | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 427655adf1..b810ec45e0 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -64,18 +64,7 @@ namespace Avalonia.Win32 using (var target = windowSurface.CreateGlRenderTarget()) { - using (var session = target.BeginDraw()) - { - using (session.Context.MakeCurrent()) - { - var gl = _context.GlInterface; - gl.Viewport(0, 0, _info.Size.Width, _info.Size.Height); - gl.ClearStencil(0); - gl.ClearColor(0, 0, 0, 0); - gl.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_DEPTH_BUFFER_BIT); - gl.Flush(); - } - } + target.BeginDraw().Dispose(); } } @@ -83,12 +72,7 @@ namespace Avalonia.Win32 var iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); var updateRect = new RECT { right = _info.Size.Width, bottom = _info.Size.Height }; var offset = new POINT(); - - if (lastSize.X != _info.Size.Width || lastSize.Y != _info.Size.Height) - { - lastSize = new POINT { X = _info.Size.Width, Y = _info.Size.Height }; - _surfaceInterop.Resize(lastSize); - } + _surfaceInterop.BeginDraw( ref updateRect, ref iid, From 40f45115fbbe1e6a9dddc075ef5d926829e34768 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 07:14:28 -0700 Subject: [PATCH 018/115] remove unnecessary calls. --- src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs index 081db5d26a..ce4c6ecb90 100644 --- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs @@ -72,10 +72,6 @@ namespace Avalonia.Skia $"Can't create drawing context for surface with {size} size and {scaling} scaling"); } - gl.Viewport(0, 0, size.Width, size.Height); - gl.ClearStencil(0); - gl.ClearColor(0, 0, 0, 0); - gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); lock (_grContext) { _grContext.ResetContext(); @@ -88,6 +84,7 @@ namespace Avalonia.Skia SKColorType.Rgba8888); success = true; + return new GlGpuSession(_grContext, renderTarget, surface, glSession); } } From 3deae8dbff8e4734e96b1f6aed2791f0eb989ee1 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 07:32:53 -0700 Subject: [PATCH 019/115] no redirection bitmap --- .../Avalonia.Win32/Composition/CompositionHost.cs | 13 ------------- src/Windows/Avalonia.Win32/WindowImpl.cs | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index b810ec45e0..6d293a31eb 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -53,22 +53,9 @@ namespace Avalonia.Win32 public override bool IsCorrupted => _initialSize != _info.Size; - bool _firstRun = true; POINT lastSize; public override IGlPlatformSurfaceRenderingSession BeginDraw() { - if (_firstRun) - { - _firstRun = false; - var windowSurface = new EglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, _info); - - using (var target = windowSurface.CreateGlRenderTarget()) - { - target.BeginDraw().Dispose(); - } - } - - var iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); var updateRect = new RECT { right = _info.Size.Width, bottom = _info.Size.Height }; var offset = new POINT(); diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 25ae755990..3047f44a71 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -626,7 +626,7 @@ namespace Avalonia.Win32 protected virtual IntPtr CreateWindowOverride(ushort atom) { return CreateWindowEx( - 0, + (int)WindowStyles.WS_EX_NOREDIRECTIONBITMAP, // TODO this is only when using Win UI Comp. atom, null, (int)WindowStyles.WS_OVERLAPPEDWINDOW | (int) WindowStyles.WS_CLIPCHILDREN, From 2981cc470dc2258450c1b6dae80e405f1ab357a9 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 08:46:12 -0700 Subject: [PATCH 020/115] use render thread. --- src/Windows/Avalonia.Win32/Win32Platform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 8840dcacef..af6058d197 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -88,7 +88,7 @@ namespace Avalonia.Win32 .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) .Bind().ToConstant(new RenderLoop()) - .Bind().ToConstant(new UiThreadRenderTimer(60)) + .Bind().ToConstant(new DefaultRenderTimer(60)) .Bind().ToSingleton() .Bind().ToConstant(s_instance) .Bind().ToSingleton() From 62e2a2d2e64426ed69c0b97cf41ffbb6b386b7e6 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 16:59:14 +0100 Subject: [PATCH 021/115] remove override directx api. --- samples/ControlCatalog.NetCore/Program.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index 9fcf618614..142736a0bb 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -10,8 +10,6 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Headless; using Avalonia.LogicalTree; using Avalonia.Skia; -using Avalonia.Dialogs; -using Avalonia.OpenGL; using Avalonia.ReactiveUI; using Avalonia.Threading; using Avalonia.Dialogs; @@ -120,10 +118,6 @@ namespace ControlCatalog.NetCore EnableMultitouch = true, AllowEglInitialization = true }) - .With(new AngleOptions - { - AllowedPlatformApis = new System.Collections.Generic.List { AngleOptions.PlatformApi.DirectX11} - }) .UseSkia() .UseReactiveUI() .UseManagedSystemDialogs() From 758ddafad888f0791a6a0cd256b11ca97ac24971 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 17:02:38 +0100 Subject: [PATCH 022/115] restore file. --- src/Avalonia.OpenGL/Angle/AngleEglInterface.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs index ef0ddf65b6..375b93c27c 100644 --- a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs +++ b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs @@ -7,8 +7,8 @@ namespace Avalonia.OpenGL.Angle { public class AngleEglInterface : EglInterface { - [DllImport("libglesv2.dll", CharSet = CharSet.Ansi)] - static extern IntPtr EGL_GetProcAddress(string proc); + [DllImport("libegl.dll", CharSet = CharSet.Ansi)] + static extern IntPtr eglGetProcAddress(string proc); public AngleEglInterface() : base(LoadAngle()) { @@ -20,10 +20,10 @@ namespace Avalonia.OpenGL.Angle if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) throw new PlatformNotSupportedException(); { - var disp = EGL_GetProcAddress("eglGetPlatformDisplayEXT"); + var disp = eglGetProcAddress("eglGetPlatformDisplayEXT"); if (disp == IntPtr.Zero) throw new OpenGlException("libegl.dll doesn't have eglGetPlatformDisplayEXT entry point"); - return EGL_GetProcAddress; + return eglGetProcAddress; } } From e68ce5643e815210d0b8f8b622eed3aae30e74dd Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 09:05:24 -0700 Subject: [PATCH 023/115] Revert "restore file." This reverts commit 758ddafad888f0791a6a0cd256b11ca97ac24971. --- src/Avalonia.OpenGL/Angle/AngleEglInterface.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs index 375b93c27c..ef0ddf65b6 100644 --- a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs +++ b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs @@ -7,8 +7,8 @@ namespace Avalonia.OpenGL.Angle { public class AngleEglInterface : EglInterface { - [DllImport("libegl.dll", CharSet = CharSet.Ansi)] - static extern IntPtr eglGetProcAddress(string proc); + [DllImport("libglesv2.dll", CharSet = CharSet.Ansi)] + static extern IntPtr EGL_GetProcAddress(string proc); public AngleEglInterface() : base(LoadAngle()) { @@ -20,10 +20,10 @@ namespace Avalonia.OpenGL.Angle if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) throw new PlatformNotSupportedException(); { - var disp = eglGetProcAddress("eglGetPlatformDisplayEXT"); + var disp = EGL_GetProcAddress("eglGetPlatformDisplayEXT"); if (disp == IntPtr.Zero) throw new OpenGlException("libegl.dll doesn't have eglGetPlatformDisplayEXT entry point"); - return eglGetProcAddress; + return EGL_GetProcAddress; } } From f068fa02e989e55ac3d24c944a0aa66837480dad Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 11 Sep 2020 09:14:37 -0700 Subject: [PATCH 024/115] restore render timer. --- src/Windows/Avalonia.Win32/Win32Platform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index af6058d197..8840dcacef 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -88,7 +88,7 @@ namespace Avalonia.Win32 .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) .Bind().ToConstant(new RenderLoop()) - .Bind().ToConstant(new DefaultRenderTimer(60)) + .Bind().ToConstant(new UiThreadRenderTimer(60)) .Bind().ToSingleton() .Bind().ToConstant(s_instance) .Bind().ToSingleton() From 0de7f4d7e0c5141060038d4a7f1f55ab36c10e51 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sat, 12 Sep 2020 11:24:21 -0700 Subject: [PATCH 025/115] pass egl_width / height. --- src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs index c1f0f376b1..3b254d401a 100644 --- a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs +++ b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs @@ -82,7 +82,7 @@ namespace Avalonia.OpenGL.Angle { if (PlatformApi != AngleOptions.PlatformApi.DirectX11) throw new InvalidOperationException("Current platform API is " + PlatformApi); - return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_TRUE, EGL_TEXTURE_OFFSET_X_ANGLE, offsetX, EGL_TEXTURE_OFFSET_Y_ANGLE, offsetY, EGL_NONE }); + return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_TRUE, EGL_TEXTURE_OFFSET_X_ANGLE, offsetX, EGL_TEXTURE_OFFSET_Y_ANGLE, offsetY, EGL_NONE }); } } } From 75025a15c195cf91197674f78a368e9ee6ac3da0 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sat, 12 Sep 2020 11:46:32 -0700 Subject: [PATCH 026/115] avalonia never resizes so use intptr for update rect. --- .../Avalonia.Win32/Composition/CompositionHost.cs | 7 +++---- .../Composition/ICompositionDrawingSurfaceInterop.cs | 12 ++++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 6d293a31eb..5d13109dda 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -39,6 +39,7 @@ namespace Avalonia.Win32 private readonly IEglWindowGlPlatformSurfaceInfo _info; private PixelSize _initialSize; private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; + private static Guid s_Iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); public CompositionRenderTarget(EglDisplay display, EglContext context, ICompositionDrawingSurfaceInterop interopSurface, IEglWindowGlPlatformSurfaceInfo info) : base(display, context) { @@ -56,13 +57,11 @@ namespace Avalonia.Win32 POINT lastSize; public override IGlPlatformSurfaceRenderingSession BeginDraw() { - var iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); - var updateRect = new RECT { right = _info.Size.Width, bottom = _info.Size.Height }; var offset = new POINT(); _surfaceInterop.BeginDraw( - ref updateRect, - ref iid, + IntPtr.Zero, + ref s_Iid, out IntPtr texture, ref offset); var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture, offset.X, offset.Y, _info.Size.Width, _info.Size.Height); diff --git a/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs b/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs index 8fea5f293b..2eac796376 100644 --- a/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs +++ b/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs @@ -25,7 +25,7 @@ namespace Windows.UI.Composition.Interop [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] public interface ICompositionDrawingSurfaceInterop { - void BeginDraw(ref RECT updateRect, ref Guid iid, out IntPtr updateObject, ref POINT point); + void BeginDraw(IntPtr updateRect, ref Guid iid, out IntPtr updateObject, ref POINT point); void EndDraw(); @@ -51,9 +51,9 @@ namespace ABI.Windows.UI.Composition.Interop { [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] - public struct Vftbl + public unsafe struct Vftbl { - public delegate int _BeginDraw(IntPtr ThisPtr, ref RECT updateRect, ref Guid iid, out IntPtr updateObject, ref POINT updateOffset); + public delegate int _BeginDraw(IntPtr ThisPtr, IntPtr updateRect, ref Guid iid, out IntPtr updateObject, ref POINT updateOffset); public delegate int _EndDraw(IntPtr ThisPtr); public delegate int _Resize(IntPtr ThisPtr, POINT sizePixels); public delegate int _ResumeDraw(IntPtr ThisPtr); @@ -87,7 +87,7 @@ namespace ABI.Windows.UI.Composition.Interop Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false); } - private static int Do_Abi_BeginDraw(IntPtr ThisPtr, ref RECT updateRect, ref Guid iid, out IntPtr updateObject, ref POINT updateOffset) + private static int Do_Abi_BeginDraw(IntPtr ThisPtr, IntPtr updateRect, ref Guid iid, out IntPtr updateObject, ref POINT updateOffset) { updateObject = IntPtr.Zero; return 0; @@ -118,9 +118,9 @@ namespace ABI.Windows.UI.Composition.Interop _obj = obj; } - public void BeginDraw(ref RECT updateRect, ref Guid iid, out IntPtr updateObject, ref POINT point) + public void BeginDraw(IntPtr updateRect, ref Guid iid, out IntPtr updateObject, ref POINT point) { - Marshal.ThrowExceptionForHR(_obj.Vftbl.BeginDraw(ThisPtr, ref updateRect, ref iid, out updateObject, ref point)); + Marshal.ThrowExceptionForHR(_obj.Vftbl.BeginDraw(ThisPtr, updateRect, ref iid, out updateObject, ref point)); } public void EndDraw() From 688ba15b6a3c6b1010bb558cf8b224de589936b7 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 01:53:54 -0700 Subject: [PATCH 027/115] seperate classes. --- .../CompositionEglGlPlatformSurface.cs | 75 +++++++++++++++++ .../Composition/CompositionHost.cs | 83 ++----------------- 2 files changed, 84 insertions(+), 74 deletions(-) create mode 100644 src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs new file mode 100644 index 0000000000..c5e99a4b5d --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -0,0 +1,75 @@ +using System; +using System.Runtime.InteropServices; +using Avalonia.OpenGL; +using Avalonia.OpenGL.Angle; +using Windows.UI.Composition.Interop; + +namespace Avalonia.Win32 +{ + public class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase + { + private readonly EglDisplay _display; + private readonly EglContext _context; + private readonly IEglWindowGlPlatformSurfaceInfo _info; + private ICompositionDrawingSurfaceInterop _surfaceInterop; + private Windows.UI.Composition.Visual _surface; + + public CompositionEglGlPlatformSurface(EglContext context, IEglWindowGlPlatformSurfaceInfo info) : base() + { + _display = context.Display; + _context = context; + _info = info; + } + + public void AttachToCompositionTree(IntPtr hwnd) + { + _surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd, out _surface); + } + + public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() + { + return new CompositionRenderTarget(_display, _context, _surface, _surfaceInterop, _info); + } + + class CompositionRenderTarget : EglPlatformSurfaceRenderTargetBase + { + private readonly EglDisplay _display; + private readonly IEglWindowGlPlatformSurfaceInfo _info; + private PixelSize _initialSize; + private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; + private static Guid s_Iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); + private Windows.UI.Composition.Visual _compositionVisual; + + public CompositionRenderTarget(EglDisplay display, + EglContext context, + Windows.UI.Composition.Visual compositionVisual, + ICompositionDrawingSurfaceInterop interopSurface, + IEglWindowGlPlatformSurfaceInfo info) + : base(display, context) + { + _display = display; + _surfaceInterop = interopSurface; + _info = info; + _initialSize = info.Size; + _compositionVisual = compositionVisual; + _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); + } + + public override bool IsCorrupted => _initialSize != _info.Size; + public override IGlPlatformSurfaceRenderingSession BeginDraw() + { + var offset = new POINT(); + + _surfaceInterop.BeginDraw( + IntPtr.Zero, + ref s_Iid, + out IntPtr texture, ref offset); + + var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture, offset.X, offset.Y, _info.Size.Width, _info.Size.Height); + + return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); Marshal.Release(texture); surface.Dispose(); _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); }, true); + } + } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 5d13109dda..48656e1816 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -1,6 +1,5 @@ using System; using System.Runtime.InteropServices; -using Avalonia.OpenGL; using Avalonia.OpenGL.Angle; using Windows.UI.Composition; using Windows.UI.Composition.Interop; @@ -8,71 +7,6 @@ using WinRT; namespace Avalonia.Win32 { - public class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase - { - private readonly EglDisplay _display; - private readonly EglContext _context; - private readonly IEglWindowGlPlatformSurfaceInfo _info; - private ICompositionDrawingSurfaceInterop _surfaceInterop; - - public CompositionEglGlPlatformSurface(EglContext context, IEglWindowGlPlatformSurfaceInfo info) : base() - { - _display = context.Display; - _context = context; - _info = info; - } - - public void AttachToCompositionTree(IntPtr hwnd) - { - _surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd); - } - - public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() - { - return new CompositionRenderTarget(_display, _context, _surfaceInterop, _info); - } - - class CompositionRenderTarget : EglPlatformSurfaceRenderTargetBase - { - private readonly EglDisplay _display; - private readonly EglContext _context; - private readonly IEglWindowGlPlatformSurfaceInfo _info; - private PixelSize _initialSize; - private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; - private static Guid s_Iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); - - public CompositionRenderTarget(EglDisplay display, EglContext context, ICompositionDrawingSurfaceInterop interopSurface, IEglWindowGlPlatformSurfaceInfo info) : base(display, context) - { - _display = display; - _context = context; - _surfaceInterop = interopSurface; - _info = info; - _initialSize = info.Size; - lastSize = new POINT { X = _info.Size.Width, Y = _info.Size.Height }; - _surfaceInterop.Resize(lastSize); - } - - public override bool IsCorrupted => _initialSize != _info.Size; - - POINT lastSize; - public override IGlPlatformSurfaceRenderingSession BeginDraw() - { - var offset = new POINT(); - - _surfaceInterop.BeginDraw( - IntPtr.Zero, - ref s_Iid, - out IntPtr texture, ref offset); - - var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture, offset.X, offset.Y, _info.Size.Width, _info.Size.Height); - - return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); Marshal.Release(texture); surface.Dispose(); }, true); - } - } - } - - - class CompositionHost { internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE @@ -155,7 +89,7 @@ namespace Avalonia.Win32 _graphicsDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); } - public ICompositionDrawingSurfaceInterop InitialiseWindowCompositionTree(IntPtr hwnd) + public ICompositionDrawingSurfaceInterop InitialiseWindowCompositionTree(IntPtr hwnd, out Windows.UI.Composition.Visual surfaceVisual) { var target = CreateDesktopWindowTarget(hwnd); @@ -163,22 +97,23 @@ namespace Avalonia.Win32 Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); - var surfaceInterop = surface.As(); + var surfaceInterop = surface.As(); var brush = _compositor.CreateSurfaceBrush(surface); - var visual = _compositor.CreateSpriteVisual(); - - visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); + visual.Brush = brush; - //_target.Root = visual; - + visual.Offset = new System.Numerics.Vector3(0, 0, 0); target.Root = CreateBlur(); var visuals = target.Root.As().Children; visuals.InsertAtTop(visual); + visual.CompositeMode = CompositionCompositeMode.SourceOver; + + surfaceVisual = visual; + return surfaceInterop; } @@ -204,7 +139,7 @@ namespace Avalonia.Win32 { var interop = _compositor.As(); - interop.CreateDesktopWindowTarget(window, false, out var windowTarget); + interop.CreateDesktopWindowTarget(window, true, out var windowTarget); return Windows.UI.Composition.Desktop.DesktopWindowTarget.FromAbi(windowTarget); } From b0bc3f4ea8fd47237f946ad72e59da4d399a1568 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 01:56:40 -0700 Subject: [PATCH 028/115] check for windows 10 to decide to use windows.ui.comp tree to render into. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 3047f44a71..d964e490c0 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -104,17 +104,17 @@ namespace Avalonia.Win32 _framebuffer = new FramebufferManager(_hwnd); if (Win32GlManager.EglFeature != null) - { - _gl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); - } - - if (_gl is CompositionEglGlPlatformSurface cgl) - { - cgl.AttachToCompositionTree(_hwnd); - } - else { - CompositionHost.Instance.InitialiseWindowCompositionTree(_hwnd); + if (Win32Platform.WindowsVersion.Major >= 10) + { + var cgl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); + cgl.AttachToCompositionTree(_hwnd); + _gl = cgl; + } + else + { + _gl = new EglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); + } } Screen = new ScreenImpl(); From 8913cea89ec85f4b4a24ea82c32ac70cbf603198 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 01:57:00 -0700 Subject: [PATCH 029/115] code tidy. --- .../CompositionEglGlPlatformSurface.cs | 15 +++---- .../Composition/CompositionHost.cs | 42 ++++--------------- 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index c5e99a4b5d..701070a6b5 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -27,7 +27,7 @@ namespace Avalonia.Win32 } public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() - { + { return new CompositionRenderTarget(_display, _context, _surface, _surfaceInterop, _info); } @@ -40,11 +40,11 @@ namespace Avalonia.Win32 private static Guid s_Iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); private Windows.UI.Composition.Visual _compositionVisual; - public CompositionRenderTarget(EglDisplay display, - EglContext context, - Windows.UI.Composition.Visual compositionVisual, - ICompositionDrawingSurfaceInterop interopSurface, - IEglWindowGlPlatformSurfaceInfo info) + public CompositionRenderTarget(EglDisplay display, + EglContext context, + Windows.UI.Composition.Visual compositionVisual, + ICompositionDrawingSurfaceInterop interopSurface, + IEglWindowGlPlatformSurfaceInfo info) : base(display, context) { _display = display; @@ -53,6 +53,7 @@ namespace Avalonia.Win32 _initialSize = info.Size; _compositionVisual = compositionVisual; _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); + _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); } public override bool IsCorrupted => _initialSize != _info.Size; @@ -67,7 +68,7 @@ namespace Avalonia.Win32 var surface = (_display as AngleWin32EglDisplay).WrapDirect3D11Texture(texture, offset.X, offset.Y, _info.Size.Width, _info.Size.Height); - return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); Marshal.Release(texture); surface.Dispose(); _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); }, true); + return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); Marshal.Release(texture); surface.Dispose(); }, true); } } } diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 48656e1816..8da205fdc6 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -48,41 +48,13 @@ namespace Avalonia.Win32 Initialize(); } - public void AddElement(CompositionTarget target, float size, float x, float y) - { - if (target.Root != null) - { - var visuals = target.Root.As().Children; - - var visual = _compositor.CreateSpriteVisual(); - - var element = _compositor.CreateSpriteVisual(); - var rand = new Random(); - - element.Brush = _compositor.CreateColorBrush(new Windows.UI.Color { A = 255, R = (byte)(rand.NextDouble() * 255), G = (byte)(rand.NextDouble() * 255), B = (byte)(rand.NextDouble() * 255) }); - element.Size = new System.Numerics.Vector2(size, size); - element.Offset = new System.Numerics.Vector3(x, y, 0.0f); - - var animation = _compositor.CreateVector3KeyFrameAnimation(); - var bottom = (float)600 - element.Size.Y; - animation.InsertKeyFrame(1, new System.Numerics.Vector3(element.Offset.X, bottom, 0)); - - animation.Duration = TimeSpan.FromSeconds(2); - animation.DelayTime = TimeSpan.FromSeconds(3); - element.StartAnimation("Offset", animation); - visuals.InsertAtTop(element); - - visuals.InsertAtTop(visual); - } - } - private void Initialize() { EnsureDispatcherQueue(); if (_dispatcherQueueController != null) - _compositor = new Windows.UI.Composition.Compositor(); + _compositor = new Compositor(); - var interop = _compositor.As(); + var interop = _compositor.As(); var display = Win32GlManager.EglFeature.Display as AngleWin32EglDisplay; @@ -91,19 +63,19 @@ namespace Avalonia.Win32 public ICompositionDrawingSurfaceInterop InitialiseWindowCompositionTree(IntPtr hwnd, out Windows.UI.Composition.Visual surfaceVisual) { - var target = CreateDesktopWindowTarget(hwnd); + var target = CreateDesktopWindowTarget(hwnd); var surface = _graphicsDevice.CreateDrawingSurface(new Windows.Foundation.Size(0, 0), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); - var surfaceInterop = surface.As(); + var surfaceInterop = surface.As(); var brush = _compositor.CreateSurfaceBrush(surface); var visual = _compositor.CreateSpriteVisual(); - + visual.Brush = brush; - visual.Offset = new System.Numerics.Vector3(0, 0, 0); + visual.Offset = new System.Numerics.Vector3(0, 0, 0); target.Root = CreateBlur(); var visuals = target.Root.As().Children; @@ -139,7 +111,7 @@ namespace Avalonia.Win32 { var interop = _compositor.As(); - interop.CreateDesktopWindowTarget(window, true, out var windowTarget); + interop.CreateDesktopWindowTarget(window, false, out var windowTarget); return Windows.UI.Composition.Desktop.DesktopWindowTarget.FromAbi(windowTarget); } From 0140d201a1d3ea1444f9397c35cba495e2a39283 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 02:08:43 -0700 Subject: [PATCH 030/115] use render thread. --- src/Windows/Avalonia.Win32/Win32Platform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 8840dcacef..af6058d197 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -88,7 +88,7 @@ namespace Avalonia.Win32 .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) .Bind().ToConstant(new RenderLoop()) - .Bind().ToConstant(new UiThreadRenderTimer(60)) + .Bind().ToConstant(new DefaultRenderTimer(60)) .Bind().ToSingleton() .Bind().ToConstant(s_instance) .Bind().ToSingleton() From 75bf2fcb67e7f63b53aec383c89ad5e18bb0c742 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 02:19:29 -0700 Subject: [PATCH 031/115] remove usings. --- src/Avalonia.OpenGL/Angle/AngleEglInterface.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs index b73053b52e..07890b260c 100644 --- a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs +++ b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs @@ -1,7 +1,5 @@ using System; using System.Runtime.InteropServices; -using Avalonia.Platform; -using Avalonia.Platform.Interop; namespace Avalonia.OpenGL.Angle { From 0b7f211b3a9a98449fc0e6a6c6efd4a911645739 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 02:22:17 -0700 Subject: [PATCH 032/115] fix build error. --- src/Avalonia.OpenGL/Angle/AngleEglInterface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs index 07890b260c..0067124c0b 100644 --- a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs +++ b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs @@ -24,7 +24,7 @@ namespace Avalonia.OpenGL.Angle throw new OpenGlException("libegl.dll doesn't have eglGetPlatformDisplayEXT entry point"); } - return eglGetProcAddress; + return EGL_GetProcAddress; } throw new PlatformNotSupportedException(); From 7dc21fa2164b376f064e12d8b00219c3f4c78791 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 02:29:30 -0700 Subject: [PATCH 033/115] only apply no-redirection bitmap if we are on windows 10. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index d964e490c0..a96a662a71 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -45,6 +45,7 @@ namespace Avalonia.Win32 private Thickness _extendedMargins; private Thickness _offScreenMargin; private double _extendTitleBarHint = -1; + private bool _isUsingComposition; #if USE_MANAGED_DRAG private readonly ManagedWindowResizeDragHelper _managedDrag; @@ -110,6 +111,7 @@ namespace Avalonia.Win32 var cgl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); cgl.AttachToCompositionTree(_hwnd); _gl = cgl; + _isUsingComposition = true; } else { @@ -626,7 +628,7 @@ namespace Avalonia.Win32 protected virtual IntPtr CreateWindowOverride(ushort atom) { return CreateWindowEx( - (int)WindowStyles.WS_EX_NOREDIRECTIONBITMAP, // TODO this is only when using Win UI Comp. + _isUsingComposition ? (int)WindowStyles.WS_EX_NOREDIRECTIONBITMAP : 0, atom, null, (int)WindowStyles.WS_OVERLAPPEDWINDOW | (int) WindowStyles.WS_CLIPCHILDREN, From 094e605af9000e257eff19b0657b4db217527bf0 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 02:36:46 -0700 Subject: [PATCH 034/115] ensure dx11 api for win.ui.comp. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index a96a662a71..fb9f7783b1 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -7,6 +7,7 @@ using Avalonia.Controls.Platform; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.OpenGL; +using Avalonia.OpenGL.Angle; using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Win32.Input; @@ -106,11 +107,15 @@ namespace Avalonia.Win32 if (Win32GlManager.EglFeature != null) { - if (Win32Platform.WindowsVersion.Major >= 10) + if (Win32Platform.WindowsVersion.Major >= 10 && + Win32GlManager.EglFeature.Display is AngleWin32EglDisplay angleDisplay && + angleDisplay.PlatformApi == AngleOptions.PlatformApi.DirectX11) { var cgl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); cgl.AttachToCompositionTree(_hwnd); + _gl = cgl; + _isUsingComposition = true; } else From 874ac50de24753be252f42a237250137fff14447 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 02:54:31 -0700 Subject: [PATCH 035/115] add a texture wrapping method without requiring offset, etc. --- src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs index 3b254d401a..9bb0dd8351 100644 --- a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs +++ b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs @@ -78,6 +78,13 @@ namespace Avalonia.OpenGL.Angle return d3dDeviceHandle; } + public EglSurface WrapDirect3D11Texture(IntPtr handle) + { + if (PlatformApi != AngleOptions.PlatformApi.DirectX11) + throw new InvalidOperationException("Current platform API is " + PlatformApi); + return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_TRUE, EGL_NONE }); + } + public EglSurface WrapDirect3D11Texture(IntPtr handle, int offsetX, int offsetY, int width, int height) { if (PlatformApi != AngleOptions.PlatformApi.DirectX11) From fdb68480463776f8d5cd125ce4eb867a5a9ebc75 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 02:55:13 -0700 Subject: [PATCH 036/115] check windows 10 build number and set composition flag before create window is called. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index fb9f7783b1..c100b3308d 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -101,15 +101,16 @@ namespace Avalonia.Win32 }; _rendererLock = new ManagedDeferredRendererLock(); + _isUsingComposition = Win32Platform.WindowsVersion.Major >= 10 && Win32Platform.WindowsVersion.Build >= 14393 && + Win32GlManager.EglFeature.Display is AngleWin32EglDisplay angleDisplay && + angleDisplay.PlatformApi == AngleOptions.PlatformApi.DirectX11; CreateWindow(); _framebuffer = new FramebufferManager(_hwnd); if (Win32GlManager.EglFeature != null) { - if (Win32Platform.WindowsVersion.Major >= 10 && - Win32GlManager.EglFeature.Display is AngleWin32EglDisplay angleDisplay && - angleDisplay.PlatformApi == AngleOptions.PlatformApi.DirectX11) + if (_isUsingComposition) { var cgl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); cgl.AttachToCompositionTree(_hwnd); From d25d88cdfac7ab224b3fb6f5342699c262a5fabd Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 14 Sep 2020 04:20:17 -0700 Subject: [PATCH 037/115] increase min windows version. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index c100b3308d..7222b66beb 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -101,7 +101,7 @@ namespace Avalonia.Win32 }; _rendererLock = new ManagedDeferredRendererLock(); - _isUsingComposition = Win32Platform.WindowsVersion.Major >= 10 && Win32Platform.WindowsVersion.Build >= 14393 && + _isUsingComposition = Win32Platform.WindowsVersion.Major >= 10 && Win32Platform.WindowsVersion.Build >= 16299 && Win32GlManager.EglFeature.Display is AngleWin32EglDisplay angleDisplay && angleDisplay.PlatformApi == AngleOptions.PlatformApi.DirectX11; From 974c73ca46c414899535635ffab73930e53b5924 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 15 Sep 2020 02:36:27 -0700 Subject: [PATCH 038/115] opengl es 3 --- src/Avalonia.OpenGL/EglDisplay.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.OpenGL/EglDisplay.cs b/src/Avalonia.OpenGL/EglDisplay.cs index 7b194e4346..a3d11f2311 100644 --- a/src/Avalonia.OpenGL/EglDisplay.cs +++ b/src/Avalonia.OpenGL/EglDisplay.cs @@ -67,12 +67,13 @@ namespace Avalonia.OpenGL { Attributes = new[] { - EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_MAJOR_VERSION, 3, + EGL_CONTEXT_MINOR_VERSION, 0, EGL_NONE }, Api = EGL_OPENGL_ES_API, - RenderableTypeBit = EGL_OPENGL_ES2_BIT, - Version = new GlVersion(GlProfileType.OpenGLES, 2, 0) + RenderableTypeBit = EGL_OPENGL_ES3_BIT, + Version = new GlVersion(GlProfileType.OpenGLES, 3, 0) } }) { From 1d1275059883ba603db9727422b5c10471776d8b Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 16 Sep 2020 03:25:47 -0700 Subject: [PATCH 039/115] allow enabling of windows.ui.composition with win32 options. --- src/Windows/Avalonia.Win32/Win32Platform.cs | 9 +++++++++ src/Windows/Avalonia.Win32/WindowImpl.cs | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index af6058d197..7f1ac443ad 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -39,6 +39,15 @@ namespace Avalonia public bool AllowEglInitialization { get; set; } = true; public bool? EnableMultitouch { get; set; } public bool OverlayPopups { get; set; } + + /// + /// Render Avalonia to a Texture inside the Windows.UI.Composition tree. + /// + /// + /// Supported on Windows 10 build 16299 and above. Ignored on other versions. + /// This is recommended if you need to use AcrylicBlur or acrylic in your applications. + /// + public bool UseWindowsUIComposition { get; set; } } } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 7222b66beb..a2bd7f57b9 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -101,7 +101,8 @@ namespace Avalonia.Win32 }; _rendererLock = new ManagedDeferredRendererLock(); - _isUsingComposition = Win32Platform.WindowsVersion.Major >= 10 && Win32Platform.WindowsVersion.Build >= 16299 && + _isUsingComposition = Win32Platform.Options.UseWindowsUIComposition && + Win32Platform.WindowsVersion.Major >= 10 && Win32Platform.WindowsVersion.Build >= 16299 && Win32GlManager.EglFeature.Display is AngleWin32EglDisplay angleDisplay && angleDisplay.PlatformApi == AngleOptions.PlatformApi.DirectX11; From 8470a399b6214ecdd82774cbbc7a1620751db787 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 17 Sep 2020 14:52:02 -0700 Subject: [PATCH 040/115] point angle interface to avalonias custom built optimised angle. --- samples/ControlCatalog.NetCore/Program.cs | 4 +++- src/Avalonia.OpenGL/Angle/AngleEglInterface.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index 142736a0bb..9b62c2c98e 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -13,6 +13,7 @@ using Avalonia.Skia; using Avalonia.ReactiveUI; using Avalonia.Threading; using Avalonia.Dialogs; +using Avalonia.OpenGL; namespace ControlCatalog.NetCore { @@ -116,7 +117,8 @@ namespace ControlCatalog.NetCore .With(new Win32PlatformOptions { EnableMultitouch = true, - AllowEglInitialization = true + AllowEglInitialization = true, + UseWindowsUIComposition = true }) .UseSkia() .UseReactiveUI() diff --git a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs index 0067124c0b..a6f5f33968 100644 --- a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs +++ b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs @@ -5,7 +5,7 @@ namespace Avalonia.OpenGL.Angle { public class AngleEglInterface : EglInterface { - [DllImport("avangle.dll", CharSet = CharSet.Ansi)] + [DllImport("av_libGLESv2.dll", CharSet = CharSet.Ansi)] static extern IntPtr EGL_GetProcAddress(string proc); public AngleEglInterface() : base(LoadAngle()) From a114c59fe7930c523f4503c0bd401ee7e0f8bac6 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 17 Sep 2020 16:09:59 -0700 Subject: [PATCH 041/115] update angle binaries. --- samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj index 28b0257eda..6b3e3a5f61 100644 --- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj +++ b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj @@ -13,7 +13,7 @@ - + From d3700adb560d295908c87231dc1b77ff973c4d7f Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 17 Sep 2020 16:23:40 -0700 Subject: [PATCH 042/115] setup the acrylic blur in a way it can be show or hidden. --- .../Avalonia.Win32/Composition/CompositionHost.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 8da205fdc6..958959bc93 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -76,7 +76,15 @@ namespace Avalonia.Win32 visual.Brush = brush; visual.Offset = new System.Numerics.Vector3(0, 0, 0); - target.Root = CreateBlur(); + + var container = _compositor.CreateContainerVisual(); + container.RelativeSizeAdjustment = new System.Numerics.Vector2(1, 1); + + target.Root = container; + + var blur = CreateBlur(); + + container.Children.InsertAtTop(blur); var visuals = target.Root.As().Children; From e00aa6e5ded72e32e356793c38bb68daeb2f127c Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 17 Sep 2020 17:30:13 -0700 Subject: [PATCH 043/115] iscorrupted no longer useful. --- .../Composition/CompositionEglGlPlatformSurface.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index 701070a6b5..96646b9590 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -35,7 +35,7 @@ namespace Avalonia.Win32 { private readonly EglDisplay _display; private readonly IEglWindowGlPlatformSurfaceInfo _info; - private PixelSize _initialSize; + private readonly PixelSize _initialSize; private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; private static Guid s_Iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); private Windows.UI.Composition.Visual _compositionVisual; @@ -56,7 +56,7 @@ namespace Avalonia.Win32 _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); } - public override bool IsCorrupted => _initialSize != _info.Size; + public override bool IsCorrupted => false; public override IGlPlatformSurfaceRenderingSession BeginDraw() { var offset = new POINT(); From 6bcf36e23fc61353406ee1dcb6009fe8cba6aa65 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 01:36:17 -0700 Subject: [PATCH 044/115] windows.ui.composition compatible with acrylic blur setting. --- .../CompositionEglGlPlatformSurface.cs | 8 +- .../Composition/CompositionHost.cs | 24 +++++- src/Windows/Avalonia.Win32/WindowImpl.cs | 84 +++++++++++-------- 3 files changed, 75 insertions(+), 41 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index 96646b9590..38ea545957 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -6,7 +6,7 @@ using Windows.UI.Composition.Interop; namespace Avalonia.Win32 { - public class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase + internal class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase { private readonly EglDisplay _display; private readonly EglContext _context; @@ -21,9 +21,11 @@ namespace Avalonia.Win32 _info = info; } - public void AttachToCompositionTree(IntPtr hwnd) + public IBlurHost AttachToCompositionTree(IntPtr hwnd) { - _surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd, out _surface); + _surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd, out _surface, out var blurHost); + + return blurHost; } public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 958959bc93..dfcf6e1d7f 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -7,6 +7,26 @@ using WinRT; namespace Avalonia.Win32 { + internal interface IBlurHost + { + void SetBlur(bool enabled); + } + + internal class CompositionBlurHost : IBlurHost + { + Windows.UI.Composition.Visual _blurVisual; + + public CompositionBlurHost(Windows.UI.Composition.Visual blurVisual) + { + _blurVisual = blurVisual; + } + + public void SetBlur(bool enabled) + { + _blurVisual.IsVisible = enabled; + } + } + class CompositionHost { internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE @@ -61,7 +81,7 @@ namespace Avalonia.Win32 _graphicsDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); } - public ICompositionDrawingSurfaceInterop InitialiseWindowCompositionTree(IntPtr hwnd, out Windows.UI.Composition.Visual surfaceVisual) + public ICompositionDrawingSurfaceInterop InitialiseWindowCompositionTree(IntPtr hwnd, out Windows.UI.Composition.Visual surfaceVisual, out IBlurHost blurHost) { var target = CreateDesktopWindowTarget(hwnd); @@ -84,6 +104,8 @@ namespace Avalonia.Win32 var blur = CreateBlur(); + blurHost = new CompositionBlurHost(blur); + container.Children.InsertAtTop(blur); var visuals = target.Root.As().Children; diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index a2bd7f57b9..46c18dea68 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -47,6 +47,7 @@ namespace Avalonia.Win32 private Thickness _offScreenMargin; private double _extendTitleBarHint = -1; private bool _isUsingComposition; + private IBlurHost _blurHost; #if USE_MANAGED_DRAG private readonly ManagedWindowResizeDragHelper _managedDrag; @@ -114,7 +115,7 @@ namespace Avalonia.Win32 if (_isUsingComposition) { var cgl = new CompositionEglGlPlatformSurface(Win32GlManager.EglFeature.DeferredContext, this); - cgl.AttachToCompositionTree(_hwnd); + _blurHost = cgl.AttachToCompositionTree(_hwnd); _gl = cgl; @@ -341,54 +342,63 @@ namespace Avalonia.Win32 private WindowTransparencyLevel Win10EnableBlur(WindowTransparencyLevel transparencyLevel) { - bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || Win32Platform.WindowsVersion.Build >= 19628; - - var accent = new AccentPolicy(); - var accentStructSize = Marshal.SizeOf(accent); - - if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur && !canUseAcrylic) + if (_isUsingComposition) { - transparencyLevel = WindowTransparencyLevel.Blur; - } + _blurHost?.SetBlur(transparencyLevel >= WindowTransparencyLevel.Blur); - switch (transparencyLevel) + return transparencyLevel; + } + else { - default: - case WindowTransparencyLevel.None: - accent.AccentState = AccentState.ACCENT_DISABLED; - break; + bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || Win32Platform.WindowsVersion.Build >= 19628; - case WindowTransparencyLevel.Transparent: - accent.AccentState = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT; - break; + var accent = new AccentPolicy(); + var accentStructSize = Marshal.SizeOf(accent); - case WindowTransparencyLevel.Blur: - accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; - break; + if (transparencyLevel == WindowTransparencyLevel.AcrylicBlur && !canUseAcrylic) + { + transparencyLevel = WindowTransparencyLevel.Blur; + } - case WindowTransparencyLevel.AcrylicBlur: - case (WindowTransparencyLevel.AcrylicBlur + 1): // hack-force acrylic. - accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC; - transparencyLevel = WindowTransparencyLevel.AcrylicBlur; - break; - } + switch (transparencyLevel) + { + default: + case WindowTransparencyLevel.None: + accent.AccentState = AccentState.ACCENT_DISABLED; + break; + + case WindowTransparencyLevel.Transparent: + accent.AccentState = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT; + break; + + case WindowTransparencyLevel.Blur: + accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; + break; + + case WindowTransparencyLevel.AcrylicBlur: + case (WindowTransparencyLevel.AcrylicBlur + 1): // hack-force acrylic. + accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC; + transparencyLevel = WindowTransparencyLevel.AcrylicBlur; + break; + } - accent.AccentFlags = 2; - accent.GradientColor = 0x01000000; + accent.AccentFlags = 2; + accent.GradientColor = 0x01000000; - var accentPtr = Marshal.AllocHGlobal(accentStructSize); - Marshal.StructureToPtr(accent, accentPtr, false); + var accentPtr = Marshal.AllocHGlobal(accentStructSize); + Marshal.StructureToPtr(accent, accentPtr, false); - var data = new WindowCompositionAttributeData(); - data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; - data.SizeOfData = accentStructSize; - data.Data = accentPtr; + var data = new WindowCompositionAttributeData(); + data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; + data.SizeOfData = accentStructSize; + data.Data = accentPtr; - SetWindowCompositionAttribute(_hwnd, ref data); + SetWindowCompositionAttribute(_hwnd, ref data); - Marshal.FreeHGlobal(accentPtr); + Marshal.FreeHGlobal(accentPtr); - return transparencyLevel; + return transparencyLevel; + } } public IEnumerable Surfaces => new object[] { Handle, _gl, _framebuffer }; From 8fa906281fa2b175247bd39db8b8b33acab8ee1f Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 01:39:49 -0700 Subject: [PATCH 045/115] zero bitmap memory, not transparent white. --- src/Avalonia.Visuals/Rendering/RenderLayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Rendering/RenderLayer.cs b/src/Avalonia.Visuals/Rendering/RenderLayer.cs index ddf5f4e5cf..668e9167dc 100644 --- a/src/Avalonia.Visuals/Rendering/RenderLayer.cs +++ b/src/Avalonia.Visuals/Rendering/RenderLayer.cs @@ -35,7 +35,7 @@ namespace Avalonia.Rendering using (var context = resized.Item.CreateDrawingContext(null)) { - context.Clear(Colors.Transparent); + context.Clear(default); Bitmap = resized; Scaling = scaling; From 274e76fec9211b016d53750cc202835549adbf1c Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 01:49:48 -0700 Subject: [PATCH 046/115] dispose current bitmap whilst context is current. --- src/Avalonia.Visuals/Rendering/RenderLayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Rendering/RenderLayer.cs b/src/Avalonia.Visuals/Rendering/RenderLayer.cs index 668e9167dc..1fbd8c02c0 100644 --- a/src/Avalonia.Visuals/Rendering/RenderLayer.cs +++ b/src/Avalonia.Visuals/Rendering/RenderLayer.cs @@ -30,11 +30,11 @@ namespace Avalonia.Rendering { if (Size != size || Scaling != scaling) { - Bitmap.Dispose(); var resized = RefCountable.Create(drawingContext.CreateLayer(size)); using (var context = resized.Item.CreateDrawingContext(null)) { + Bitmap.Dispose(); context.Clear(default); Bitmap = resized; From 7f9b675efbe154439a956504464883fffae7bbd5 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 03:11:42 -0700 Subject: [PATCH 047/115] refactor effects. --- .../Composition/CompositionHost.cs | 18 ++++++-- .../Avalonia.Win32/Composition/EffectBase.cs | 45 +++++++++++++++++++ .../Composition/GaussianBlurEffect.cs | 42 +++++------------ .../Composition/SaturationEffect.cs | 35 +++++++++++++++ 4 files changed, 104 insertions(+), 36 deletions(-) create mode 100644 src/Windows/Avalonia.Win32/Composition/EffectBase.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/SaturationEffect.cs diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index dfcf6e1d7f..f1cf5af0e8 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -121,18 +121,28 @@ namespace Avalonia.Win32 public SpriteVisual CreateBlur() { - var effect = new GaussianBlurEffect(); - var effectFactory = _compositor.CreateEffectFactory(effect); - var blurBrush = effectFactory.CreateBrush(); + var blurEffect = new GaussianBlurEffect(new CompositionEffectSourceParameter ("backdrop")); + var blurEffectFactory = _compositor.CreateEffectFactory(blurEffect); + var blurBrush = blurEffectFactory.CreateBrush(); var backDropBrush = _compositor.CreateBackdropBrush(); blurBrush.SetSourceParameter("backdrop", backDropBrush); + + var saturateEffect = new SaturationEffect(blurEffect); + var satEffectFactory = _compositor.CreateEffectFactory(saturateEffect); + + + var satBrush = satEffectFactory.CreateBrush(); + satBrush.SetSourceParameter("backdrop", backDropBrush); + + + var visual = _compositor.CreateSpriteVisual(); visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); - visual.Brush = blurBrush; + visual.Brush = satBrush; return visual; } diff --git a/src/Windows/Avalonia.Win32/Composition/EffectBase.cs b/src/Windows/Avalonia.Win32/Composition/EffectBase.cs new file mode 100644 index 0000000000..ca5b15971e --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/EffectBase.cs @@ -0,0 +1,45 @@ +using System; +using Windows.Graphics.Effects; +using Windows.Graphics.Effects.Interop; + + +namespace Avalonia.Win32 +{ + abstract class EffectBase : IGraphicsEffect, IGraphicsEffectSource, global::Windows.Graphics.Effects.Interop.IGraphicsEffectD2D1Interop + { + private IGraphicsEffectSource[] _sources; + + public EffectBase(params IGraphicsEffectSource[] sources) + { + _sources = sources; + } + + private IGraphicsEffectSource _source; + + public virtual string Name { get; set; } + + public abstract Guid EffectId { get; } + + public abstract uint PropertyCount { get; } + + public uint SourceCount => (uint)_sources.Length; + + public IGraphicsEffectSource GetSource(uint index) + { + if(index < _sources.Length) + { + return _sources[index]; + } + + return null; + } + + public uint GetNamedPropertyMapping(string name, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + throw new NotImplementedException(); + } + + public abstract object GetProperty(uint index); + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs b/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs index 4e1be3af1a..342e68eeb4 100644 --- a/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs +++ b/src/Windows/Avalonia.Win32/Composition/GaussianBlurEffect.cs @@ -1,13 +1,14 @@ using System; using Windows.Graphics.Effects; -using Windows.Graphics.Effects.Interop; -using Windows.UI.Composition; - namespace Avalonia.Win32 { - class GaussianBlurEffect : IGraphicsEffect, IGraphicsEffectSource, global::Windows.Graphics.Effects.Interop.IGraphicsEffectD2D1Interop + class GaussianBlurEffect : EffectBase { + public GaussianBlurEffect(IGraphicsEffectSource source) : base(source) + { + } + enum D2D1_GAUSSIANBLUR_OPTIMIZATION { D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED, @@ -31,20 +32,11 @@ namespace Avalonia.Win32 D2D1_GAUSSIANBLUR_PROP_FORCE_DWORD }; - public string Name { get; set; } - - public Guid EffectId => D2DEffects.CLSID_D2D1GaussianBlur; + public override Guid EffectId => D2DEffects.CLSID_D2D1GaussianBlur; - public uint PropertyCount => 3; - - public uint SourceCount => 1; - - public uint GetNamedPropertyMapping(string name, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) - { - throw new NotImplementedException(); - } + public override uint PropertyCount => 3; - public object GetProperty(uint index) + public override object GetProperty(uint index) { switch ((D2D1GaussianBlurProp)index) { @@ -52,28 +44,14 @@ namespace Avalonia.Win32 return 30.0f; case D2D1GaussianBlurProp.D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION: - return (UInt32)D2D1_GAUSSIANBLUR_OPTIMIZATION.D2D1_GAUSSIANBLUR_OPTIMIZATION_BALANCED; + return (uint)D2D1_GAUSSIANBLUR_OPTIMIZATION.D2D1_GAUSSIANBLUR_OPTIMIZATION_BALANCED; case D2D1GaussianBlurProp.D2D1_GAUSSIANBLUR_PROP_BORDER_MODE: - return (UInt32)D2D1_BORDER_MODE.D2D1_BORDER_MODE_HARD; + return (uint)D2D1_BORDER_MODE.D2D1_BORDER_MODE_HARD; } return null; } - - private IGraphicsEffectSource _source = new CompositionEffectSourceParameter("backdrop"); - - public IGraphicsEffectSource GetSource(uint index) - { - if (index == 0) - { - return _source; - } - else - { - return null; - } - } } } diff --git a/src/Windows/Avalonia.Win32/Composition/SaturationEffect.cs b/src/Windows/Avalonia.Win32/Composition/SaturationEffect.cs new file mode 100644 index 0000000000..90eca22d8e --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/SaturationEffect.cs @@ -0,0 +1,35 @@ +using System; +using Windows.Graphics.Effects; + + +namespace Avalonia.Win32 +{ + class SaturationEffect : EffectBase + { + public SaturationEffect(IGraphicsEffect source) : base(source) + { + } + + enum D2D1_SATURATION_PROP + { + D2D1_SATURATION_PROP_SATURATION, + D2D1_SATURATION_PROP_FORCE_DWORD + }; + + public override Guid EffectId => D2DEffects.CLSID_D2D1Saturation; + + public override uint PropertyCount => 1; + + public override object GetProperty(uint index) + { + switch ((D2D1_SATURATION_PROP)index) + { + case D2D1_SATURATION_PROP.D2D1_SATURATION_PROP_SATURATION: + return 2.0f; + } + + return null; + } + } +} + From 57b3f0b10574a167a448ad4401b6de88c1563354 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 03:21:04 -0700 Subject: [PATCH 048/115] revert changed code. --- .../ControlCatalog.NetCore/Properties/launchSettings.json | 8 -------- samples/ControlCatalog/MainWindow.xaml | 8 ++++++-- 2 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 samples/ControlCatalog.NetCore/Properties/launchSettings.json diff --git a/samples/ControlCatalog.NetCore/Properties/launchSettings.json b/samples/ControlCatalog.NetCore/Properties/launchSettings.json deleted file mode 100644 index cd8a2c824b..0000000000 --- a/samples/ControlCatalog.NetCore/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "ControlCatalog.NetCore": { - "commandName": "Project", - "nativeDebugging": true - } - } -} \ No newline at end of file diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml index eebc804a64..97bd88f5e4 100644 --- a/samples/ControlCatalog/MainWindow.xaml +++ b/samples/ControlCatalog/MainWindow.xaml @@ -7,8 +7,12 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:ControlCatalog.ViewModels" xmlns:v="clr-namespace:ControlCatalog.Views" - TransparencyLevelHint="Transparent" - x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}" Background="{x:Null}"> + ExtendClientAreaToDecorationsHint="{Binding ExtendClientAreaEnabled}" + ExtendClientAreaChromeHints="{Binding ChromeHints}" + ExtendClientAreaTitleBarHeightHint="{Binding TitleBarHeight}" + TransparencyLevelHint="{Binding TransparencyLevel}" + x:Name="MainWindow" + x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}"> From 4d0c27dc8f8da04be98b690a8406df2d86a9f49a Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 03:32:43 -0700 Subject: [PATCH 049/115] whitespace. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 46c18dea68..9c002038cb 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -717,7 +717,7 @@ namespace Avalonia.Win32 { _scaling = dpix / 96.0; } - } + } } private void CreateDropTarget() From 28168d571be4912cb85d87629fba798ae5fd3b09 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 10:06:19 -0700 Subject: [PATCH 050/115] make managed deferredrenderer lock global. --- src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs | 6 +++--- src/Windows/Avalonia.Win32/WindowImpl.cs | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs index 25a34561fc..0bab0d1657 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs @@ -339,7 +339,7 @@ namespace Avalonia.Win32 case WindowsMessage.WM_PAINT: { - using (_rendererLock.Lock()) + using (s_rendererLock.Lock()) { if (BeginPaint(_hwnd, out PAINTSTRUCT ps) != IntPtr.Zero) { @@ -356,7 +356,7 @@ namespace Avalonia.Win32 case WindowsMessage.WM_SIZE: { - using (_rendererLock.Lock()) + using (s_rendererLock.Lock()) { // Do nothing here, just block until the pending frame render is completed on the render thread } @@ -464,7 +464,7 @@ namespace Avalonia.Win32 } } - using (_rendererLock.Lock()) + using (s_rendererLock.Lock()) { return DefWindowProc(hWnd, msg, wParam, lParam); } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 9c002038cb..7b8b6d3e83 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -56,7 +56,7 @@ namespace Avalonia.Win32 private const WindowStyles WindowStateMask = (WindowStyles.WS_MAXIMIZE | WindowStyles.WS_MINIMIZE); private readonly TouchDevice _touchDevice; private readonly MouseDevice _mouseDevice; - private readonly ManagedDeferredRendererLock _rendererLock; + private static readonly ManagedDeferredRendererLock s_rendererLock = new ManagedDeferredRendererLock(); private readonly FramebufferManager _framebuffer; private readonly IGlPlatformSurface _gl; @@ -100,7 +100,6 @@ namespace Avalonia.Win32 IsResizable = true, Decorations = SystemDecorations.Full }; - _rendererLock = new ManagedDeferredRendererLock(); _isUsingComposition = Win32Platform.Options.UseWindowsUIComposition && Win32Platform.WindowsVersion.Major >= 10 && Win32Platform.WindowsVersion.Build >= 16299 && @@ -443,7 +442,7 @@ namespace Avalonia.Win32 return customRendererFactory.Create(root, loop); return Win32Platform.UseDeferredRendering ? - (IRenderer)new DeferredRenderer(root, loop, rendererLock: _rendererLock) : + (IRenderer)new DeferredRenderer(root, loop, rendererLock: s_rendererLock) : new ImmediateRenderer(root); } From 7720d8f9062c220e05b2c40183694defccccb616 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 10:42:39 -0700 Subject: [PATCH 051/115] fix visual tree so that content resizes with the window. --- .../Composition/CompositionEglGlPlatformSurface.cs | 3 ++- .../Avalonia.Win32/Composition/CompositionHost.cs | 11 ++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index 38ea545957..4e6dc79673 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -58,7 +58,8 @@ namespace Avalonia.Win32 _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); } - public override bool IsCorrupted => false; + public override bool IsCorrupted => _info.Size != _initialSize; + public override IGlPlatformSurfaceRenderingSession BeginDraw() { var offset = new POINT(); diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index f1cf5af0e8..615b5d303a 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -95,11 +95,10 @@ namespace Avalonia.Win32 var visual = _compositor.CreateSpriteVisual(); visual.Brush = brush; - visual.Offset = new System.Numerics.Vector3(0, 0, 0); + visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1, 1); var container = _compositor.CreateContainerVisual(); - container.RelativeSizeAdjustment = new System.Numerics.Vector2(1, 1); - + target.Root = container; var blur = CreateBlur(); @@ -108,13 +107,11 @@ namespace Avalonia.Win32 container.Children.InsertAtTop(blur); - var visuals = target.Root.As().Children; - - visuals.InsertAtTop(visual); + container.Children.InsertAtTop(visual); visual.CompositeMode = CompositionCompositeMode.SourceOver; - surfaceVisual = visual; + surfaceVisual = container; return surfaceInterop; } From a004366e70c0e8b7dead53f092bc261246597a4d Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 10:50:27 -0700 Subject: [PATCH 052/115] make blur not visible at startup. --- src/Windows/Avalonia.Win32/Composition/CompositionHost.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 615b5d303a..516ad44071 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -126,17 +126,14 @@ namespace Avalonia.Win32 blurBrush.SetSourceParameter("backdrop", backDropBrush); - var saturateEffect = new SaturationEffect(blurEffect); var satEffectFactory = _compositor.CreateEffectFactory(saturateEffect); - var satBrush = satEffectFactory.CreateBrush(); satBrush.SetSourceParameter("backdrop", backDropBrush); - - var visual = _compositor.CreateSpriteVisual(); + visual.IsVisible = false; visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); visual.Brush = satBrush; From 099909d4e286a9820e8a34b9b793979c4b827e77 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 10:55:07 -0700 Subject: [PATCH 053/115] make win.ui.comp the default when running on win10 and compatible gpu is used. --- samples/ControlCatalog.NetCore/Program.cs | 3 +-- src/Windows/Avalonia.Win32/Win32Platform.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index 9b62c2c98e..d967fde34c 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -117,8 +117,7 @@ namespace ControlCatalog.NetCore .With(new Win32PlatformOptions { EnableMultitouch = true, - AllowEglInitialization = true, - UseWindowsUIComposition = true + AllowEglInitialization = true }) .UseSkia() .UseReactiveUI() diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 7f1ac443ad..e9d34d7d56 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -47,7 +47,7 @@ namespace Avalonia /// Supported on Windows 10 build 16299 and above. Ignored on other versions. /// This is recommended if you need to use AcrylicBlur or acrylic in your applications. /// - public bool UseWindowsUIComposition { get; set; } + public bool UseWindowsUIComposition { get; set; } = true; } } From 59d68a30370694203a4647399cddc81542c09c92 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 10:57:45 -0700 Subject: [PATCH 054/115] remove usings. --- samples/ControlCatalog.NetCore/Program.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index d967fde34c..3851cbf9a6 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -7,13 +7,11 @@ using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Dialogs; using Avalonia.Headless; using Avalonia.LogicalTree; -using Avalonia.Skia; using Avalonia.ReactiveUI; using Avalonia.Threading; -using Avalonia.Dialogs; -using Avalonia.OpenGL; namespace ControlCatalog.NetCore { From 02f33d561c21439849838cce4587f27b5560122e Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 10:59:16 -0700 Subject: [PATCH 055/115] 1 file per class. --- .../Composition/CompositionBlurHost.cs | 18 +++++++++++++++++ .../Composition/CompositionHost.cs | 20 ------------------- .../Avalonia.Win32/Composition/IBlurHost.cs | 8 ++++++++ 3 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 src/Windows/Avalonia.Win32/Composition/CompositionBlurHost.cs create mode 100644 src/Windows/Avalonia.Win32/Composition/IBlurHost.cs diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionBlurHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionBlurHost.cs new file mode 100644 index 0000000000..4c090e797c --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/CompositionBlurHost.cs @@ -0,0 +1,18 @@ +namespace Avalonia.Win32 +{ + internal class CompositionBlurHost : IBlurHost + { + Windows.UI.Composition.Visual _blurVisual; + + public CompositionBlurHost(Windows.UI.Composition.Visual blurVisual) + { + _blurVisual = blurVisual; + } + + public void SetBlur(bool enabled) + { + _blurVisual.IsVisible = enabled; + } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 516ad44071..07a0170810 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -7,26 +7,6 @@ using WinRT; namespace Avalonia.Win32 { - internal interface IBlurHost - { - void SetBlur(bool enabled); - } - - internal class CompositionBlurHost : IBlurHost - { - Windows.UI.Composition.Visual _blurVisual; - - public CompositionBlurHost(Windows.UI.Composition.Visual blurVisual) - { - _blurVisual = blurVisual; - } - - public void SetBlur(bool enabled) - { - _blurVisual.IsVisible = enabled; - } - } - class CompositionHost { internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE diff --git a/src/Windows/Avalonia.Win32/Composition/IBlurHost.cs b/src/Windows/Avalonia.Win32/Composition/IBlurHost.cs new file mode 100644 index 0000000000..6ab470d81c --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/IBlurHost.cs @@ -0,0 +1,8 @@ +namespace Avalonia.Win32 +{ + internal interface IBlurHost + { + void SetBlur(bool enabled); + } +} + From 3541e70c3b4c822ca8a082c76c45efaae752d37d Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 11:50:45 -0700 Subject: [PATCH 056/115] fix hostapp for designer. --- .../Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj index 51d18e55d1..152581de27 100644 --- a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj +++ b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj @@ -23,5 +23,8 @@ + + + From 8c667faf64f9adf0829929a2a70a9e9247a3d931 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 18 Sep 2020 13:37:16 -0700 Subject: [PATCH 057/115] use stable Angle. --- samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj | 2 +- samples/interop/NativeEmbedSample/NativeEmbedSample.csproj | 2 +- src/Windows/Avalonia.Win32/Avalonia.Win32.csproj | 2 +- .../Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj index 6b3e3a5f61..d4d50163d5 100644 --- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj +++ b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj @@ -13,7 +13,7 @@ - + diff --git a/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj b/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj index cc831ef8ae..abdcac3b77 100644 --- a/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj +++ b/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj @@ -13,7 +13,7 @@ - + Designer diff --git a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj index c6af049868..5889d919df 100644 --- a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj +++ b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj index 152581de27..a2d27fd579 100644 --- a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj +++ b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj @@ -24,7 +24,7 @@ - + From 10206e728dacd64f4b754965ad6555ee6ac6a6bc Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 27 Sep 2020 21:26:25 +0100 Subject: [PATCH 058/115] Revert "make managed deferredrenderer lock global." This reverts commit 28168d571be4912cb85d87629fba798ae5fd3b09. --- src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs | 6 +++--- src/Windows/Avalonia.Win32/WindowImpl.cs | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs index 0bab0d1657..25a34561fc 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs @@ -339,7 +339,7 @@ namespace Avalonia.Win32 case WindowsMessage.WM_PAINT: { - using (s_rendererLock.Lock()) + using (_rendererLock.Lock()) { if (BeginPaint(_hwnd, out PAINTSTRUCT ps) != IntPtr.Zero) { @@ -356,7 +356,7 @@ namespace Avalonia.Win32 case WindowsMessage.WM_SIZE: { - using (s_rendererLock.Lock()) + using (_rendererLock.Lock()) { // Do nothing here, just block until the pending frame render is completed on the render thread } @@ -464,7 +464,7 @@ namespace Avalonia.Win32 } } - using (s_rendererLock.Lock()) + using (_rendererLock.Lock()) { return DefWindowProc(hWnd, msg, wParam, lParam); } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 6ca12e571f..848635fe23 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -58,7 +58,7 @@ namespace Avalonia.Win32 private const WindowStyles WindowStateMask = (WindowStyles.WS_MAXIMIZE | WindowStyles.WS_MINIMIZE); private readonly TouchDevice _touchDevice; private readonly MouseDevice _mouseDevice; - private static readonly ManagedDeferredRendererLock s_rendererLock = new ManagedDeferredRendererLock(); + private readonly ManagedDeferredRendererLock _rendererLock; private readonly FramebufferManager _framebuffer; private readonly IGlPlatformSurface _gl; @@ -102,6 +102,7 @@ namespace Avalonia.Win32 IsResizable = true, Decorations = SystemDecorations.Full }; + _rendererLock = new ManagedDeferredRendererLock(); _isUsingComposition = Win32Platform.Options.UseWindowsUIComposition && Win32Platform.WindowsVersion.Major >= 10 && Win32Platform.WindowsVersion.Build >= 16299 && @@ -445,7 +446,7 @@ namespace Avalonia.Win32 return customRendererFactory.Create(root, loop); return Win32Platform.UseDeferredRendering ? - (IRenderer)new DeferredRenderer(root, loop, rendererLock: s_rendererLock) : + (IRenderer)new DeferredRenderer(root, loop, rendererLock: _rendererLock) : new ImmediateRenderer(root); } From 05f7ee83af016d4f6f10b9294e270299295596e9 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 29 Sep 2020 18:23:19 +0100 Subject: [PATCH 059/115] fix resizing of composition surface. --- .../Composition/CompositionEglGlPlatformSurface.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index c034d8f7f7..2e4b69c0b5 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -39,7 +39,7 @@ namespace Avalonia.Win32 { private readonly EglPlatformOpenGlInterface _egl; private readonly IEglWindowGlPlatformSurfaceInfo _info; - private readonly PixelSize _initialSize; + private PixelSize _currentSize; private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; private static Guid s_Iid = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); private Windows.UI.Composition.Visual _compositionVisual; @@ -53,7 +53,7 @@ namespace Avalonia.Win32 _egl = egl; _surfaceInterop = interopSurface; _info = info; - _initialSize = info.Size; + _currentSize = info.Size; _compositionVisual = compositionVisual; _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); @@ -61,6 +61,13 @@ namespace Avalonia.Win32 public override IGlPlatformSurfaceRenderingSession BeginDraw() { + if (_info.Size != _currentSize) + { + _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); + _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); + _currentSize = _info.Size; + } + var offset = new POINT(); _surfaceInterop.BeginDraw( From b5c5cc7192b8298c6136f331e3256a58a778256b Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 2 Oct 2020 20:27:21 +0100 Subject: [PATCH 060/115] protect d3d calls. --- .../CompositionEglGlPlatformSurface.cs | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index 2e4b69c0b5..b30043fedd 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -25,9 +25,11 @@ namespace Avalonia.Win32 public IBlurHost AttachToCompositionTree(IntPtr hwnd) { - _surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd, out _surface, out var blurHost); - - return blurHost; + using (_egl.PrimaryContext.MakeCurrent()) + { + _surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd, out _surface, out var blurHost); + return blurHost; + } } public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() @@ -55,27 +57,38 @@ namespace Avalonia.Win32 _info = info; _currentSize = info.Size; _compositionVisual = compositionVisual; - _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); + + using (_egl.PrimaryContext.MakeCurrent()) + { + _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); + } + _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); } public override IGlPlatformSurfaceRenderingSession BeginDraw() { - if (_info.Size != _currentSize) + IntPtr texture; + EglSurface surface; + + using (_egl.PrimaryEglContext.EnsureCurrent()) { - _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); - _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); - _currentSize = _info.Size; - } + if (_info.Size != _currentSize) + { + _surfaceInterop.Resize(new POINT { X = _info.Size.Width, Y = _info.Size.Height }); + _compositionVisual.Size = new System.Numerics.Vector2(_info.Size.Width, _info.Size.Height); + _currentSize = _info.Size; + } - var offset = new POINT(); + var offset = new POINT(); - _surfaceInterop.BeginDraw( - IntPtr.Zero, - ref s_Iid, - out IntPtr texture, ref offset); + _surfaceInterop.BeginDraw( + IntPtr.Zero, + ref s_Iid, + out texture, ref offset); - var surface = (_egl.Display as AngleWin32EglDisplay).WrapDirect3D11Texture(_egl, texture, offset.X, offset.Y, _info.Size.Width, _info.Size.Height); + surface = (_egl.Display as AngleWin32EglDisplay).WrapDirect3D11Texture(_egl, texture, offset.X, offset.Y, _info.Size.Width, _info.Size.Height); + } return base.BeginDraw(surface, _info, () => { _surfaceInterop.EndDraw(); Marshal.Release(texture); surface.Dispose(); }, true); } From ddd3dfa0a70ef98b9797fae4d1d1d17e2aa1cf00 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 8 Oct 2020 22:18:41 +0100 Subject: [PATCH 061/115] change surface origin. --- src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs index 9ee8d698ba..24464c39d9 100644 --- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs +++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs @@ -93,7 +93,7 @@ namespace Avalonia.Skia var target = new GRBackendRenderTarget(pixelSize.Width, pixelSize.Height, 0, 8, new GRGlFramebufferInfo((uint)_fbo, SKColorType.Rgba8888.ToGlSizedFormat())); Surface = SKSurface.Create(_grContext, target, - GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888); + GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888); CanBlit = gl.BlitFramebuffer != null; } From 8fddd4b94e19f3434868bd3367e83a6914a7b0cf Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 8 Oct 2020 22:51:48 +0100 Subject: [PATCH 062/115] remove unused var. --- .../Composition/CompositionEglGlPlatformSurface.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index b30043fedd..547e2d3c0e 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -10,15 +10,13 @@ namespace Avalonia.Win32 { internal class CompositionEglGlPlatformSurface : EglGlPlatformSurfaceBase { - private readonly EglDisplay _display; private EglPlatformOpenGlInterface _egl; private readonly IEglWindowGlPlatformSurfaceInfo _info; private ICompositionDrawingSurfaceInterop _surfaceInterop; - private Windows.UI.Composition.Visual _surface; + private Windows.UI.Composition.Visual _surface; public CompositionEglGlPlatformSurface(EglPlatformOpenGlInterface egl, IEglWindowGlPlatformSurfaceInfo info) : base() - { - _display = egl.Display; + { _egl = egl; _info = info; } From 7b0598559a1307ebf2eab4da53e11d05884582ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20Komosi=C5=84ski?= Date: Tue, 6 Oct 2020 12:06:01 +0200 Subject: [PATCH 063/115] GeometryDrawing does not need to allocate new Pen for each GetBounds call. --- src/Avalonia.Visuals/ApiCompatBaseline.txt | 4 +++- src/Avalonia.Visuals/Media/Geometry.cs | 4 ++-- src/Avalonia.Visuals/Media/GeometryDrawing.cs | 10 ++++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Avalonia.Visuals/ApiCompatBaseline.txt b/src/Avalonia.Visuals/ApiCompatBaseline.txt index 7fb44152c9..2d00d82a46 100644 --- a/src/Avalonia.Visuals/ApiCompatBaseline.txt +++ b/src/Avalonia.Visuals/ApiCompatBaseline.txt @@ -2,6 +2,8 @@ Compat issues with assembly Avalonia.Visuals: MembersMustExist : Member 'public void Avalonia.Media.DrawingContext.DrawGlyphRun(Avalonia.Media.IBrush, Avalonia.Media.GlyphRun, Avalonia.Point)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public Avalonia.Media.Typeface Avalonia.Media.FontManager.GetOrAddTypeface(Avalonia.Media.FontFamily, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public Avalonia.Media.Typeface Avalonia.Media.FontManager.MatchCharacter(System.Int32, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight, Avalonia.Media.FontFamily, System.Globalization.CultureInfo)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'public Avalonia.Rect Avalonia.Media.Geometry.GetRenderBounds(Avalonia.Media.Pen)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'public System.Boolean Avalonia.Media.Geometry.StrokeContains(Avalonia.Media.Pen, Avalonia.Point)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public Avalonia.Rect Avalonia.Media.GlyphRun.Bounds.get()' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public Avalonia.StyledProperty Avalonia.StyledProperty Avalonia.Media.GlyphRunDrawing.BaselineOriginProperty' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public Avalonia.Point Avalonia.Media.GlyphRunDrawing.BaselineOrigin.get()' does not exist in the implementation but it does exist in the contract. @@ -34,4 +36,4 @@ InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalon MembersMustExist : Member 'public System.Boolean Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight, Avalonia.Media.FontFamily, System.Globalization.CultureInfo, Avalonia.Media.Fonts.FontKey)' does not exist in the implementation but it does exist in the contract. InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight, Avalonia.Media.FontFamily, System.Globalization.CultureInfo, Avalonia.Media.Typeface)' is present in the implementation but not in the contract. MembersMustExist : Member 'public Avalonia.Utilities.IRef Avalonia.Rendering.RenderLayer.Bitmap.get()' does not exist in the implementation but it does exist in the contract. -Total Issues: 35 +Total Issues: 37 diff --git a/src/Avalonia.Visuals/Media/Geometry.cs b/src/Avalonia.Visuals/Media/Geometry.cs index 33aafb58fc..ccef6665a9 100644 --- a/src/Avalonia.Visuals/Media/Geometry.cs +++ b/src/Avalonia.Visuals/Media/Geometry.cs @@ -84,7 +84,7 @@ namespace Avalonia.Media /// /// The stroke thickness. /// The bounding rectangle. - public Rect GetRenderBounds(Pen pen) => PlatformImpl?.GetRenderBounds(pen) ?? Rect.Empty; + public Rect GetRenderBounds(IPen pen) => PlatformImpl?.GetRenderBounds(pen) ?? Rect.Empty; /// /// Indicates whether the geometry's fill contains the specified point. @@ -102,7 +102,7 @@ namespace Avalonia.Media /// The pen to use. /// The point. /// true if the geometry contains the point; otherwise, false. - public bool StrokeContains(Pen pen, Point point) + public bool StrokeContains(IPen pen, Point point) { return PlatformImpl?.StrokeContains(pen, point) == true; } diff --git a/src/Avalonia.Visuals/Media/GeometryDrawing.cs b/src/Avalonia.Visuals/Media/GeometryDrawing.cs index 4df3aa8ae2..b5052550e6 100644 --- a/src/Avalonia.Visuals/Media/GeometryDrawing.cs +++ b/src/Avalonia.Visuals/Media/GeometryDrawing.cs @@ -1,9 +1,13 @@ -using Avalonia.Metadata; +using Avalonia.Media.Immutable; +using Avalonia.Metadata; namespace Avalonia.Media { public class GeometryDrawing : Drawing { + // Adding the Pen's stroke thickness here could yield wrong results due to transforms. + private static readonly IPen s_boundsPen = new ImmutablePen(Colors.Black.ToUint32(), 0); + public static readonly StyledProperty GeometryProperty = AvaloniaProperty.Register(nameof(Geometry)); @@ -42,9 +46,7 @@ namespace Avalonia.Media public override Rect GetBounds() { - // adding the Pen's stroke thickness here could yield wrong results due to transforms - var pen = new Pen(Brushes.Black, 0); - return Geometry?.GetRenderBounds(pen) ?? new Rect(); + return Geometry?.GetRenderBounds(s_boundsPen) ?? new Rect(); } } } From 13d2c286fdd6aef41624a5fffa4f0dcbbb85f7a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20Komosi=C5=84ski?= Date: Tue, 6 Oct 2020 12:22:41 +0200 Subject: [PATCH 064/115] Add doc comments and cleanup code a bit. --- src/Avalonia.Visuals/Media/Drawing.cs | 14 +++++-- src/Avalonia.Visuals/Media/GeometryDrawing.cs | 38 +++++++++++++++---- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/Avalonia.Visuals/Media/Drawing.cs b/src/Avalonia.Visuals/Media/Drawing.cs index 6bc808e407..66d05e7e48 100644 --- a/src/Avalonia.Visuals/Media/Drawing.cs +++ b/src/Avalonia.Visuals/Media/Drawing.cs @@ -1,11 +1,19 @@ -using Avalonia.Platform; - -namespace Avalonia.Media +namespace Avalonia.Media { + /// + /// Abstract class that describes a 2-D drawing. + /// public abstract class Drawing : AvaloniaObject { + /// + /// Draws this drawing to the given . + /// + /// The drawing context. public abstract void Draw(DrawingContext context); + /// + /// Gets the drawing's bounding rectangle. + /// public abstract Rect GetBounds(); } } diff --git a/src/Avalonia.Visuals/Media/GeometryDrawing.cs b/src/Avalonia.Visuals/Media/GeometryDrawing.cs index b5052550e6..e46e3a7d5f 100644 --- a/src/Avalonia.Visuals/Media/GeometryDrawing.cs +++ b/src/Avalonia.Visuals/Media/GeometryDrawing.cs @@ -3,14 +3,36 @@ using Avalonia.Metadata; namespace Avalonia.Media { + /// + /// Represents a drawing operation that combines + /// a geometry with and brush and/or pen to produce rendered content. + /// public class GeometryDrawing : Drawing { // Adding the Pen's stroke thickness here could yield wrong results due to transforms. private static readonly IPen s_boundsPen = new ImmutablePen(Colors.Black.ToUint32(), 0); - + + /// + /// Defines the property. + /// public static readonly StyledProperty GeometryProperty = AvaloniaProperty.Register(nameof(Geometry)); + /// + /// Defines the property. + /// + public static readonly StyledProperty BrushProperty = + AvaloniaProperty.Register(nameof(Brush), Brushes.Transparent); + + /// + /// Defines the property. + /// + public static readonly StyledProperty PenProperty = + AvaloniaProperty.Register(nameof(Pen)); + + /// + /// Gets or sets the that describes the shape of this . + /// [Content] public Geometry Geometry { @@ -18,18 +40,18 @@ namespace Avalonia.Media set => SetValue(GeometryProperty, value); } - public static readonly StyledProperty BrushProperty = - AvaloniaProperty.Register(nameof(Brush), Brushes.Transparent); - + /// + /// Gets or sets the used to fill the interior of the shape described by this . + /// public IBrush Brush { get => GetValue(BrushProperty); set => SetValue(BrushProperty, value); } - public static readonly StyledProperty PenProperty = - AvaloniaProperty.Register(nameof(Pen)); - + /// + /// Gets or sets the used to stroke this . + /// public IPen Pen { get => GetValue(PenProperty); @@ -46,7 +68,7 @@ namespace Avalonia.Media public override Rect GetBounds() { - return Geometry?.GetRenderBounds(s_boundsPen) ?? new Rect(); + return Geometry?.GetRenderBounds(s_boundsPen) ?? Rect.Empty; } } } From e4505ce861c85e117da11d6379489ac2c0c5fff2 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Mon, 12 Oct 2020 18:09:56 +0300 Subject: [PATCH 065/115] Strong name support --- build/SharedVersion.props | 2 ++ build/XUnit.props | 4 ++++ build/avalonia.snk | Bin 0 -> 596 bytes nukebuild/BuildTasksPatcher.cs | 3 ++- nukebuild/_build.csproj | 2 +- packages/Avalonia/AvaloniaBuildTasks.targets | 3 +++ src/Avalonia.Animation/Properties/AssemblyInfo.cs | 4 ++-- src/Avalonia.Base/Properties/AssemblyInfo.cs | 10 +++++----- .../Avalonia.Build.Tasks.csproj | 2 +- .../CompileAvaloniaXamlTask.cs | 8 +++++++- .../XamlCompilerTaskExecutor.cs | 12 +++++++----- .../Properties/AssemblyInfo.cs | 4 ++-- src/Avalonia.Controls/Properties/AssemblyInfo.cs | 4 ++-- .../Avalonia.FreeDesktop.csproj | 4 +--- src/Avalonia.Layout/Properties/AssemblyInfo.cs | 2 +- src/Avalonia.Styling/Properties/AssemblyInfo.cs | 2 +- src/Avalonia.Visuals/Properties/AssemblyInfo.cs | 8 ++++---- .../Properties/AssemblyInfo.cs | 2 +- .../Avalonia.Markup/Properties/AssemblyInfo.cs | 2 +- src/Skia/Avalonia.Skia/Properties/AssemblyInfo.cs | 4 ++-- .../Avalonia.Direct2D1/Properties/AssemblyInfo.cs | 4 ++-- .../Avalonia.UnitTests/Avalonia.UnitTests.csproj | 2 ++ 22 files changed, 53 insertions(+), 35 deletions(-) create mode 100644 build/avalonia.snk diff --git a/build/SharedVersion.props b/build/SharedVersion.props index d3cebef418..a909855ace 100644 --- a/build/SharedVersion.props +++ b/build/SharedVersion.props @@ -15,5 +15,7 @@ avalonia;avaloniaui;mvvm;rx;reactive extensions;android;ios;mac;forms;wpf;net;netstandard;net461;uwp;xamarin https://github.com/AvaloniaUI/Avalonia/releases git + $(MSBuildThisFileDirectory)\avalonia.snk + True diff --git a/build/XUnit.props b/build/XUnit.props index 079565d184..53f524b8e9 100644 --- a/build/XUnit.props +++ b/build/XUnit.props @@ -11,4 +11,8 @@ + + $(MSBuildThisFileDirectory)\avalonia.snk + True + diff --git a/build/avalonia.snk b/build/avalonia.snk new file mode 100644 index 0000000000000000000000000000000000000000..10b49deb317f66acbf94ac91c3fb4e1066b11943 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098OyP*^!h5iH?GHr0jVfXw1mKGrZq92J|(XpFp)DiBw-Z!BWY`Bn=-i(~@q( zFS=ks<7P~GaI50~9@dlKIFzd>EpCVBc8q@)iz81oG<|TKKgSo7;Jb+ILAUS8ye7lf z@B;^IqY`!iW+5Nz%~CJWE2-xq6i%7T`X=nQVOF!Yfg@pa9Q}co7VO77Md5xwZ8ias zJNxIB-(r{0doj`xP_m5qd-Nw0d@%}{UcaWW63g#RH(D=wP~kJH)|NIB$f38ZKz)1Y z-x(8Cxm8lS#Qm>~w8`L|kXGpBaM=C75+NN3UlQZFP4;nrXlonN iwWP+bhD&zRYgLZM_PoX>$ViOoD||G}Mwg&TAnsL#*B`L} literal 0 HcmV?d00001 diff --git a/nukebuild/BuildTasksPatcher.cs b/nukebuild/BuildTasksPatcher.cs index 44f01da669..0b650ca7cc 100644 --- a/nukebuild/BuildTasksPatcher.cs +++ b/nukebuild/BuildTasksPatcher.cs @@ -29,7 +29,8 @@ public class BuildTasksPatcher InputAssemblies = new[] { temp, typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0] - .FullyQualifiedName + .FullyQualifiedName, + typeof(Mono.Cecil.Rocks.MethodBodyRocks).Assembly.GetModules()[0].FullyQualifiedName }, SearchDirectories = new string[0], OutputFile = output diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj index b06e49f2eb..77cfb83427 100644 --- a/nukebuild/_build.csproj +++ b/nukebuild/_build.csproj @@ -16,7 +16,7 @@ - + diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets index 84a62bb5c0..612c368633 100644 --- a/packages/Avalonia/AvaloniaBuildTasks.targets +++ b/packages/Avalonia/AvaloniaBuildTasks.targets @@ -87,6 +87,9 @@ ProjectDirectory="$(MSBuildProjectDirectory)" VerifyIl="$(AvaloniaXamlIlVerifyIl)" ReportImportance="$(AvaloniaXamlReportImportance)" + AssemblyOriginatorKeyFile="$(AssemblyOriginatorKeyFile)" + SignAssembly="$(SignAssembly)" + DelaySign="$(DelaySign)" /> - + diff --git a/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs b/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs index 95e59dde2b..8e1f6c257d 100644 --- a/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs +++ b/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs @@ -39,7 +39,9 @@ namespace Avalonia.Build.Tasks var res = XamlCompilerTaskExecutor.Compile(BuildEngine, input, File.ReadAllLines(ReferencesFilePath).Where(l => !string.IsNullOrWhiteSpace(l)).ToArray(), - ProjectDirectory, OutputPath, VerifyIl, outputImportance); + ProjectDirectory, OutputPath, VerifyIl, outputImportance, + (SignAssembly && !DelaySign) ? AssemblyOriginatorKeyFile : null + ); if (!res.Success) return false; if (!res.WrittenFile) @@ -73,6 +75,10 @@ namespace Avalonia.Build.Tasks public string OutputPath { get; set; } public bool VerifyIl { get; set; } + + public string AssemblyOriginatorKeyFile { get; set; } + public bool SignAssembly { get; set; } + public bool DelaySign { get; set; } public string ReportImportance { get; set; } diff --git a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs index c9c9c562bd..7c4a9df0f4 100644 --- a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs +++ b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs @@ -42,7 +42,7 @@ namespace Avalonia.Build.Tasks } public static CompileResult Compile(IBuildEngine engine, string input, string[] references, string projectDirectory, - string output, bool verifyIl, MessageImportance logImportance) + string output, bool verifyIl, MessageImportance logImportance, string strongNameKey) { var typeSystem = new CecilTypeSystem(references.Concat(new[] {input}), input); var asm = typeSystem.TargetAssemblyDefinition; @@ -361,10 +361,12 @@ namespace Avalonia.Build.Tasks loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull)); loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); - asm.Write(output, new WriterParameters - { - WriteSymbols = asm.MainModule.HasSymbols - }); + + var writerParameters = new WriterParameters { WriteSymbols = asm.MainModule.HasSymbols }; + if (!string.IsNullOrWhiteSpace(strongNameKey)) + writerParameters.StrongNameKeyBlob = File.ReadAllBytes(strongNameKey); + + asm.Write(output, writerParameters); return new CompileResult(true, true); } diff --git a/src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs b/src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs index 82b01e99bb..72dd949421 100644 --- a/src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs @@ -2,8 +2,8 @@ using System.Reflection; using System.Runtime.CompilerServices; using Avalonia.Metadata; -[assembly: InternalsVisibleTo("Avalonia.Controls.DataGrid.UnitTests")] -[assembly: InternalsVisibleTo("Avalonia.DesignerSupport")] +[assembly: InternalsVisibleTo("Avalonia.Controls.DataGrid.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] +[assembly: InternalsVisibleTo("Avalonia.DesignerSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Collections")] diff --git a/src/Avalonia.Controls/Properties/AssemblyInfo.cs b/src/Avalonia.Controls/Properties/AssemblyInfo.cs index 672fbe294e..5e18115ac8 100644 --- a/src/Avalonia.Controls/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Controls/Properties/AssemblyInfo.cs @@ -2,8 +2,8 @@ using System.Reflection; using System.Runtime.CompilerServices; using Avalonia.Metadata; -[assembly: InternalsVisibleTo("Avalonia.Controls.UnitTests")] -[assembly: InternalsVisibleTo("Avalonia.DesignerSupport")] +[assembly: InternalsVisibleTo("Avalonia.Controls.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] +[assembly: InternalsVisibleTo("Avalonia.DesignerSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")] diff --git a/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj b/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj index 260d7350d2..81af76dc20 100644 --- a/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj +++ b/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj @@ -6,9 +6,7 @@ + - - - diff --git a/src/Avalonia.Layout/Properties/AssemblyInfo.cs b/src/Avalonia.Layout/Properties/AssemblyInfo.cs index 0a6a32493a..efcbf184b5 100644 --- a/src/Avalonia.Layout/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Layout/Properties/AssemblyInfo.cs @@ -1,7 +1,7 @@ using System.Runtime.CompilerServices; using Avalonia.Metadata; -[assembly: InternalsVisibleTo("Avalonia.Layout.UnitTests")] +[assembly: InternalsVisibleTo("Avalonia.Layout.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Layout")] diff --git a/src/Avalonia.Styling/Properties/AssemblyInfo.cs b/src/Avalonia.Styling/Properties/AssemblyInfo.cs index b231f3b406..f6b69d8150 100644 --- a/src/Avalonia.Styling/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Styling/Properties/AssemblyInfo.cs @@ -5,4 +5,4 @@ using Avalonia.Metadata; [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.LogicalTree")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Styling")] -[assembly: InternalsVisibleTo("Avalonia.Styling.UnitTests")] \ No newline at end of file +[assembly: InternalsVisibleTo("Avalonia.Styling.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] diff --git a/src/Avalonia.Visuals/Properties/AssemblyInfo.cs b/src/Avalonia.Visuals/Properties/AssemblyInfo.cs index 5d802c27b9..5bb9ae78b0 100644 --- a/src/Avalonia.Visuals/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Visuals/Properties/AssemblyInfo.cs @@ -2,13 +2,13 @@ using System.Reflection; using System.Runtime.CompilerServices; using Avalonia.Metadata; -[assembly: InternalsVisibleTo("Avalonia.Visuals.UnitTests")] +[assembly: InternalsVisibleTo("Avalonia.Visuals.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media.Imaging")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media.Transformation")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")] -[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests")] -[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests")] -[assembly: InternalsVisibleTo("Avalonia.Skia.UnitTests")] +[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] +[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] +[assembly: InternalsVisibleTo("Avalonia.Skia.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] diff --git a/src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs b/src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs index 7e4a095bdf..cee2b8a484 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs @@ -5,5 +5,5 @@ using System.Runtime.CompilerServices; [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.MarkupExtensions")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.Styling")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.Templates")] -[assembly: InternalsVisibleTo("Avalonia.Markup.Xaml.UnitTests")] +[assembly: InternalsVisibleTo("Avalonia.Markup.Xaml.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] diff --git a/src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs b/src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs index 72c1659a1e..3da708bc9c 100644 --- a/src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs +++ b/src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs @@ -4,4 +4,4 @@ using System.Runtime.CompilerServices; [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Data")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Data")] -[assembly: InternalsVisibleTo("Avalonia.Markup.UnitTests")] +[assembly: InternalsVisibleTo("Avalonia.Markup.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] diff --git a/src/Skia/Avalonia.Skia/Properties/AssemblyInfo.cs b/src/Skia/Avalonia.Skia/Properties/AssemblyInfo.cs index f6aabfae39..b923e3a9f6 100644 --- a/src/Skia/Avalonia.Skia/Properties/AssemblyInfo.cs +++ b/src/Skia/Avalonia.Skia/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests")] -[assembly: InternalsVisibleTo("Avalonia.Skia.UnitTests")] +[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] +[assembly: InternalsVisibleTo("Avalonia.Skia.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] diff --git a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs index 5d53fd4aae..78e7b4aad6 100644 --- a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs +++ b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs @@ -6,6 +6,6 @@ using Avalonia.Direct2D1; [assembly: ExportRenderingSubsystem(OperatingSystemType.WinNT, 1, "Direct2D1", typeof(Direct2D1Platform), nameof(Direct2D1Platform.Initialize), typeof(Direct2DChecker))] -[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests")] -[assembly: InternalsVisibleTo("Avalonia.Direct2D1.UnitTests")] +[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] +[assembly: InternalsVisibleTo("Avalonia.Direct2D1.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")] diff --git a/tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj b/tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj index b1d89037da..11394c6e5c 100644 --- a/tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj +++ b/tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj @@ -6,6 +6,8 @@ Library false latest + ..\..\build\avalonia.snk + True From 0e70ce4999b3a7c452026d7e095c9b62f5262766 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 12 Oct 2020 18:27:26 +0100 Subject: [PATCH 066/115] rename CompositionHost to CompositionConnector. --- .../{CompositionHost.cs => CompositionConnector.cs} | 6 +++--- .../Composition/CompositionEglGlPlatformSurface.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/Windows/Avalonia.Win32/Composition/{CompositionHost.cs => CompositionConnector.cs} (97%) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs similarity index 97% rename from src/Windows/Avalonia.Win32/Composition/CompositionHost.cs rename to src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs index c88d239670..1519520d89 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs @@ -9,7 +9,7 @@ using WinRT; namespace Avalonia.Win32 { - class CompositionHost + class CompositionConnector { internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE { @@ -39,13 +39,13 @@ namespace Avalonia.Win32 [DllImport("coremessaging.dll", EntryPoint = "CreateDispatcherQueueController", CharSet = CharSet.Unicode)] internal static extern IntPtr CreateDispatcherQueueController(DispatcherQueueOptions options, out IntPtr dispatcherQueueController); - public static CompositionHost Instance { get; } = new CompositionHost(); + public static CompositionConnector Instance { get; } = new CompositionConnector(); private Compositor _compositor; private Windows.System.DispatcherQueueController _dispatcherQueueController; private CompositionGraphicsDevice _graphicsDevice; - private CompositionHost() + private CompositionConnector() { var glPlatform = AvaloniaLocator.Current.GetService(); diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index 547e2d3c0e..6b6e272580 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -25,7 +25,7 @@ namespace Avalonia.Win32 { using (_egl.PrimaryContext.MakeCurrent()) { - _surfaceInterop = CompositionHost.Instance.InitialiseWindowCompositionTree(hwnd, out _surface, out var blurHost); + _surfaceInterop = CompositionConnector.Instance.InitialiseWindowCompositionTree(hwnd, out _surface, out var blurHost); return blurHost; } } From ae876bd058675e644924eb24d20837f4191208ad Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 12 Oct 2020 18:48:12 +0100 Subject: [PATCH 067/115] simplify composition connection. --- .../Composition/CompositionConnector.cs | 15 ++------------- .../CompositionEglGlPlatformSurface.cs | 4 ++-- src/Windows/Avalonia.Win32/Win32GlManager.cs | 18 ++++++++++++++---- src/Windows/Avalonia.Win32/Win32Platform.cs | 3 ++- src/Windows/Avalonia.Win32/WindowImpl.cs | 9 +++++---- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs b/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs index 1519520d89..447f8a8c90 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs @@ -39,24 +39,13 @@ namespace Avalonia.Win32 [DllImport("coremessaging.dll", EntryPoint = "CreateDispatcherQueueController", CharSet = CharSet.Unicode)] internal static extern IntPtr CreateDispatcherQueueController(DispatcherQueueOptions options, out IntPtr dispatcherQueueController); - public static CompositionConnector Instance { get; } = new CompositionConnector(); - private Compositor _compositor; private Windows.System.DispatcherQueueController _dispatcherQueueController; private CompositionGraphicsDevice _graphicsDevice; - private CompositionConnector() + internal CompositionConnector(EglPlatformOpenGlInterface egl) { - var glPlatform = AvaloniaLocator.Current.GetService(); - - if (glPlatform is EglPlatformOpenGlInterface egl) - { - Initialize(egl); - } - else - { - throw new PlatformNotSupportedException(); - } + Initialize(egl); } private void Initialize(EglPlatformOpenGlInterface egl) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs index 6b6e272580..441da93787 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionEglGlPlatformSurface.cs @@ -21,11 +21,11 @@ namespace Avalonia.Win32 _info = info; } - public IBlurHost AttachToCompositionTree(IntPtr hwnd) + public IBlurHost AttachToCompositionTree(CompositionConnector connector, IntPtr hwnd) { using (_egl.PrimaryContext.MakeCurrent()) { - _surfaceInterop = CompositionConnector.Instance.InitialiseWindowCompositionTree(hwnd, out _surface, out var blurHost); + _surfaceInterop = connector.InitialiseWindowCompositionTree(hwnd, out _surface, out var blurHost); return blurHost; } } diff --git a/src/Windows/Avalonia.Win32/Win32GlManager.cs b/src/Windows/Avalonia.Win32/Win32GlManager.cs index 523a059e0e..6a6ce2ec3c 100644 --- a/src/Windows/Avalonia.Win32/Win32GlManager.cs +++ b/src/Windows/Avalonia.Win32/Win32GlManager.cs @@ -7,8 +7,6 @@ namespace Avalonia.Win32 { static class Win32GlManager { - private static bool s_attemptedToInitialize; - public static void Initialize() { AvaloniaLocator.CurrentMutable.Bind().ToLazy(() => @@ -19,9 +17,21 @@ namespace Avalonia.Win32 var wgl = WglPlatformOpenGlInterface.TryCreate(); return wgl; } - + if (opts?.AllowEglInitialization == true) - return EglPlatformOpenGlInterface.TryCreate(() => new AngleWin32EglDisplay()); + { + var egl = EglPlatformOpenGlInterface.TryCreate(() => new AngleWin32EglDisplay()); + + if (egl is { } && + opts?.UseWindowsUIComposition == true && + Win32Platform.WindowsVersion.Major >= 10 && + Win32Platform.WindowsVersion.Build >= 16299) + { + AvaloniaLocator.CurrentMutable.BindToSelf(new CompositionConnector(egl)); + } + + return egl; + } return null; }); diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 493ae45656..5b16cae26e 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -12,6 +12,7 @@ using Avalonia.Controls.Platform; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.OpenGL; +using Avalonia.OpenGL.Egl; using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Threading; @@ -113,7 +114,7 @@ namespace Avalonia.Win32 .Bind().ToConstant(new WindowsMountedVolumeInfoProvider()); Win32GlManager.Initialize(); - + _uiThread = Thread.CurrentThread; if (OleContext.Current != null) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 1fd8752a8f..715c8fc01d 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -107,9 +107,10 @@ namespace Avalonia.Win32 var glPlatform = AvaloniaLocator.Current.GetService(); - _isUsingComposition = Win32Platform.Options.UseWindowsUIComposition && - Win32Platform.WindowsVersion.Major >= 10 && Win32Platform.WindowsVersion.Build >= 16299 && - glPlatform != null && glPlatform is EglPlatformOpenGlInterface egl && + var compositionConnector = AvaloniaLocator.Current.GetService(); + + _isUsingComposition = compositionConnector is { } && + glPlatform is EglPlatformOpenGlInterface egl && egl.Display is AngleWin32EglDisplay angleDisplay && angleDisplay.PlatformApi == AngleOptions.PlatformApi.DirectX11; @@ -121,7 +122,7 @@ namespace Avalonia.Win32 if (_isUsingComposition) { var cgl = new CompositionEglGlPlatformSurface(glPlatform as EglPlatformOpenGlInterface, this); - _blurHost = cgl.AttachToCompositionTree(_hwnd); + _blurHost = cgl.AttachToCompositionTree(compositionConnector, _hwnd); _gl = cgl; From 614c0c6726eaaf7fbc0a825618cf518cd4320f3e Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 12 Oct 2020 18:51:00 +0100 Subject: [PATCH 068/115] tidy composition connector. --- .../Composition/CompositionConnector.cs | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs b/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs index 447f8a8c90..3929dc07bf 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionConnector.cs @@ -9,8 +9,12 @@ using WinRT; namespace Avalonia.Win32 { - class CompositionConnector + internal class CompositionConnector { + private Compositor _compositor; + private Windows.System.DispatcherQueueController _dispatcherQueueController; + private CompositionGraphicsDevice _graphicsDevice; + internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE { DQTAT_COM_NONE = 0, @@ -39,23 +43,15 @@ namespace Avalonia.Win32 [DllImport("coremessaging.dll", EntryPoint = "CreateDispatcherQueueController", CharSet = CharSet.Unicode)] internal static extern IntPtr CreateDispatcherQueueController(DispatcherQueueOptions options, out IntPtr dispatcherQueueController); - private Compositor _compositor; - private Windows.System.DispatcherQueueController _dispatcherQueueController; - private CompositionGraphicsDevice _graphicsDevice; - - internal CompositionConnector(EglPlatformOpenGlInterface egl) - { - Initialize(egl); - } - - private void Initialize(EglPlatformOpenGlInterface egl) + public CompositionConnector(EglPlatformOpenGlInterface egl) { EnsureDispatcherQueue(); + if (_dispatcherQueueController != null) _compositor = new Compositor(); var interop = _compositor.As(); - + var display = egl.Display as AngleWin32EglDisplay; _graphicsDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); @@ -78,7 +74,7 @@ namespace Avalonia.Win32 visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1, 1); var container = _compositor.CreateContainerVisual(); - + target.Root = container; var blur = CreateBlur(); @@ -96,9 +92,9 @@ namespace Avalonia.Win32 return surfaceInterop; } - public SpriteVisual CreateBlur() + private SpriteVisual CreateBlur() { - var blurEffect = new GaussianBlurEffect(new CompositionEffectSourceParameter ("backdrop")); + var blurEffect = new GaussianBlurEffect(new CompositionEffectSourceParameter("backdrop")); var blurEffectFactory = _compositor.CreateEffectFactory(blurEffect); var blurBrush = blurEffectFactory.CreateBrush(); @@ -121,7 +117,7 @@ namespace Avalonia.Win32 return visual; } - CompositionTarget CreateDesktopWindowTarget(IntPtr window) + private CompositionTarget CreateDesktopWindowTarget(IntPtr window) { var interop = _compositor.As(); @@ -129,7 +125,7 @@ namespace Avalonia.Win32 return Windows.UI.Composition.Desktop.DesktopWindowTarget.FromAbi(windowTarget); } - void EnsureDispatcherQueue() + private void EnsureDispatcherQueue() { if (_dispatcherQueueController == null) { From c1bcdb95860739f4b5dd428d935ca7e57fbde8e3 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Wed, 14 Oct 2020 22:19:17 +0200 Subject: [PATCH 069/115] Allow for setting wm shadow hint on a context menu. --- src/Avalonia.Controls/ContextMenu.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs index c4df5c1815..ec9649bc64 100644 --- a/src/Avalonia.Controls/ContextMenu.cs +++ b/src/Avalonia.Controls/ContextMenu.cs @@ -62,6 +62,12 @@ namespace Avalonia.Controls public static readonly StyledProperty PlacementRectProperty = AvaloniaProperty.Register(nameof(PlacementRect)); + /// + /// Defines the property. + /// + public static readonly StyledProperty WindowManagerAddShadowHintProperty = + Popup.WindowManagerAddShadowHintProperty.AddOwner(); + /// /// Defines the property. /// @@ -158,6 +164,12 @@ namespace Avalonia.Controls set { SetValue(PlacementModeProperty, value); } } + public bool WindowManagerAddShadowHint + { + get { return GetValue(WindowManagerAddShadowHintProperty); } + set { SetValue(WindowManagerAddShadowHintProperty, value); } + } + /// /// Gets or sets the the anchor rectangle within the parent that the context menu will be placed /// relative to when is . @@ -267,6 +279,7 @@ namespace Avalonia.Controls PlacementTarget = PlacementTarget ?? control, IsLightDismissEnabled = true, OverlayDismissEventPassThrough = true, + WindowManagerAddShadowHint = WindowManagerAddShadowHint, }; _popup.Opened += PopupOpened; From cdb4e9051854d2d7eff66993ae2733de28cec315 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Thu, 15 Oct 2020 19:37:28 +0300 Subject: [PATCH 070/115] Simplified conditions --- .../Primitives/SelectingItemsControl.cs | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index e34b3b145f..4786e88fca 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -794,18 +794,13 @@ namespace Avalonia.Controls.Primitives /// The event. private void ContainerSelectionChanged(RoutedEventArgs e) { - if (!_ignoreContainerSelectionChanged) + if (!_ignoreContainerSelectionChanged && + e.Source is IControl control && + e.Source is ISelectable selectable && + control.LogicalParent == this && + ItemContainerGenerator?.IndexFromContainer(control) != -1) { - var control = e.Source as IControl; - var selectable = e.Source as ISelectable; - - if (control != null && - selectable != null && - control.LogicalParent == this && - ItemContainerGenerator?.IndexFromContainer(control) != -1) - { - UpdateSelection(control, selectable.IsSelected); - } + UpdateSelection(control, selectable.IsSelected); } if (e.Source != this) @@ -824,12 +819,11 @@ namespace Avalonia.Controls.Primitives { try { - var selectable = container as ISelectable; bool result; _ignoreContainerSelectionChanged = true; - if (selectable != null) + if (container is ISelectable selectable) { result = selectable.IsSelected; selectable.IsSelected = selected; From 3b48238fe07642d780740a9b1c26a0b6860374ff Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Thu, 15 Oct 2020 19:38:06 +0300 Subject: [PATCH 071/115] Removed dead code --- .../Primitives/SelectingItemsControl.cs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index 4786e88fca..301487ebb6 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -842,21 +842,6 @@ namespace Avalonia.Controls.Primitives } } - /// - /// Sets an item container's 'selected' class or . - /// - /// The index of the item. - /// Whether the item should be selected or deselected. - private void MarkItemSelected(int index, bool selected) - { - var container = ItemContainerGenerator?.ContainerFromIndex(index); - - if (container != null) - { - MarkContainerSelected(container, selected); - } - } - private void UpdateContainerSelection() { if (Presenter?.Panel is IPanel panel) From 70aef2b17ed84b51b226b6f004efb79ca1b7067b Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 16 Oct 2020 15:35:20 +0300 Subject: [PATCH 072/115] We can't randomly reference ReactiveUI anymore due to its maintainer's religious views --- .../Avalonia.Controls.UnitTests.csproj | 1 - .../TreeViewTests.cs | 20 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj b/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj index 19c4454d3d..7a6d77ef46 100644 --- a/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj +++ b/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj @@ -22,7 +22,6 @@ - diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs index 9253d8a07f..b805683393 100644 --- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs @@ -2,7 +2,9 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Linq; +using System.Runtime.CompilerServices; using Avalonia.Collections; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; @@ -14,7 +16,7 @@ using Avalonia.Interactivity; using Avalonia.LogicalTree; using Avalonia.Styling; using Avalonia.UnitTests; -using ReactiveUI; +using JetBrains.Annotations; using Xunit; namespace Avalonia.Controls.UnitTests @@ -480,8 +482,12 @@ namespace Avalonia.Controls.UnitTests var selectedValues = new List(); - dataContext.WhenAnyValue(x => x.SelectedItem) - .Subscribe(x => selectedValues.Add(x)); + dataContext.PropertyChanged += (_, e) => + { + if (e.PropertyName == nameof(TestDataContext.SelectedItem)) + selectedValues.Add(dataContext.SelectedItem); + }; + selectedValues.Add(dataContext.SelectedItem); _mouse.Click((Interactive)target.Presenter.Panel.Children[0], MouseButton.Left); _mouse.Click((Interactive)target.Presenter.Panel.Children[2], MouseButton.Left); @@ -1326,7 +1332,7 @@ namespace Avalonia.Controls.UnitTests { } - private class TestDataContext : ReactiveObject + private class TestDataContext : INotifyPropertyChanged { private string _selectedItem; @@ -1342,9 +1348,13 @@ namespace Avalonia.Controls.UnitTests get { return _selectedItem; } set { - this.RaiseAndSetIfChanged(ref _selectedItem, value); + _selectedItem = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItem))); } } + + public event PropertyChangedEventHandler PropertyChanged; + } } } From 21fadbedd6734fd74e07fdeb7c2383b546ce6b38 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 16 Oct 2020 12:43:17 +0300 Subject: [PATCH 073/115] add tests for text issue:4866 --- .../Controls/TextBlockTests.cs | 54 ++++++++++++++++++ ...estrictedHeight_VerticalAlign.expected.png | Bin 0 -> 527 bytes ...estrictedHeight_VerticalAlign.expected.png | Bin 0 -> 527 bytes 3 files changed, 54 insertions(+) create mode 100644 tests/TestFiles/Direct2D1/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png create mode 100644 tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png diff --git a/tests/Avalonia.RenderTests/Controls/TextBlockTests.cs b/tests/Avalonia.RenderTests/Controls/TextBlockTests.cs index ab769e4ff0..53a2959848 100644 --- a/tests/Avalonia.RenderTests/Controls/TextBlockTests.cs +++ b/tests/Avalonia.RenderTests/Controls/TextBlockTests.cs @@ -40,5 +40,59 @@ namespace Avalonia.Direct2D1.RenderTests.Controls await RenderToFile(target); CompareImages(); } + + + [Win32Fact("Has text")] + public async Task RestrictedHeight_VerticalAlign() + { + IControl text(VerticalAlignment verticalAlingnment, bool clip = true, bool restrictHeight = true) + { + return new Border() + { + BorderBrush = Brushes.Blue, + BorderThickness = new Thickness(1), + VerticalAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Center, + Height = restrictHeight ? 20 : double.NaN, + Margin = new Thickness(1), + Child = new TextBlock + { + FontFamily = new FontFamily("Courier New"), + Background = Brushes.Red, + FontSize = 24, + Foreground = Brushes.Black, + Text = "L", + VerticalAlignment = verticalAlingnment, + ClipToBounds = clip + } + }; + } + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 180, + Height = 80, + + Child = new StackPanel() + { + Orientation = Orientation.Horizontal, + Children = + { + text(VerticalAlignment.Stretch, restrictHeight: false), + text(VerticalAlignment.Center), + text(VerticalAlignment.Stretch), + text(VerticalAlignment.Top), + text(VerticalAlignment.Bottom), + text(VerticalAlignment.Center, clip:false), + text(VerticalAlignment.Stretch, clip:false), + text(VerticalAlignment.Top, clip:false), + text(VerticalAlignment.Bottom, clip:false), + } + } + }; + + await RenderToFile(target); + CompareImages(); + } } } diff --git a/tests/TestFiles/Direct2D1/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png b/tests/TestFiles/Direct2D1/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..c5a0a14e52616d76ebd7926248e785e0c6b42296 GIT binary patch literal 527 zcmeAS@N?(olHy`uVBq!ia0vp^TYxx#gAGV-kceLfq*#ibJVQ8upoSx*gMoqZn5T}U;+IFz$-)-2Qso+}Sug{{q>EZbaGG{*& z^BrhqNHVFa5_;F;p$aq=4P+N;Sm#Ql+4(;Fe8A?um%ofx_5WVyv^uebmhOAP3E}(H zCG9Noq|YTwv?afjs6ErKopYshQv6nS-E$W{D;@W4TQ~J+@8*An?jwXI=Mg#)U&G&X+8f+7-6YKb)<8(jSY;J4LA* zLS7lie%u!OY5#?jJ6KrO-q@BLY*L~g?)mTQydzD%YtOHe-W9g&{YH-6{+~*gZH#}j z(QdKPmrGYpeTj~h269&aYirvscK^brXV0%Z-@4hfWUbTo6SKC?Njp1RW&h{GZ);p@ z!i5)L7|fua=M~7lo_83w~vya^yjSMfh`j0J+JDUAFAD)x=QqT z_~xVcen?B5^9CAdVlq2uPwsR5y=Y<0z|in+9^)@(Q)>rl$*mwsPgg&ebxsLQ0Q>~$ ATmS$7 literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..c5a0a14e52616d76ebd7926248e785e0c6b42296 GIT binary patch literal 527 zcmeAS@N?(olHy`uVBq!ia0vp^TYxx#gAGV-kceLfq*#ibJVQ8upoSx*gMoqZn5T}U;+IFz$-)-2Qso+}Sug{{q>EZbaGG{*& z^BrhqNHVFa5_;F;p$aq=4P+N;Sm#Ql+4(;Fe8A?um%ofx_5WVyv^uebmhOAP3E}(H zCG9Noq|YTwv?afjs6ErKopYshQv6nS-E$W{D;@W4TQ~J+@8*An?jwXI=Mg#)U&G&X+8f+7-6YKb)<8(jSY;J4LA* zLS7lie%u!OY5#?jJ6KrO-q@BLY*L~g?)mTQydzD%YtOHe-W9g&{YH-6{+~*gZH#}j z(QdKPmrGYpeTj~h269&aYirvscK^brXV0%Z-@4hfWUbTo6SKC?Njp1RW&h{GZ);p@ z!i5)L7|fua=M~7lo_83w~vya^yjSMfh`j0J+JDUAFAD)x=QqT z_~xVcen?B5^9CAdVlq2uPwsR5y=Y<0z|in+9^)@(Q)>rl$*mwsPgg&ebxsLQ0Q>~$ ATmS$7 literal 0 HcmV?d00001 From dda966676c62932cc3d92a53a0430d03cb3296eb Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 16 Oct 2020 15:38:43 +0300 Subject: [PATCH 074/115] fix Textblock text alignment with restricted height #4866 --- src/Avalonia.Controls/TextBlock.cs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs index d61519e697..31517ba59d 100644 --- a/src/Avalonia.Controls/TextBlock.cs +++ b/src/Avalonia.Controls/TextBlock.cs @@ -3,6 +3,7 @@ using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.Media.TextFormatting; using Avalonia.Metadata; +using Avalonia.Layout; namespace Avalonia.Controls { @@ -427,14 +428,32 @@ namespace Avalonia.Controls case TextAlignment.Center: offsetX = (width - TextLayout.Size.Width) / 2; break; + case TextAlignment.Right: - offsetX = width - TextLayout.Size.Width; + offsetX = width - TextLayout.Size.Width; break; } var padding = Padding; - using (context.PushPostTransform(Matrix.CreateTranslation(padding.Left + offsetX, padding.Top))) + var top = padding.Top; + var textSize = TextLayout.Size; + + if (Bounds.Height < textSize.Height) + { + switch (VerticalAlignment) + { + case VerticalAlignment.Center: + top += (Bounds.Height - textSize.Height) / 2; + break; + + case VerticalAlignment.Bottom: + top += (Bounds.Height - textSize.Height); + break; + } + } + + using (context.PushPostTransform(Matrix.CreateTranslation(padding.Left + offsetX, top))) { TextLayout.Draw(context); } From 1dc2b0b12a12542a95bfc40373cf28d44e8fc688 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 16 Oct 2020 15:39:06 +0300 Subject: [PATCH 075/115] fix TextPresenter text alignment with restricted height #4866 --- .../Presenters/TextPresenter.cs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs index 6a6d37605d..078d8050bf 100644 --- a/src/Avalonia.Controls/Presenters/TextPresenter.cs +++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs @@ -4,6 +4,7 @@ using Avalonia.Media; using Avalonia.Metadata; using Avalonia.Threading; using Avalonia.VisualTree; +using Avalonia.Layout; namespace Avalonia.Controls.Presenters { @@ -312,7 +313,24 @@ namespace Avalonia.Controls.Presenters context.FillRectangle(background, new Rect(Bounds.Size)); } - context.DrawText(Foreground, new Point(), FormattedText); + double top = 0; + var textSize = FormattedText.Bounds.Size; + + if (Bounds.Height < textSize.Height) + { + switch (VerticalAlignment) + { + case VerticalAlignment.Center: + top += (Bounds.Height - textSize.Height) / 2; + break; + + case VerticalAlignment.Bottom: + top += (Bounds.Height - textSize.Height); + break; + } + } + + context.DrawText(Foreground, new Point(0, top), FormattedText); } public override void Render(DrawingContext context) From 919c1edde4e7be6716023204df3547b1b0c9d49a Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 17 Oct 2020 10:30:45 +0200 Subject: [PATCH 076/115] Remove warning sample --- samples/BindingDemo/App.xaml.cs | 20 +++++++++++------- samples/ControlCatalog.Desktop/Program.cs | 8 ++----- .../ControlCatalog.NetCore.csproj | 1 - samples/Previewer/App.xaml.cs | 10 ++++++++- samples/Previewer/Program.cs | 15 ++++++------- samples/RenderDemo/App.xaml.cs | 11 +++++++++- samples/RenderDemo/Pages/GlyphRunPage.xaml | 6 +++--- samples/RenderDemo/Pages/GlyphRunPage.xaml.cs | 7 ++++--- samples/VirtualizationDemo/App.xaml.cs | 8 +++++++ samples/VirtualizationDemo/Program.cs | 20 ++++++++---------- .../interop/Direct3DInteropSample/App.paml.cs | 8 +++++++ .../interop/Direct3DInteropSample/Program.cs | 21 ++++++++----------- .../NativeEmbedSample.csproj | 1 - 13 files changed, 83 insertions(+), 53 deletions(-) diff --git a/samples/BindingDemo/App.xaml.cs b/samples/BindingDemo/App.xaml.cs index 13875aeb21..5c38ab8305 100644 --- a/samples/BindingDemo/App.xaml.cs +++ b/samples/BindingDemo/App.xaml.cs @@ -1,6 +1,5 @@ -using System; using Avalonia; -using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; @@ -13,13 +12,20 @@ namespace BindingDemo AvaloniaXamlLoader.Load(this); } - private static void Main() + public override void OnFrameworkInitializationCompleted() { - AppBuilder.Configure() + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + desktop.MainWindow = new MainWindow(); + base.OnFrameworkInitializationCompleted(); + } + + public static int Main(string[] args) + => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); + + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() .UsePlatformDetect() .UseReactiveUI() - .LogToDebug() - .Start(); - } + .LogToDebug(); } } diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index b2df1953f5..e0cc8cc904 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -10,12 +10,8 @@ namespace ControlCatalog internal class Program { [STAThread] - static void Main(string[] args) - { - // TODO: Make this work with GTK/Skia/Cairo depending on command-line args - // again. - BuildAvaloniaApp().Start(); - } + public static int Main(string[] args) + => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); /// /// This method is needed for IDE previewer infrastructure diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj index 28b0257eda..2752703e21 100644 --- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj +++ b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj @@ -11,7 +11,6 @@ - diff --git a/samples/Previewer/App.xaml.cs b/samples/Previewer/App.xaml.cs index fffa987a27..ab83d45cd3 100644 --- a/samples/Previewer/App.xaml.cs +++ b/samples/Previewer/App.xaml.cs @@ -1,4 +1,5 @@ using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; namespace Previewer @@ -9,6 +10,13 @@ namespace Previewer { AvaloniaXamlLoader.Load(this); } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + desktop.MainWindow = new MainWindow(); + base.OnFrameworkInitializationCompleted(); + } } -} \ No newline at end of file +} diff --git a/samples/Previewer/Program.cs b/samples/Previewer/Program.cs index 48363e27f2..b12b93974a 100644 --- a/samples/Previewer/Program.cs +++ b/samples/Previewer/Program.cs @@ -1,13 +1,14 @@ -using System; -using Avalonia; +using Avalonia; namespace Previewer { class Program { - static void Main(string[] args) - { - AppBuilder.Configure().UsePlatformDetect().Start(); - } + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect(); + + public static int Main(string[] args) + => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); } -} \ No newline at end of file +} diff --git a/samples/RenderDemo/App.xaml.cs b/samples/RenderDemo/App.xaml.cs index 340ccdae19..2247fd7c5a 100644 --- a/samples/RenderDemo/App.xaml.cs +++ b/samples/RenderDemo/App.xaml.cs @@ -1,4 +1,5 @@ using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; @@ -11,9 +12,17 @@ namespace RenderDemo AvaloniaXamlLoader.Load(this); } + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + desktop.MainWindow = new MainWindow(); + base.OnFrameworkInitializationCompleted(); + } + // TODO: Make this work with GTK/Skia/Cairo depending on command-line args // again. - static void Main(string[] args) => BuildAvaloniaApp().Start(); + static void Main(string[] args) + => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); // App configuration, used by the entry point and previewer static AppBuilder BuildAvaloniaApp() diff --git a/samples/RenderDemo/Pages/GlyphRunPage.xaml b/samples/RenderDemo/Pages/GlyphRunPage.xaml index fb3e318a0e..c2914e8847 100644 --- a/samples/RenderDemo/Pages/GlyphRunPage.xaml +++ b/samples/RenderDemo/Pages/GlyphRunPage.xaml @@ -6,9 +6,9 @@ x:Class="RenderDemo.Pages.GlyphRunPage"> - - + diff --git a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs index ddee880288..857358f6b2 100644 --- a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs +++ b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs @@ -9,7 +9,7 @@ namespace RenderDemo.Pages { public class GlyphRunPage : UserControl { - private DrawingPresenter _drawingPresenter; + private Image _imageControl; private GlyphTypeface _glyphTypeface = Typeface.Default.GlyphTypeface; private readonly Random _rand = new Random(); private ushort[] _glyphIndices = new ushort[1]; @@ -25,7 +25,8 @@ namespace RenderDemo.Pages { AvaloniaXamlLoader.Load(this); - _drawingPresenter = this.FindControl("drawingPresenter"); + _imageControl = this.FindControl("imageControl"); + _imageControl.Source = new DrawingImage(); DispatcherTimer.Run(() => { @@ -73,7 +74,7 @@ namespace RenderDemo.Pages drawingGroup.Children.Add(geometryDrawing); - _drawingPresenter.Drawing = drawingGroup; + (_imageControl.Source as DrawingImage).Drawing = drawingGroup; } } } diff --git a/samples/VirtualizationDemo/App.xaml.cs b/samples/VirtualizationDemo/App.xaml.cs index 5990dd282c..81b80c1f40 100644 --- a/samples/VirtualizationDemo/App.xaml.cs +++ b/samples/VirtualizationDemo/App.xaml.cs @@ -1,4 +1,5 @@ using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; namespace VirtualizationDemo @@ -9,5 +10,12 @@ namespace VirtualizationDemo { AvaloniaXamlLoader.Load(this); } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + desktop.MainWindow = new MainWindow(); + base.OnFrameworkInitializationCompleted(); + } } } diff --git a/samples/VirtualizationDemo/Program.cs b/samples/VirtualizationDemo/Program.cs index 93ea5e1b88..c23bfd7ad9 100644 --- a/samples/VirtualizationDemo/Program.cs +++ b/samples/VirtualizationDemo/Program.cs @@ -1,19 +1,17 @@ -using System; -using Avalonia; -using Avalonia.Controls; +using Avalonia; using Avalonia.ReactiveUI; namespace VirtualizationDemo { class Program { - static void Main(string[] args) - { - AppBuilder.Configure() - .UsePlatformDetect() - .UseReactiveUI() - .LogToDebug() - .Start(); - } + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .UseReactiveUI() + .LogToDebug(); + + public static int Main(string[] args) + => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); } } diff --git a/samples/interop/Direct3DInteropSample/App.paml.cs b/samples/interop/Direct3DInteropSample/App.paml.cs index 1b6d5fd39c..29365decfe 100644 --- a/samples/interop/Direct3DInteropSample/App.paml.cs +++ b/samples/interop/Direct3DInteropSample/App.paml.cs @@ -1,4 +1,5 @@ using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; namespace Direct3DInteropSample @@ -9,5 +10,12 @@ namespace Direct3DInteropSample { AvaloniaXamlLoader.Load(this); } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + desktop.MainWindow = new MainWindow(); + base.OnFrameworkInitializationCompleted(); + } } } diff --git a/samples/interop/Direct3DInteropSample/Program.cs b/samples/interop/Direct3DInteropSample/Program.cs index 21302fa68a..bf8e76d7e4 100644 --- a/samples/interop/Direct3DInteropSample/Program.cs +++ b/samples/interop/Direct3DInteropSample/Program.cs @@ -1,19 +1,16 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Avalonia; +using Avalonia; namespace Direct3DInteropSample { class Program { - static void Main(string[] args) - { - AppBuilder.Configure() - .With(new Win32PlatformOptions {UseDeferredRendering = false}) - .UseWin32().UseDirect2D1().Start(); - } + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .With(new Win32PlatformOptions { UseDeferredRendering = false }) + .UseWin32() + .UseDirect2D1(); + + public static int Main(string[] args) + => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); } } diff --git a/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj b/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj index cc831ef8ae..0e0e71fbb2 100644 --- a/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj +++ b/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj @@ -9,7 +9,6 @@ - From a6c705bf70f56389392fadabff43e05b3010f143 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 17 Oct 2020 10:35:18 +0200 Subject: [PATCH 077/115] Update XML Comment --- .../DataGridColumn.cs | 1 + .../Primitives/IPopupHost.cs | 1 + src/Avalonia.Controls/Window.cs | 2 +- src/Avalonia.Visuals/Media/Imaging/Bitmap.cs | 1 - .../Platform/IDrawingContextImpl.cs | 2 +- .../SceneGraph/ExperimentalAcrylicNode.cs | 7 ++--- .../Rendering/SceneGraph/GeometryNode.cs | 1 - .../Rendering/SceneGraph/RectangleNode.cs | 2 +- .../Avalonia.LinuxFramebuffer/Output/Drm.cs | 16 +++++----- .../AvaloniaRuntimeXamlLoader.cs | 31 ++++++++++++++++--- .../Media/DrawingContextImpl.cs | 1 - .../Avalonia.Win32/Interop/TaskBarList.cs | 1 + 12 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs index 23c4acdf6c..92ddd4e736 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs @@ -665,6 +665,7 @@ namespace Avalonia.Controls /// /// The data item represented by the row that contains the intended cell. /// + /// When the method returns, contains the applied binding. /// /// A new editing element that is bound to the column's property value. /// diff --git a/src/Avalonia.Controls/Primitives/IPopupHost.cs b/src/Avalonia.Controls/Primitives/IPopupHost.cs index 82a49c4189..ab81fe869e 100644 --- a/src/Avalonia.Controls/Primitives/IPopupHost.cs +++ b/src/Avalonia.Controls/Primitives/IPopupHost.cs @@ -47,6 +47,7 @@ namespace Avalonia.Controls.Primitives /// The offset, in device-independent pixels. /// The anchor point. /// The popup gravity. + /// Defines how a popup position will be adjusted if the unadjusted position would result in the popup being partly constrained. /// /// The anchor rect. If null, the bounds of will be used. /// diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 317b6d3f2e..54574a7e1c 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -451,7 +451,7 @@ namespace Avalonia.Controls /// /// The dialog result. /// - /// When the window is shown with the + /// When the window is shown with the /// or method, the /// resulting task will produce the value when the window /// is closed. diff --git a/src/Avalonia.Visuals/Media/Imaging/Bitmap.cs b/src/Avalonia.Visuals/Media/Imaging/Bitmap.cs index ca303211cd..5a0c57b333 100644 --- a/src/Avalonia.Visuals/Media/Imaging/Bitmap.cs +++ b/src/Avalonia.Visuals/Media/Imaging/Bitmap.cs @@ -99,7 +99,6 @@ namespace Avalonia.Media.Imaging /// Initializes a new instance of the class. /// /// The pixel format. - /// The alpha format. /// The pointer to the source bytes. /// The size of the bitmap in device pixels. /// The DPI of the bitmap. diff --git a/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs b/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs index cfe2cf979a..9cf4e62030 100644 --- a/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs +++ b/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs @@ -63,7 +63,7 @@ namespace Avalonia.Platform /// The brush used to fill the rectangle, or null for no fill. /// The pen used to stroke the rectangle, or null for no stroke. /// The rectangle bounds. - /// Box shadow effect parameters + /// Box shadow effect parameters /// /// The brush and the pen can both be null. If the brush is null, then no fill is performed. /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible. diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/ExperimentalAcrylicNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/ExperimentalAcrylicNode.cs index 336d11e3fd..8bd079d070 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/ExperimentalAcrylicNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/ExperimentalAcrylicNode.cs @@ -13,10 +13,9 @@ namespace Avalonia.Rendering.SceneGraph /// /// Initializes a new instance of the class. /// - /// The transform. + /// The transform. + /// /// The rectangle to draw. - /// The box shadow parameters - /// Child scenes for drawing visual brushes. public ExperimentalAcrylicNode( Matrix transform, IExperimentalAcrylicMaterial material, @@ -44,7 +43,7 @@ namespace Avalonia.Rendering.SceneGraph /// Determines if this draw operation equals another. /// /// The transform of the other draw operation. - /// The fill of the other draw operation. + /// The fill of the other draw operation. /// The rectangle of the other draw operation. /// True if the draw operations are the same, otherwise false. /// diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs index 8a19679c77..508ca0ad18 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs @@ -63,7 +63,6 @@ namespace Avalonia.Rendering.SceneGraph /// The fill of the other draw operation. /// The stroke of the other draw operation. /// The geometry of the other draw operation. - /// The box shadow parameters /// True if the draw operations are the same, otherwise false. /// /// The properties of the other draw operation are passed in as arguments to prevent diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs index ec1a7753b1..d0c4566485 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs @@ -73,7 +73,7 @@ namespace Avalonia.Rendering.SceneGraph /// The fill of the other draw operation. /// The stroke of the other draw operation. /// The rectangle of the other draw operation. - /// The box shadow parameters of the other draw operation + /// The box shadow parameters of the other draw operation /// True if the draw operations are the same, otherwise false. /// /// The properties of the other draw operation are passed in as arguments to prevent diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs index 787a2e4cb8..9c476b1b63 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs @@ -113,22 +113,22 @@ namespace Avalonia.LinuxFramebuffer.Output [StructLayout(LayoutKind.Sequential)] public struct drmModeConnector { public uint connector_id; - public uint encoder_id; /**< Encoder currently connected to */ + public uint encoder_id; // Encoder currently connected to public uint connector_type; public uint connector_type_id; public DrmModeConnection connection; - public uint mmWidth, mmHeight; /**< HxW in millimeters */ + public uint mmWidth, mmHeight; // HxW in millimeters public DrmModeSubPixel subpixel; public int count_modes; public drmModeModeInfo* modes; public int count_props; - public uint *props; /**< List of property ids */ - public ulong *prop_values; /**< List of property values */ + public uint *props; // List of property ids + public ulong *prop_values; // List of property values public int count_encoders; - public uint *encoders; /**< List of encoder ids */ + public uint *encoders; //List of encoder ids } [StructLayout(LayoutKind.Sequential)] @@ -143,14 +143,14 @@ namespace Avalonia.LinuxFramebuffer.Output [StructLayout(LayoutKind.Sequential)] public struct drmModeCrtc { public uint crtc_id; - public uint buffer_id; /**< FB id to connect to 0 = disconnect */ + public uint buffer_id; // FB id to connect to 0 = disconnect - public uint x, y; /**< Position on the framebuffer */ + public uint x, y; // Position on the framebuffer public uint width, height; public int mode_valid; public drmModeModeInfo mode; - public int gamma_size; /**< Number of gamma stops */ + public int gamma_size; // Number of gamma stops } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs index 4569970d01..4df07bcdd8 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs @@ -3,7 +3,6 @@ using System.IO; using System.Reflection; using System.Text; using Avalonia.Markup.Xaml.XamlIl; -// ReSharper disable CheckNamespace namespace Avalonia.Markup.Xaml { @@ -13,10 +12,10 @@ namespace Avalonia.Markup.Xaml /// Loads XAML from a string. /// /// The string containing the XAML. - /// Default assembly for clr-namespace: - /// - /// The optional instance into which the XAML should be loaded. - /// + /// Default assembly for clr-namespace:. + /// The optional instance into which the XAML should be loaded. + /// The URI of the XAML being loaded. + /// Indicates whether the XAML is being loaded in design mode. /// The loaded object. public static object Load(string xaml, Assembly localAssembly = null, object rootInstance = null, Uri uri = null, bool designMode = false) { @@ -28,13 +27,35 @@ namespace Avalonia.Markup.Xaml } } + /// + /// Loads XAML from a stream. + /// + /// The stream containing the XAML. + /// Default assembly for clr-namespace: + /// The optional instance into which the XAML should be loaded. + /// The URI of the XAML being loaded. + /// Indicates whether the XAML is being loaded in design mode. + /// The loaded object. public static object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null, bool designMode = false) => AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri, designMode); + /// + /// Parse XAML from a string. + /// + /// The string containing the XAML. + /// Default assembly for clr-namespace:. + /// The loaded object. public static object Parse(string xaml, Assembly localAssembly = null) => Load(xaml, localAssembly); + /// + /// Parse XAML from a string. + /// + /// The type of the returned object. + /// >The string containing the XAML. + /// >Default assembly for clr-namespace:. + /// The loaded object. public static T Parse(string xaml, Assembly localAssembly = null) => (T)Parse(xaml, localAssembly); diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs index 59292d605c..ace658654d 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs @@ -323,7 +323,6 @@ namespace Avalonia.Direct2D1.Media /// /// The foreground. /// The glyph run. - /// public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun) { using (var brush = CreateBrush(foreground, glyphRun.Size)) diff --git a/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs b/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs index 1b01ebbe7f..88b907aeec 100644 --- a/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs +++ b/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs @@ -13,6 +13,7 @@ namespace Avalonia.Win32.Interop /// /// Ported from https://github.com/chromium/chromium/blob/master/ui/views/win/fullscreen_handler.cc /// + /// The window handle. /// Fullscreen state. public static unsafe void MarkFullscreen(IntPtr hwnd, bool fullscreen) { From c98918bc2afc97da3692a616bf5e74db393523a9 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 17 Oct 2020 10:38:17 +0200 Subject: [PATCH 078/115] Update tests --- .../AnimatableTests.cs | 8 +- .../AvaloniaObjectTests_Metadata.cs | 4 +- .../Collections/AvaloniaListExtenionsTests.cs | 4 + .../Data/Core/BindingExpressionTests.cs | 2 +- .../Data/DefaultValueConverterTests.cs | 14 ++-- tests/Avalonia.Benchmarks/NullRenderer.cs | 3 +- .../NullThreadingPlatform.cs | 3 + .../BorderTests.cs | 2 +- .../Avalonia.Controls.UnitTests/PanelTests.cs | 2 +- .../DefaultMenuInteractionHandlerTests.cs | 10 +-- .../ContentPresenterTests_Standalone.cs | 2 +- .../TextBlockTests.cs | 4 +- .../App.xaml.cs | 13 ++-- .../Program.cs | 20 ++--- .../LayoutableTests.cs | 6 +- ...ayoutableTests_EffectiveViewportChanged.cs | 2 + tests/Avalonia.LeakTests/ControlTests.cs | 7 +- ...ExpressionObserverBuilderTests_Negation.cs | 15 +++- .../Avalonia.RenderTests/Media/BitmapTests.cs | 2 + .../ResourceDictionaryTests.cs | 12 +-- .../SelectorTests_Child.cs | 75 ------------------- .../SelectorTests_Descendent.cs | 74 ------------------ .../Avalonia.Styling.UnitTests/StyleTests.cs | 2 +- .../Avalonia.Styling.UnitTests/StylesTests.cs | 8 +- .../Rendering/DeferredRendererTests.cs | 2 +- .../Avalonia.Visuals.UnitTests/VisualTests.cs | 2 +- 26 files changed, 86 insertions(+), 212 deletions(-) diff --git a/tests/Avalonia.Animation.UnitTests/AnimatableTests.cs b/tests/Avalonia.Animation.UnitTests/AnimatableTests.cs index 784f40fe1f..7633a761a3 100644 --- a/tests/Avalonia.Animation.UnitTests/AnimatableTests.cs +++ b/tests/Avalonia.Animation.UnitTests/AnimatableTests.cs @@ -113,7 +113,7 @@ namespace Avalonia.Animation.UnitTests It.IsAny(), 1.0, 0.5)); - target.ResetCalls(); + target.Invocations.Clear(); control.SetValue(Visual.OpacityProperty, 0.8, BindingPriority.StyleTrigger); @@ -135,7 +135,7 @@ namespace Avalonia.Animation.UnitTests target.Setup(x => x.Apply(control, It.IsAny(), 1.0, 0.5)).Returns(sub.Object); control.Opacity = 0.5; - sub.ResetCalls(); + sub.Invocations.Clear(); control.Opacity = 0.4; sub.Verify(x => x.Dispose()); @@ -158,7 +158,7 @@ namespace Avalonia.Animation.UnitTests control.Opacity = 0.5; Assert.Equal(0.9, control.Opacity); - target.ResetCalls(); + target.Invocations.Clear(); control.Opacity = 0.4; @@ -182,7 +182,7 @@ namespace Avalonia.Animation.UnitTests It.IsAny(), 1.0, 0.5)); - target.ResetCalls(); + target.Invocations.Clear(); var root = (TestRoot)control.Parent; root.Child = null; diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Metadata.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Metadata.cs index 161911dfd5..2edb3deff0 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Metadata.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Metadata.cs @@ -67,7 +67,7 @@ namespace Avalonia.Base.UnitTests public static readonly DirectProperty DirectProperty = AvaloniaProperty.RegisterDirect("Styled", o => o.Direct, unsetValue: "foo"); - private string _direct; + private string _direct = default; public string Direct { @@ -92,7 +92,7 @@ namespace Avalonia.Base.UnitTests public static readonly DirectProperty DirectProperty = Class1.DirectProperty.AddOwner(o => o.Direct, unsetValue: "baz"); - private string _direct; + private string _direct = default; static Class3() { diff --git a/tests/Avalonia.Base.UnitTests/Collections/AvaloniaListExtenionsTests.cs b/tests/Avalonia.Base.UnitTests/Collections/AvaloniaListExtenionsTests.cs index 7f118a2c1d..b1b2d3d8f2 100644 --- a/tests/Avalonia.Base.UnitTests/Collections/AvaloniaListExtenionsTests.cs +++ b/tests/Avalonia.Base.UnitTests/Collections/AvaloniaListExtenionsTests.cs @@ -6,10 +6,12 @@ namespace Avalonia.Base.UnitTests.Collections { public class AvaloniaListExtenionsTests { +#pragma warning disable CS0618 // Type or member is obsolete [Fact] public void CreateDerivedList_Creates_Initial_Items() { var source = new AvaloniaList(new[] { 0, 1, 2, 3 }); + var target = source.CreateDerivedList(x => new Wrapper(x)); var result = target.Select(x => x.Value).ToList(); @@ -137,6 +139,8 @@ namespace Avalonia.Base.UnitTests.Collections Assert.Equal(source, result); } +#pragma warning restore CS0618 // Type or member is obsolete + private class Wrapper { diff --git a/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.cs b/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.cs index 1e1f4bd4b2..339cf8a334 100644 --- a/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.cs +++ b/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.cs @@ -356,7 +356,7 @@ namespace Avalonia.Base.UnitTests.Data.Core } [Fact] - public async Task Null_Value_Should_Use_TargetNullValue() + public void Null_Value_Should_Use_TargetNullValue() { var data = new Class1 { StringValue = "foo" }; diff --git a/tests/Avalonia.Base.UnitTests/Data/DefaultValueConverterTests.cs b/tests/Avalonia.Base.UnitTests/Data/DefaultValueConverterTests.cs index efa81dcc1b..f522acf9ce 100644 --- a/tests/Avalonia.Base.UnitTests/Data/DefaultValueConverterTests.cs +++ b/tests/Avalonia.Base.UnitTests/Data/DefaultValueConverterTests.cs @@ -1,12 +1,11 @@ +using System; +using System.ComponentModel; using System.Globalization; -using Avalonia.Controls; -using Avalonia.Data; -using Xunit; using System.Windows.Input; -using System; +using Avalonia.Data; using Avalonia.Data.Converters; using Avalonia.Layout; -using System.ComponentModel; +using Xunit; namespace Avalonia.Base.UnitTests.Data.Converters { @@ -251,6 +250,11 @@ namespace Avalonia.Base.UnitTests.Data.Converters { return obj is CustomType other && this.Value == other.Value; } + + public override int GetHashCode() + { + return 8399587^Value.GetHashCode(); + } } private class CustomTypeConverter : TypeConverter diff --git a/tests/Avalonia.Benchmarks/NullRenderer.cs b/tests/Avalonia.Benchmarks/NullRenderer.cs index 9a756aaf0b..c1701b5d57 100644 --- a/tests/Avalonia.Benchmarks/NullRenderer.cs +++ b/tests/Avalonia.Benchmarks/NullRenderer.cs @@ -9,8 +9,9 @@ namespace Avalonia.Benchmarks { public bool DrawFps { get; set; } public bool DrawDirtyRects { get; set; } +#pragma warning disable CS0067 public event EventHandler SceneInvalidated; - +#pragma warning restore CS0067 public void AddDirty(IVisual visual) { } diff --git a/tests/Avalonia.Benchmarks/NullThreadingPlatform.cs b/tests/Avalonia.Benchmarks/NullThreadingPlatform.cs index ba84b5afcc..bb469a6b33 100644 --- a/tests/Avalonia.Benchmarks/NullThreadingPlatform.cs +++ b/tests/Avalonia.Benchmarks/NullThreadingPlatform.cs @@ -23,6 +23,9 @@ namespace Avalonia.Benchmarks public bool CurrentThreadIsLoopThread => true; +#pragma warning disable CS0067 public event Action Signaled; +#pragma warning restore CS0067 + } } diff --git a/tests/Avalonia.Controls.UnitTests/BorderTests.cs b/tests/Avalonia.Controls.UnitTests/BorderTests.cs index 6e2599c9fd..ab33eaaff9 100644 --- a/tests/Avalonia.Controls.UnitTests/BorderTests.cs +++ b/tests/Avalonia.Controls.UnitTests/BorderTests.cs @@ -54,7 +54,7 @@ namespace Avalonia.Controls.UnitTests var root = new TestRoot(target); var renderer = Mock.Get(root.Renderer); - renderer.ResetCalls(); + renderer.Invocations.Clear(); ((SolidColorBrush)target.Background).Color = Colors.Green; diff --git a/tests/Avalonia.Controls.UnitTests/PanelTests.cs b/tests/Avalonia.Controls.UnitTests/PanelTests.cs index 79ee6d1236..f189638c7d 100644 --- a/tests/Avalonia.Controls.UnitTests/PanelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/PanelTests.cs @@ -127,7 +127,7 @@ namespace Avalonia.Controls.UnitTests var root = new TestRoot(target); var renderer = Mock.Get(root.Renderer); - renderer.ResetCalls(); + renderer.Invocations.Clear(); ((SolidColorBrush)target.Background).Color = Colors.Green; diff --git a/tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs b/tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs index 64f35049ce..1a11091b81 100644 --- a/tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs @@ -503,26 +503,26 @@ namespace Avalonia.Controls.UnitTests.Platform target.PointerEnter(item, enter); Assert.True(timer.ActionIsQueued); Mock.Get(parentItem).VerifySet(x => x.SelectedItem = item); - Mock.Get(parentItem).ResetCalls(); + Mock.Get(parentItem).Invocations.Clear(); // SubMenu shown after a delay. timer.Pulse(); Mock.Get(item).Verify(x => x.Open()); Mock.Get(item).SetupGet(x => x.IsSubMenuOpen).Returns(true); - Mock.Get(item).ResetCalls(); + Mock.Get(item).Invocations.Clear(); // Pointer briefly exits item, but submenu remains open. target.PointerLeave(item, leave); Mock.Get(item).Verify(x => x.Close(), Times.Never); - Mock.Get(item).ResetCalls(); + Mock.Get(item).Invocations.Clear(); // Pointer enters child item; is selected. enter.Source = childItem; target.PointerEnter(childItem, enter); Mock.Get(item).VerifySet(x => x.SelectedItem = childItem); Mock.Get(parentItem).VerifySet(x => x.SelectedItem = item); - Mock.Get(item).ResetCalls(); - Mock.Get(parentItem).ResetCalls(); + Mock.Get(item).Invocations.Clear(); + Mock.Get(parentItem).Invocations.Clear(); } [Fact] diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Standalone.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Standalone.cs index c0440ebc7b..c7aa583b6f 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Standalone.cs +++ b/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Standalone.cs @@ -212,7 +212,7 @@ namespace Avalonia.Controls.UnitTests.Presenters var root = new TestRoot(target); var renderer = Mock.Get(root.Renderer); - renderer.ResetCalls(); + renderer.Invocations.Clear(); ((SolidColorBrush)target.Background).Color = Colors.Green; diff --git a/tests/Avalonia.Controls.UnitTests/TextBlockTests.cs b/tests/Avalonia.Controls.UnitTests/TextBlockTests.cs index 2d2c197220..b180a536a5 100644 --- a/tests/Avalonia.Controls.UnitTests/TextBlockTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TextBlockTests.cs @@ -37,7 +37,7 @@ namespace Avalonia.Controls.UnitTests var root = new TestRoot(target); var renderer = Mock.Get(root.Renderer); - renderer.ResetCalls(); + renderer.Invocations.Clear(); ((SolidColorBrush)target.Background).Color = Colors.Green; @@ -54,7 +54,7 @@ namespace Avalonia.Controls.UnitTests var root = new TestRoot(target); var renderer = Mock.Get(root.Renderer); - renderer.ResetCalls(); + renderer.Invocations.Clear(); ((SolidColorBrush)target.Foreground).Color = Colors.Green; diff --git a/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs b/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs index 653a51232b..97b6b9021a 100644 --- a/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs +++ b/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; namespace Avalonia.DesignerSupport.TestApp @@ -13,5 +9,12 @@ namespace Avalonia.DesignerSupport.TestApp { AvaloniaXamlLoader.Load(this); } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + desktop.MainWindow = new MainWindow(); + base.OnFrameworkInitializationCompleted(); + } } } diff --git a/tests/Avalonia.DesignerSupport.TestApp/Program.cs b/tests/Avalonia.DesignerSupport.TestApp/Program.cs index c7c60a4eca..b8428511b3 100644 --- a/tests/Avalonia.DesignerSupport.TestApp/Program.cs +++ b/tests/Avalonia.DesignerSupport.TestApp/Program.cs @@ -1,24 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Avalonia.Controls; - -namespace Avalonia.DesignerSupport.TestApp +namespace Avalonia.DesignerSupport.TestApp { static class Program { /// /// The main entry point for the application. /// - static void Main() - { - BuildAvaloniaApp().Start(); - } + public static int Main(string[] args) + => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); - private static AppBuilder BuildAvaloniaApp() - { - return AppBuilder.Configure().UsePlatformDetect(); - } + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure().UsePlatformDetect(); } } diff --git a/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs b/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs index 44a5af94b9..a8aa0bbf0e 100644 --- a/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs +++ b/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs @@ -112,7 +112,7 @@ namespace Avalonia.Layout.UnitTests root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); - target.ResetCalls(); + target.Invocations.Clear(); control.InvalidateMeasure(); control.InvalidateMeasure(); @@ -133,7 +133,7 @@ namespace Avalonia.Layout.UnitTests root.Measure(Size.Infinity); root.Arrange(new Rect(root.DesiredSize)); - target.ResetCalls(); + target.Invocations.Clear(); control.InvalidateArrange(); control.InvalidateArrange(); @@ -163,7 +163,7 @@ namespace Avalonia.Layout.UnitTests Assert.False(control.IsMeasureValid); Assert.True(root.IsMeasureValid); - target.ResetCalls(); + target.Invocations.Clear(); root.Child = control; diff --git a/tests/Avalonia.Layout.UnitTests/LayoutableTests_EffectiveViewportChanged.cs b/tests/Avalonia.Layout.UnitTests/LayoutableTests_EffectiveViewportChanged.cs index 504e3fa585..f1cec24516 100644 --- a/tests/Avalonia.Layout.UnitTests/LayoutableTests_EffectiveViewportChanged.cs +++ b/tests/Avalonia.Layout.UnitTests/LayoutableTests_EffectiveViewportChanged.cs @@ -15,7 +15,9 @@ namespace Avalonia.Layout.UnitTests [Fact] public async Task EffectiveViewportChanged_Not_Raised_When_Control_Added_To_Tree() { +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously await RunOnUIThread.Execute(async () => +#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously { var root = CreateRoot(); var target = new Canvas(); diff --git a/tests/Avalonia.LeakTests/ControlTests.cs b/tests/Avalonia.LeakTests/ControlTests.cs index 0c7b966f29..b03ae00cfe 100644 --- a/tests/Avalonia.LeakTests/ControlTests.cs +++ b/tests/Avalonia.LeakTests/ControlTests.cs @@ -460,7 +460,7 @@ namespace Avalonia.LeakTests AttachShowAndDetachContextMenu(window); - Mock.Get(window.PlatformImpl).ResetCalls(); + Mock.Get(window.PlatformImpl).Invocations.Clear(); dotMemory.Check(memory => Assert.Equal(initialMenuCount, memory.GetObjects(where => where.Type.Is()).ObjectsCount)); dotMemory.Check(memory => @@ -505,7 +505,7 @@ namespace Avalonia.LeakTests BuildAndShowContextMenu(window); BuildAndShowContextMenu(window); - Mock.Get(window.PlatformImpl).ResetCalls(); + Mock.Get(window.PlatformImpl).Invocations.Clear(); dotMemory.Check(memory => Assert.Equal(initialMenuCount, memory.GetObjects(where => where.Type.Is()).ObjectsCount)); dotMemory.Check(memory => @@ -601,8 +601,9 @@ namespace Avalonia.LeakTests { public bool DrawFps { get; set; } public bool DrawDirtyRects { get; set; } +#pragma warning disable CS0067 public event EventHandler SceneInvalidated; - +#pragma warning restore CS0067 public void AddDirty(IVisual visual) { } diff --git a/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionObserverBuilderTests_Negation.cs b/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionObserverBuilderTests_Negation.cs index 0be3bbbb9f..0028502eeb 100644 --- a/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionObserverBuilderTests_Negation.cs +++ b/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionObserverBuilderTests_Negation.cs @@ -168,10 +168,23 @@ namespace Avalonia.Markup.UnitTests.Parsers private class Test : INotifyDataErrorInfo { + private string _dataValidationError; + public bool Foo { get; set; } public object Bar { get; set; } - public string DataValidationError { get; set; } + public string DataValidationError + { + get => _dataValidationError; + set + { + if (value == _dataValidationError) + return; + _dataValidationError = value; + ErrorsChanged? + .Invoke(this, new DataErrorsChangedEventArgs(nameof(DataValidationError))); + } + } public bool HasErrors => !string.IsNullOrWhiteSpace(DataValidationError); public event EventHandler ErrorsChanged; diff --git a/tests/Avalonia.RenderTests/Media/BitmapTests.cs b/tests/Avalonia.RenderTests/Media/BitmapTests.cs index d52539c371..b629304b77 100644 --- a/tests/Avalonia.RenderTests/Media/BitmapTests.cs +++ b/tests/Avalonia.RenderTests/Media/BitmapTests.cs @@ -102,7 +102,9 @@ namespace Avalonia.Direct2D1.RenderTests.Media [InlineData(PixelFormat.Bgra8888), InlineData(PixelFormat.Rgba8888)] public void WriteableBitmapShouldBeUsable(PixelFormat fmt) { +#pragma warning disable CS0618 // Type or member is obsolete var writeableBitmap = new WriteableBitmap(new PixelSize(256, 256), new Vector(96, 96), fmt); +#pragma warning restore CS0618 // Type or member is obsolete var data = new int[256 * 256]; for (int y = 0; y < 256; y++) diff --git a/tests/Avalonia.Styling.UnitTests/ResourceDictionaryTests.cs b/tests/Avalonia.Styling.UnitTests/ResourceDictionaryTests.cs index 84b0d09b61..d91d1fab9e 100644 --- a/tests/Avalonia.Styling.UnitTests/ResourceDictionaryTests.cs +++ b/tests/Avalonia.Styling.UnitTests/ResourceDictionaryTests.cs @@ -108,7 +108,7 @@ namespace Avalonia.Styling.UnitTests var target = new ResourceDictionary { { "foo", "bar" } }; ((IResourceProvider)target).AddOwner(host.Object); - host.ResetCalls(); + host.Invocations.Clear(); ((IResourceProvider)target).RemoveOwner(host.Object); host.Verify(x => x.NotifyHostedResourcesChanged(It.IsAny())); @@ -120,7 +120,7 @@ namespace Avalonia.Styling.UnitTests var host = new Mock(); var target = new ResourceDictionary(host.Object); - host.ResetCalls(); + host.Invocations.Clear(); target.Add("foo", "bar"); host.Verify(x => x.NotifyHostedResourcesChanged(It.IsAny())); @@ -132,7 +132,7 @@ namespace Avalonia.Styling.UnitTests var host = new Mock(); var target = new ResourceDictionary(host.Object); - host.ResetCalls(); + host.Invocations.Clear(); target.MergedDictionaries.Add(new ResourceDictionary { { "foo", "bar" }, @@ -149,7 +149,7 @@ namespace Avalonia.Styling.UnitTests var host = new Mock(); var target = new ResourceDictionary(host.Object); - host.ResetCalls(); + host.Invocations.Clear(); target.MergedDictionaries.Add(new ResourceDictionary()); host.Verify( @@ -169,7 +169,7 @@ namespace Avalonia.Styling.UnitTests } }; - host.ResetCalls(); + host.Invocations.Clear(); target.MergedDictionaries.RemoveAt(0); host.Verify( @@ -189,7 +189,7 @@ namespace Avalonia.Styling.UnitTests } }; - host.ResetCalls(); + host.Invocations.Clear(); ((IResourceDictionary)target.MergedDictionaries[0]).Add("foo", "bar"); host.Verify( diff --git a/tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs b/tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs index 8ae556cc6f..d011c16ebb 100644 --- a/tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs +++ b/tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs @@ -1,12 +1,7 @@ -using System; using System.Collections.Generic; -using System.Linq; -using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; -using Avalonia.Collections; using Avalonia.Controls; -using Avalonia.Data; using Avalonia.LogicalTree; using Xunit; @@ -85,76 +80,6 @@ namespace Avalonia.Styling.UnitTests get => Parent; set => ((ISetLogicalParent)this).SetParent(value); } - - public void ClearValue(AvaloniaProperty property) - { - throw new NotImplementedException(); - } - - public void ClearValue(AvaloniaProperty property) - { - throw new NotImplementedException(); - } - - public void AddInheritanceChild(IAvaloniaObject child) - { - throw new NotImplementedException(); - } - - public void RemoveInheritanceChild(IAvaloniaObject child) - { - throw new NotImplementedException(); - } - - public void InheritanceParentChanged(StyledPropertyBase property, IAvaloniaObject oldParent, IAvaloniaObject newParent) - { - throw new NotImplementedException(); - } - - public void InheritedPropertyChanged(AvaloniaProperty property, Optional oldValue, Optional newValue) - { - throw new NotImplementedException(); - } - - public void ClearValue(StyledPropertyBase property) - { - throw new NotImplementedException(); - } - - public void ClearValue(DirectPropertyBase property) - { - throw new NotImplementedException(); - } - - public T GetValue(StyledPropertyBase property) - { - throw new NotImplementedException(); - } - - public T GetValue(DirectPropertyBase property) - { - throw new NotImplementedException(); - } - - public void SetValue(StyledPropertyBase property, T value, BindingPriority priority = BindingPriority.LocalValue) - { - throw new NotImplementedException(); - } - - public void SetValue(DirectPropertyBase property, T value) - { - throw new NotImplementedException(); - } - - public IDisposable Bind(StyledPropertyBase property, IObservable> source, BindingPriority priority = BindingPriority.LocalValue) - { - throw new NotImplementedException(); - } - - public IDisposable Bind(DirectPropertyBase property, IObservable> source) - { - throw new NotImplementedException(); - } } public class TestLogical1 : TestLogical diff --git a/tests/Avalonia.Styling.UnitTests/SelectorTests_Descendent.cs b/tests/Avalonia.Styling.UnitTests/SelectorTests_Descendent.cs index 81485f0345..aacf2ce223 100644 --- a/tests/Avalonia.Styling.UnitTests/SelectorTests_Descendent.cs +++ b/tests/Avalonia.Styling.UnitTests/SelectorTests_Descendent.cs @@ -1,11 +1,7 @@ -using System; using System.Linq; -using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; -using Avalonia.Collections; using Avalonia.Controls; -using Avalonia.Data; using Avalonia.LogicalTree; using Xunit; @@ -115,76 +111,6 @@ namespace Avalonia.Styling.UnitTests get => Parent; set => ((ISetLogicalParent)this).SetParent(value); } - - public void ClearValue(AvaloniaProperty property) - { - throw new NotImplementedException(); - } - - public void ClearValue(AvaloniaProperty property) - { - throw new NotImplementedException(); - } - - public void AddInheritanceChild(IAvaloniaObject child) - { - throw new NotImplementedException(); - } - - public void RemoveInheritanceChild(IAvaloniaObject child) - { - throw new NotImplementedException(); - } - - public void InheritanceParentChanged(StyledPropertyBase property, IAvaloniaObject oldParent, IAvaloniaObject newParent) - { - throw new NotImplementedException(); - } - - public void InheritedPropertyChanged(AvaloniaProperty property, Optional oldValue, Optional newValue) - { - throw new NotImplementedException(); - } - - public void ClearValue(StyledPropertyBase property) - { - throw new NotImplementedException(); - } - - public void ClearValue(DirectPropertyBase property) - { - throw new NotImplementedException(); - } - - public T GetValue(StyledPropertyBase property) - { - throw new NotImplementedException(); - } - - public T GetValue(DirectPropertyBase property) - { - throw new NotImplementedException(); - } - - public void SetValue(StyledPropertyBase property, T value, BindingPriority priority = BindingPriority.LocalValue) - { - throw new NotImplementedException(); - } - - public void SetValue(DirectPropertyBase property, T value) - { - throw new NotImplementedException(); - } - - public IDisposable Bind(StyledPropertyBase property, IObservable> source, BindingPriority priority = BindingPriority.LocalValue) - { - throw new NotImplementedException(); - } - - public IDisposable Bind(DirectPropertyBase property, IObservable> source) - { - throw new NotImplementedException(); - } } public class TestLogical1 : TestLogical diff --git a/tests/Avalonia.Styling.UnitTests/StyleTests.cs b/tests/Avalonia.Styling.UnitTests/StyleTests.cs index 3e2bd68cf0..df94887340 100644 --- a/tests/Avalonia.Styling.UnitTests/StyleTests.cs +++ b/tests/Avalonia.Styling.UnitTests/StyleTests.cs @@ -443,7 +443,7 @@ namespace Avalonia.Styling.UnitTests var resources = new Mock(); target.Resources = resources.Object; - host.ResetCalls(); + host.Invocations.Clear(); ((IResourceProvider)target).AddOwner(host.Object); resources.Verify(x => x.AddOwner(host.Object), Times.Once); } diff --git a/tests/Avalonia.Styling.UnitTests/StylesTests.cs b/tests/Avalonia.Styling.UnitTests/StylesTests.cs index 9d3704c91d..88ab124e01 100644 --- a/tests/Avalonia.Styling.UnitTests/StylesTests.cs +++ b/tests/Avalonia.Styling.UnitTests/StylesTests.cs @@ -15,7 +15,7 @@ namespace Avalonia.Styling.UnitTests var style = new Mock(); var rp = style.As(); - host.ResetCalls(); + host.Invocations.Clear(); target.Add(style.Object); rp.Verify(x => x.AddOwner(host.Object)); @@ -29,7 +29,7 @@ namespace Avalonia.Styling.UnitTests var style = new Mock(); var rp = style.As(); - host.ResetCalls(); + host.Invocations.Clear(); target.Add(style.Object); target.Remove(style.Object); @@ -58,7 +58,7 @@ namespace Avalonia.Styling.UnitTests var resources = new Mock(); target.Resources = resources.Object; - host.ResetCalls(); + host.Invocations.Clear(); ((IResourceProvider)target).AddOwner(host.Object); resources.Verify(x => x.AddOwner(host.Object), Times.Once); } @@ -87,7 +87,7 @@ namespace Avalonia.Styling.UnitTests var resourceProvider = style.As(); target.Add(style.Object); - host.ResetCalls(); + host.Invocations.Clear(); ((IResourceProvider)target).AddOwner(host.Object); resourceProvider.Verify(x => x.AddOwner(host.Object), Times.Once); } diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs index bfcc341eed..e58eea42d8 100644 --- a/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs @@ -756,7 +756,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering private void IgnoreFirstFrame(IRenderLoopTask task, Mock sceneBuilder) { RunFrame(task); - sceneBuilder.ResetCalls(); + sceneBuilder.Invocations.Clear(); } private void RunFrame(IRenderLoopTask task) diff --git a/tests/Avalonia.Visuals.UnitTests/VisualTests.cs b/tests/Avalonia.Visuals.UnitTests/VisualTests.cs index 97ad608346..447a68aa69 100644 --- a/tests/Avalonia.Visuals.UnitTests/VisualTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/VisualTests.cs @@ -173,7 +173,7 @@ namespace Avalonia.Visuals.UnitTests }; root.Child = child; - renderer.ResetCalls(); + renderer.Invocations.Clear(); root.Child = null; renderer.Verify(x => x.AddDirty(child)); From 5a4a172652444c1e39d3da18ebbd76e8af14528f Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 17 Oct 2020 10:43:04 +0200 Subject: [PATCH 079/115] fix NU5040 --- azure-pipelines.yml | 4 ++++ build/Assets/Icon.png | Bin 0 -> 14349 bytes build/SharedVersion.props | 6 +++++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 build/Assets/Icon.png diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 721a0415f4..e67fa14c57 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -31,6 +31,8 @@ jobs: condition: not(canceled()) - job: macOS + variables: + SolutionDir: '$(Build.SourcesDirectory)' pool: vmImage: 'macOS-10.14' steps: @@ -97,6 +99,8 @@ jobs: - job: Windows pool: vmImage: 'windows-2019' + variables: + SolutionDir: '$(Build.SourcesDirectory)' steps: - task: UseDotNet@2 displayName: 'Use .NET Core SDK 3.1.401' diff --git a/build/Assets/Icon.png b/build/Assets/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..41a2a618fb02e4cb7f6a15caf572b693bfe1ebb1 GIT binary patch literal 14349 zcmdtJ^EU0vMF0h26NSCC5pomCGr^Esh3km|#NF&{iw9?Wnjl|N@ z`CNWJ_xJlef5G#^&FjT4v*$W9bLKr~&Ybg}2rW%D5<&(-5C}x_NFAXA0)gZH{o~^T zErD&~zd#^~-;WTAdY)f*(0E^|PA(JdJoCHg9rW(}-q6s{ z#*KHDghqFB4W6%q0k{gg|^3gd>rC)VTQMFLhj#M%Yxxfs$Hp@c8So3dxQzuFO6D`+4HKNdX3 zU$5ATBk*Iq3h=^S&l?Fl7GP}W<6 z!%2fSTZ=YX;Xa}7q3U>`3qD>$uw??ic;UcQ;9H#~hXP-|5dmoD!@!eAn4`WPE8Fhp zy2m^eUcq1`spUO?vi%Bn9Z$EuO(AZVukaXyO(D>WJHqBYfuJ(b8>&849Qm+KnMB)` z7Tegq#og}ib#n=|-&DBx7egWPvHNLcUtf2*)w1R@*xP~qm)tG5^s?F&uss>G895?J z)+xMi{%i;=thrkw+=bwr#awz1G8)#-%fBfEt2^N|VoCnOw900JZowTqgkDlMYoE1; zEv{Rqo@$o^(wJYH&%NWxF}z|GBjw)U#@H!2+d=_qPn@{V%UW(TeRfd_$Bk@+G`RR) zL-J0qFyb-;P0Gizoc!4D3Z~>PwAY=fEO8Kqo2S=yJ>MHGqo(Av-&zO8J$#UH^E)UT zb&Dm(0x#p0AK5jO0X1_5Km7UQW&hyM$hM96gmRU=i7b#S~P_+Dt;c71rc67ek^I{8e} z!&O^D5YEY$m!>;AL+4NcN&?wq+!faB^Wllyf_BG|w>-^n!>+@@N?anv!@5_7tS84ald_T6RH$cUk@E2iz0pV~`iDy(+ATb$#M)FF6Yr7Guh z=v|hYwbKJ)Gkh~wJKOBC(jZ7jnpp;DF)0ZS?Y}>K5@5o*?Jn}kkB;@zCwlbb=PGkX zhG0&DP5NcUYQ?PaI*$>B0|qlaT1ZGrH$S)IoHXwg79GwKXt{_Ik)bTaUX7lYaB)8* zElXwFcjkddrx+h2uG9;zy+hq0*gjKcJx~Jf8wplQq9c>xd#yVG9$sh?ukhy}7aKC( zL8lu&e#7p2SUZMdh72V_#3=Yx5`NxB`18eKR)Pnumt2}#?PDW7PwSuHv=#b1Et;hc zWm7t&I-jPfs5|w%BA=^`2Bz}o;PbPlr`ylHztg2*cSPvBt{9Sq;fpOl{kch!V?gTL zjZx(kIWKznMCuBa^O0Z}`yD?+1c@M`fF9ek5ysSbn`g&AyXh|Q$=tUaZ~C_@O-%&i zNR?s8zF@(I}S`XI==cb(a8iJ`ktce_D^p+ zlg0bW)|hNy>aP#T=s}cG%+flgBeEa`7Y4&jZ)P>vC-O*IJ|n|e@7ou9lSfjmjjmrD z=L{5Qv~won7k{@r=2s4>Y=2Mwk=s~)$-j(|?d*JDNZaG|_J++sofd4e)~t;ONOV*& z2qndG@!Xb8MQa_M7Y!+Tq+i$v1Py`94Obc61reN#z65=ra}1B~ssIU>^T;8#1fO3{ zwEY6te1RSA8zP84JgSkVT9w)bnpCuk+VKD zBm&xUs4&V_B9?1a-7MZ{La}I;)j_aF`pL*$m8JOvdO3(g!Da5?R7~TX++u)JvDf~$ ziO9*$eOj-7vQ9XDzxch`m@4I)bg8V1|5Ur#jQo?8q{t%Hh3CD&T$~OzcRHP}@J#3L zR0RZB7QimQz?-BT(e$uS?6(wL(_))>3Ko~8z(kaNPcBE!tC*!H===!dK42VsS04Zn zV3#NCFco!CIh-?>P&)J^?y}pHbRF&P*^B~_#>k{By({m$5sD0}D>Lr2hOGs$s9LoM z*X+l;w!95l5rX@!#bo0-1$MjuIlkTyMsPxBu`YjqYK^@a!>AU}oZUNb-x;d<+iE}e zni+v7;c!ObVW-VcnPyb!+b$V&U>4qc{(8_wci8y%OSOg`)q6Lu{|F(Fg(PJQZlLS4&wa`m3AkGySA9ZT-v&{T%CWaU z`Ye*WoDm7g)N$zCuEtktw4OGiSXX#NiDp!YVyQoGfS7{ocZHNg`Z{D7gzWxCwkG!) z+9ehel9gbu1#A!5A)#X1lty{On;Ve|hrp-HJR(uQ!|;lJuy?2?vMH^tWpHoGyu1h` zYkteY>B+2~Sl@EinULwJ?GcVgk)f7FqR=v3@>kq59e=%6S*7MpPpn4laU&|zGSDVy zZuslsDDpeDn}w(c`%fsF3oD*#&g4LZg4fEsG8qD_J=%lmdo8rg)S<1|9k(^E3Df8w zXk&z?JaKsL8Pe|Rt{0=~La)ZkTp9I;nMvP_)G}a-9TI~;er2MM*e0sFl&xu-ie3}O zMXK#&&s?<|4Hs@&@hudH{FBgSqaJ=Ddxj!4mxwQ>V`VOHl5Gx8IjACJG8B7=!{{D{ zk4n((Y$Cj~q2=QRMr=xT)EJc6(7K4mDJ8kZQm+fs(0%tYxEF!kmZ@&%md(3bT21=& z`SYQf8lf|Gyf*i}+S+snR)xoNeSz%c*|=2F<-0|c54_Q8-Fm6M>B#l~OV zqkqStq!)WEc@^GmA#hiJOj0J(Pwm@n+gIB1=i0Q(yILxBGvz)pxx`8RW8IwW#J=vF z#Iw5uU}jjYv%;39`(7=|`Ycm}!{@4LY)X2IG}Plhzm8Vi%_UYme7}85Hgj8C9<@Jz z3i9!()dm){o4mWn#V8+rechefyw^SK36+c9$qo%2wco5T@@)SJLCcnFQmNsDhj(9B zxLI<=Lh3*ej_B;X6?0G;#&NqSz!E7r2~iFaRt}VBY$HJLxwH89IQyr}&$AiDG zXtJ!A`Psl+FB2uKr1GtP?cz4p3yows{QMbr)%({jcj9f$QKr{wYU4Hw9W3Ug9h&uV z`c3wqj}-z`Z5!_F{y)r&xZYb2FS929?^WeJq;MRP_}T)KtZJ!;2#FjJNuG`1up8?zr`iQ_PbnuJ+wLzX*a3wg#~X zRUSiGASPtzLqB6poi#PVNgji%(JiUpIu_#dJnRnHTj$eM(&r>7#E7T{Jm?17L63su z>elXX+qr67O=w`U;fB@Zyp97;2VBXqpgj;V8fst5hA zf+9&5=egS-iH&dJlkW|^&SeHXnLL)8shUBog;dzyDEw_iz3C!H5{bY0IkqVaXAHrUq*zuDap`BK5I^%qBWhm+ z)|VGw-A;jAOeRhzygnpsLkrWoq0S|EVff#|;X@fNrz=6`XQ*gN^JimETlN-cA6%1x zd?tPs&yKHN>$!L&{`3ayG_&4@<0TVI-}+|cWf^1t1EwGjjne+WJ!%P_5A4A3SJXpf zo#9@&mS3ly+Ay|uKkl4UlP2#SSNcFr``5}{Xyd}N zUTD^ib4NAcrl&CvDsg)M3<_q?eKf!^xb*>%z8c!Q|IWj}d)uo{#z7>|o>#4iS?n~* zfetPc-udZjVTNX=DZ%Xh%Px#+^PhJ&4~oiIKPfOV5RvJ%J^SpfAob+c8WYpdioabjrN4(7A(T4R1zQ#HFY+lweKL+;>J#6U-XWJxl$ zAA(}Aps#m?`aCq>+*@!H3%qK6+vUI%Bx&t*+6k(}qRiX&?$2@W#zQ0#`Z`v;Ab z0?ycDA@95{_yTvfUfO`jRAK2Ki7P!gj_!BKLX3VsX*jta6rc_WB`#iQZ#KShdi!SK zQ}!5yV|bfLMFBnpcFTBjrowk0FGbviFEH8MW95DfoI&XOoFASF#}Qj#XW~cVxMft| zUZG_SLY~$rs(UF`Ci3>M(Q&RP%X6~aaqjia7=aujm#!TI!t+E^ip?dJ*WOtkyMCwx zd<}4~jIOV^a@yCiPZLNye1^n+<1wiTX4dU)K4NLP)2R(tg?)o)C};RHO6z7SQ`JM^ zLBKs>m8$;LuSjr0^WG00;yCQLdt!eBvPTbk^>bny>0p{QvPEYo?!5|_k=yvsB!A4o zQma^&#a8Pw;YBF?JLKILAY4;gq*~jRg%u=8E(^tB!ybs@j&$lV=YSN_J{NhHMQ$In zpA80NdpbK;cTgrn-kKYDHNQ+TJMJv0^-9Gp8sLP>_@HUU%BQ|Z8nA<|djMRulOsQj z<}dmLuBj+sjWBFUt9GD}sorIUMypQ7Ui~`Zczs^FSNvNQ$j$NYh?rSm*$!A-e>5Ju1h5GZtO^)W(8t9i>#52{4>8DSZG)9 znthp1Hr;MHA5$Y%yPUa4{41uQ-y(UvYwt%4?yyH%Z-rwJDUE6aYOuwk6$x!7UxDGv zXo;r3JI#DPyEnzte<8mW)FNaL`fK|Z)bJeT)@#bQg=V)2|9KP&bF#uq1`QIL!XM8_ zb!Xq1H*UZ3)y`LQY$ghidLo9I)#;y#;`_qVFCcj|S^0C1a5kz^>btS)Qb8)0^<(6PLz~KrKD#BmR~i{vh^-&)eY4yh zGO;~^b)Oy;-|lK5O;g@a#{c-;Ns%rS?@Z3_6&`KougE%Sx7S%@wY)t`;N&4-+noM4 zZM;oJ!!~B7Zo-&2_BW65%-wi!vw_@e{v~yKO46)rm$KA8su*}tn; zMJc}Z@ABYbr4^JF25zh1HtMDMZ6||VQOYGeM|1ft-m;}5*u#ozuGF?$9K z45N@edvkYt8D&dKhIpk{`J%n*Me?*N-|Aun#S`zEse3j`OCDCyThf0e+0UQve%+aC z`LyNzYBufU*=Ku}rZ;`zF>TnkUDfj6dW-v9;H1ZmNlb?3C_B>ct(-512(R(GKuJBr z{jDg)Jj^$Lk3?TOLKPno*=EBd-^0b0+Wlb{+{|`RM|? zMsq@?wWzpnc5}9dZ`|H|k)=)33`YYrlPT_3_W zwt1Z=fTX*!LYlq5FM!;nyw8KjuWMO9<+oNap7-^ni>&1>%nXZ>^~JH$Ml>%S?CGEr z2ZBl%?SELL5<{Xr$x!v8-4B|)>(0`k-bLkuR&K-=hwH7Ga?JMyvyJuny0^N%xg~mW z^Y=loDkp|IL0IL=AcwG1{`6mT^S{7}&f!T29n%ZI5~Vd!g)Q+yIh7T1lCzCX>q7v58ggfvy^ zsGPkzSvds!t4a|LKb+M-d;L!A_B!+uFzgiNrrD|m(`BSJ_^3tbXVhI0_w_;|RYi%` z&~6W*d0;!$?k$RKEZ#fA(MjL4com{MgrwPH`mqmvM7_J}j#o%i0HS~26Vd|yN>`_7 zi>xoQ!TwVuv|U;;$bMH;x$CLisQsgzwiq&m zR6cMD>G9oL1rX3~H1-3-tiz=RcA0XxU#E7)Z4cpb6Rti=#os8}R%>!00EYwX0<9~?5p06{n~1FQ|2P^YjaQ6--w*V3^t;XC8_%D zh*C8s38%2xG;`Hf@dcaCUFE}?Sn@mjlRVK{E6qIf3CH5Sq*3o8)dmIGOub*F*#^l| ze&?nhp^zu2wr6$v4jt^4w+;m?=9Yv7sh9wVdx{kZ z10sD9O0nJ;zbwgzt@eCcP30-plf~8sgWjcUSQ^gRSh21i27K(3qP>i|mIanYQ*!5K zeU**gXyqb7IK`J+lm5k*ttMlObi0tvIn6o(BV@DG;kT>+_hvSnp3U`}q=>*p(HSgU z@AxUXTtY}LL6td6i;IIw(-2`=VEwaq`UH=WoHlu@B%E5<*{|#QtC67zEpOTM=~xE^ z?FPlDMJ)K}9~P;AZuJAaKuT*EzTNkH&Zg=el(VOJpwyPPKk7b#Db&X;c)VuxjLbmI z+5yJ=;YcOg!{7)#>wlq*;@X+{*|H(lOu)8O?EZ#3OCfOC7%LHDzpbiyp+QddY|_SEB`NJYp1)ZtZ-uJCd;;W{5WY23;YEGdaBu zS-@^T>Ac^Mf@~2(lV}9^V`}FrPiV2sOahGGh9VQCY3@^a{ld`r?jXt-)p2muiKh2w z*Hue0){lh9e}>efSk+(yM6VljqTy!m?Q+ct6*X|1tf3Pcv7$3fJ}xo>sE%`7ODVsrNv^ z`19L$lTQQvH>MJa->gaaHd*vjI);8C9_=k+7&~u;os%$Ez%HYVINWB+AS>g#+4;8Nh-VZ1PYo7v zoEzi3^RMJYTXWoZZ&EbY!P1Uey`xcK@0n9JP8DC4@_Xq7QTvmTBabw43Xw7$}X|x65rclT8 z!l!Nhv!IJ^t{fjuEkag>@fw`^f(g9v#r@OUD)W0)gpm{eq~ts$PWSEOI5iQ(Q`EFn z({mVR6K)>JT4jR9sctE8tbzGSW+YpZJCkcE<_aRRG`DXwb@#;g)wv--3VWo;`|kDt z@c9r%-naKfU~Z_%B!rM@)14)7sJVK)U==-I#M{h5Ze3-ev41O+!GkjkT5^!@gi zRaVJCj68+*rlrT3sKA7*QX1aRZRn`_rUC&2s|!_hFyZr%uBU6=zFw(9WT#!yu* z(-S+Y{oj6ZjS4ScArVC8cb9Y6-4RT??SIOELB(S0EV+~Mq2$2XlH(W}hWnDov=3u6 zFEuO?hl-ui-tWWuB*fn&WD26#n|318K($`z@I^YFzYibh>zrcazbl#|5mn*a`n2OW zFjrmJEL|3>6p};cf?+IUJV=FlSk=t0=U+F<1^zQV*Xv~K_?F@QfiOoLt&2yz79mJI z|798!V^j0nb|=vRa`h;EbxxuoX{Qv1I=fy>B3hw)IQB}2M+tF(CS6O}A1)aZWgnaP zH$NUM4jU!Mmc1+~#K_RZJ?iJFHQK{5P^-W=9@x7ZF?>bah$GoJnyQZiLp@aF9u_a} z7u+tmvxFcyc;UYb!Z0jikE(1KcXSLyS)xN~0pI0H*Znfdqg14G;0UVS8pV->Fbznx z(<*GATD(lA2E#6zd=Keew4EpNvv0qbm5`EK1n{TH=B7~3QD#JVqTw1g-7MG3VpX@0 zdVh}$AwoZenJeO5SsAh-M~1h1RpJOb*0soY*zux4f^Z!rKWC{;kN6hlxsg0}ZiT&4 z&D5(MB69HQlY>A+w643yN5OWz&rRhzonyjf&+R)snqp?^uN%u z_c^$@s$_2F$3Na8PYii6;Cky`vC$5majHMtX(>i+w04MHFKr$Q4 zY}1{Rz;}|{sVa(GXUA|XeJH9@0@2l(MZg@=hZ6epuFU6vUHjw&hqHBa2Me*{$14!CjIA_L}uMgwZj{u;6o$ zd;T>AtY@==U{8JRiSySfKCM5%mY@H-EZ4+q%|95Xp&Yf;8b0~-CMxynwh?o#3zloW z^##zkw1({gbIEOwFh7GQC%J=zi=Nq(l5dhQ*Bv&Vn5ClL?!WoXpnZ~{%WLC@ygo2g zIlEjT>|bm7S14p`S2RCUOiua?rl_*Nsh%Nh_>sDO8+a`V>sm&I zj1lLUP4Rd-T>MFs%rZ?~a#)(sAxyua-I;Q~4Lak5s7t=KArae7DEqYqIz4D4I|?h~ zZ!`51`f*jJaC8~ESi?t0%x(xD8SGZ}Bj{rhwL$+qc%C5tM8#?9ecf3CVN2Uflj0%E z*sDU99DdTj9*b&h?>xs@h{y}ux+;`{y-6IzOv;22*jDNaAg70iqFU{U?qf=$7zgro zc?%r%Xdn4zJKDg8ih!iAZmVQUY~!@50obTjkQ^=?BP}5Tx+U23A;h>NjW3L^Y6X%$ z&v3~=+?LwMv^-bw$RLdwfAi)u*j^N2**yN6K|sia%J^NPLM1D8VaNg;4GWV;Ewct+ zIwQOHXJ6g5o?wRP6d;l0HLfce2F@u01b_C^6PBKhvmz)A)U}2$oGE`73kE}8erLXj zb`_zrS@n@SRxmI>uSzjnwu-XI&*0U*r+0MSt_I|u_$+{YrjFn84<`|A2cwNcWb!4QB5{zWFlu<8#@77OChtJg8o4`nmcHp}bC zNJ|(qryB?erE&cC0KDVGGUJ}(4#ou?NoAbn|@`x}z840)|wHURbK}#E4L*YhKJ~5#eK4xog*W|9Q zbf)ZV+?j)00YzP^FeG1{~DWIjdjosP4AIT zlQ{A`*vRv@x}bPp3#xDQzM0)kUxOshAYSUgaM0uVDP|G*;0X4(2VJW7tTf(!WN^*V zGtbVwZ91|1h|n7(0Sz#C6>+j6*2BDcUf=h};k{lEZIB!(JxRjZZuf2_cW8DM8qj~yZxb!!Tw5XbB^ag!&Q9cV zD9;u_#FLSC46A(=%1Hub#8!uW>&dV;f+`eGu({!XN*eyM!xe0iq9$2VY_Jzwyo~QN zCo@(u)xN!n~vRDMQuVD^w9qX?qF zUBr&K;Qg>4KG`X{6>SIF!E%Z@4XdWhe|v!49gVjVG`0o1niv1nPzqraD=y+Dd; zXB9$c*kQ{)X;E<*TzZ}5f55Y<4t720><(VSuRt2$x@J`Y=Rk9pDNLP`I)xDRSM7b8 ze}gOeQL#)UGjm>?yuPmcBy|}61bIEEF!#u1(bm;}EtSkZ}T!*go zu-{s&kS@aHe8wSQs@ho<&{sK$yg+pLJ{`~&^&dt>_8+pq+Sm2fhtRAg0-HdlgO~PV znHJ)vozPd=N}W)0`=na0=lL?UtZmaNZL4*G>Ay?d6WJ&{gNUJwwb~sbga4|MDKZod z{x(TlAHEW4)i&j9b~v!sSH6_KfM#U^I=c!+zddsNO%EF+BJbGIHp_E=&kvv3J{4iv z%qsGj$N&fjJwOHr<`b5ITb|4|R&GwDoLgg3>85w~DqM;-^NsbH=>bH{lL@XkcxgbZ z96~|xCQw%ES3LS(_oU<#ciNv7Vs~XO;SIcb{iEF$skH>C zf6-;sR(A1!)USo8OE&KS$6>8IKis_PUj=pZdmBiy@+Gr!NIdx_NO7}mxbTJUAcu0U zRZC(BlCZI6wqcc^sgK_c_#k<-wE8oZ-Zeq{7QtQoqcD7&XPFS2p%f`<*kwH?T3R`G z3ktq`J2O*zeCh8&D@mLA1c-CqwnzocC2*f>@0y0;-xnAG>pc3lJ=abL+agB&J!&mJ zA0HX2dM*P9C(m2^%T)JY5oK;;w3Rz ziBIpIxKr6ZHV2&dv9j?-;Xvh&^#H7ML-=KJ<=;@G*v5)s3QiLwa{JQ18$jQF^0jO* zXL(I>!-tV~%0h@fIUpB$QYJ_SDzHR~8uQ)H7$Q_*FFUgN@vFjTP==k@K`gU(GE5Qu zToBQB4;MesYyZi4C;V1VtQ)|H$?G9XaxTUh_sd~m@r$Ng{#cNrgmF&G0P=*sdjbhL zVM_TFi4Do9SJ9@xXUdAC4?DLOyI-Y6-j5Gx5InvvnO>EeXCKug!em{l@I9I=zSZuw z@?V`OQbKGCIG4m_rq|-Ek+C-pN;*9EO2q&>H!s_Y+y(Q`t~)iQgH)lUPHy)iuaxgs z3>lO;QN3Xb(vw*$J#YodKb`>!*r+@;SjFI%?GXURhDT!$3tct#L)F};C;xmi@)UKr z_ZTP@28V)m2E!adEsTZp|KLOo19=yrNOBsVH2rG87n>@T+aRrl`VozcI{?H6PBS`I z_b*ZUGHhl~Y* zb$Wx(^4^e-dWnq_qdtb?Q|T}%9kT$PFq*hmhcM*pNNwYXOMvP#D}YrC(TN7@#Ht?c zVY!`w&BE0GC}Rhoatr$)rjm=*-X||iG|)w3obO)Moupg|BUrHA%2F;CLe(qVz!&!x zm!;^&Ud^+Bu1ogD$CvV@hrj;L(6)Q@p&@>gIU>)*sLZ7{%6mdVddR8S#8xi?*FgO@gLzJDrU;u|b&eq#aJp`vh^m`$?L7hd zshhfRdV(87pg-X*Pq29ZjsKn+tcE@EcMJj;5VIPql;+2UT(+%;@PhaJYOon8iimN| zpj*&oI4kFt_^Oju2}Ol@OnbAi>j^TpDC2-wi++5yHAgvek8qbjkqpA5dq(+8KOoY^ zU*U`$g;x0H$)VKogIrz2bmGh)vji|4|AU~Q4ZiXy523?zpT{^3m zSLiEtJbXV>UP{1Rpl$8_H z6VbzGCU*v!0>bGP3y4tcldmiiRxJZiXKkl5-GnD{rLJu|-}4Vu(wJ)w`M)p*b%S2z zshL+vC_B5ZBvC1cu&rFz`xo>=*(B&#A4%Gn-C}VX{Nr;BmTi<yuzDo8hLQ&C`TC6bzdBqL5S;dOtXx`I!o=-)|0CSL4g?`qfw}G3C#wp0ZtC+- z{d_{t&IA>epb z*U2Zh`S|{%_Mh0setBCWfrC>3&@3LX8?uo_moWc7UD~)K|A9@|vg0yB1axsvnIqyq z(wuWbaABLD+APF)2crMmnEJ2raHU&&2WcKWATj~;`5iccER;fm!@=>2L<^~vDqYen zk$1v~_yU020Asj#cl-;}I;{8hrS`_--J zpP*gvf3!FEfcmkBCZB%g;WqpS+!$SX0&+rTT=m2+ZT_8D`ova%L74IZ9EH-c8rv*i zMiA+{L1QESHCD?12N=dLmuDZf(RNUSV8ken?SIRV^~5^RChNlCp*%-VBV9Xbm^uZ3 zRRCWPgy5CGuSr&u7(TH4{pb!L9@s>c0P!nIuH0%xgH22h?A!C-sQ@4a3crb|P5wts zi3BIO2lD?lu8lN;)02)>UeM`BT86rcq6EId|JraY0=z=`cd@2T%56B91yY~%zq98j zhO$)r-02H;r!4#Mf+|z{e-M-9W*K-s5`02wSFoZ4mjEIPV*q*p*@ywsl~40MO+0)V?HS_K$>i-??%0T($e2ZXw&<^C&B>YL97{!;qD zw%!0>lFN>e#3umE8e>%de#H+rk2WxNg+>qoP{Y{b6QNmftH8B5yve8D>{J5^#`^m) z&)cES0AK)Im;{64t^br%)Cm|V9O7#4l39-L;rv%C098IfWy-%*eF4ia*c?EM(ErCR zJbL;cu)0h)ljzFJxH)#rV431sYOMdio0J#$u*xdc3-e&Um_mxCJ>m2J`4m_sVLDcD zh2`$2fME-XWf(jX>^lg3r1c-Oh|xkgEdP`-wi&@BwF6c3pA!OO%xyRU!g_!!uMQgY zvFoJ$JNfiHH1aFB+u^_dP6$yz1L0_=DYd~JJEhpTxpcc2^XiTG(%#MgkLH0>MfH2S7)ab*gH zx}%qxXX>I8o!$itI*;Q|iURbUzbtyz6amQy4JICrf{o)QF&!XL#Bs{=zz{e-#_i=G z6TN!Mr=JXg3RspT4mKo&p~mtigcj5+SpBy?y=RFAr0^1nEsl6mb!U@3I+xdS>ah16 zhKnyY{8en#0{0++M+QABge~$oD+x=dfe6^lf7x_MmttX)Yh1m+zHQg92@wyF5yO>-ZLH7_B^knD!_lB@ zZ*kVrRi{Cy;wp6tBWzLmkQQ<+RB3pg{I5PgQO=3-0iJ8r;}qw;0UxOEEUv4(w^}$u zrI(kqW=oQ_AL`e=KxQ5i4xJzr!Uo0(9k$Y+w+5itNgh80o{nq>3Hv+@q@K8Y+uWGr zR~?dlN3`^W)4Qn8oEQ~C{X#btr)WY6m1CycdkbOV3N-6`B=2~jq`4n6<%mJ$#H0_gIS%X}Q?yUOy z>zK$%jq{64(yU(D!KHc1Jz~Q8?6^JWbR0gI`~gf^)MU%_Gr6f`m$_Od#d&(iOC;B} zG&Q%Otz8H^MTSYUa@<4Iv}nI#Ppq995Q4D2uAz-?10juGKD5+-drp0>iJCS1591 latest MIT - https://avatars2.githubusercontent.com/u/14075148?s=200 + Icon.png Avalonia is a WPF/UWP-inspired cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows (.NET Framework, .NET Core), Linux (via Xorg), MacOS and with experimental support for Android and iOS. avalonia;avaloniaui;mvvm;rx;reactive extensions;android;ios;mac;forms;wpf;net;netstandard;net461;uwp;xamarin https://github.com/AvaloniaUI/Avalonia/releases git + + + + From c364ca6f9bc268a4dfc336a8e39f6d826df6721e Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 17 Oct 2020 10:44:27 +0200 Subject: [PATCH 080/115] fix NU5128 --- build/SourceLink.props | 4 ++-- dirs.proj | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build/SourceLink.props b/build/SourceLink.props index 0c9b6a34f8..e27727c9e8 100644 --- a/build/SourceLink.props +++ b/build/SourceLink.props @@ -1,5 +1,5 @@ - + - \ No newline at end of file + diff --git a/dirs.proj b/dirs.proj index bf32abef72..594f2c22d3 100644 --- a/dirs.proj +++ b/dirs.proj @@ -21,6 +21,7 @@ + From a2296478ffc11106d635370d8e9761e84abc2dbc Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 17 Oct 2020 11:46:59 +0200 Subject: [PATCH 081/115] Supress warning MSBXXXX --- .../Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj b/src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj index 0d0dd98a77..0e11ee3b92 100644 --- a/src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj +++ b/src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj @@ -2,7 +2,7 @@ net461 true - true + true true true Avalonia.Win32.Interoperability From 4403d94c5c26d50c7910dc580cdd7b313a85e1d1 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 17 Oct 2020 11:51:05 +0200 Subject: [PATCH 082/115] Change boxShadow to boxShadows --- src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs b/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs index 9cf4e62030..d6e88a7507 100644 --- a/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs +++ b/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs @@ -63,13 +63,13 @@ namespace Avalonia.Platform /// The brush used to fill the rectangle, or null for no fill. /// The pen used to stroke the rectangle, or null for no stroke. /// The rectangle bounds. - /// Box shadow effect parameters + /// Box shadow effect parameters /// /// The brush and the pen can both be null. If the brush is null, then no fill is performed. /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible. /// void DrawRectangle(IBrush brush, IPen pen, RoundedRect rect, - BoxShadows boxShadow = default); + BoxShadows boxShadows = default); /// /// Draws text. From 77cd5153329cde4763a55eae30f1718f47c3c535 Mon Sep 17 00:00:00 2001 From: mj Date: Sun, 18 Oct 2020 09:10:33 -0600 Subject: [PATCH 083/115] Fixed returns value; Issue 4883 --- src/Avalonia.Controls/ItemsControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 3aec06e4eb..4dc8aec6f3 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -169,7 +169,7 @@ namespace Avalonia.Controls /// /// The collection. /// The index. - /// The index of the item or -1 if the item was not found. + /// The item at the given index or null if the index is out of bounds. protected static object ElementAt(IEnumerable items, int index) { if (index != -1 && index < items.Count()) From e5df3970e888ddcb62380f8cd3f08a9aaadddc85 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 20 Oct 2020 01:54:03 +0300 Subject: [PATCH 084/115] Workaround for corert --- .../XamlCompilerTaskExecutor.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs index 7c4a9df0f4..6b01af2ede 100644 --- a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs +++ b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs @@ -345,6 +345,20 @@ namespace Avalonia.Build.Tasks } res.Remove(); } + + + // Technically that's a hack, but it fixes corert incompatibility caused by deterministic builds + int dupeCounter = 1; + foreach (var grp in typeDef.NestedTypes.GroupBy(x => x.Name)) + { + if (grp.Count() > 1) + { + foreach (var dupe in grp) + dupe.Name += "_dup" + dupeCounter++; + } + } + + return true; } From 1aa50361bb1a27821a407a26df8f4216cdad00c4 Mon Sep 17 00:00:00 2001 From: bmello4688 Date: Tue, 20 Oct 2020 08:55:17 -0400 Subject: [PATCH 085/115] add XmlnsPrefix which is in WPF --- .../Metadata/XmlnsPrefixAttribute.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/Avalonia.Base/Metadata/XmlnsPrefixAttribute.cs diff --git a/src/Avalonia.Base/Metadata/XmlnsPrefixAttribute.cs b/src/Avalonia.Base/Metadata/XmlnsPrefixAttribute.cs new file mode 100644 index 0000000000..0f091d540a --- /dev/null +++ b/src/Avalonia.Base/Metadata/XmlnsPrefixAttribute.cs @@ -0,0 +1,30 @@ +using System; + +namespace Avalonia.Metadata +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + public sealed class XmlnsPrefixAttribute : Attribute + { + /// + /// Constructor + /// + /// XML namespce + /// recommended prefix + public XmlnsPrefixAttribute(string xmlNamespace, string prefix) + { + XmlNamespace = xmlNamespace ?? throw new ArgumentNullException(nameof(xmlNamespace)); + + Prefix = prefix ?? throw new ArgumentNullException(nameof(prefix)); + } + + /// + /// XML Namespace + /// + public string XmlNamespace { get; } + + /// + /// New Xml Namespace + /// + public string Prefix { get; } + } +} From 1497882cf64941e1f1b21957b1e490290637bdb2 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 20 Oct 2020 16:54:48 +0300 Subject: [PATCH 086/115] Enable light dismiss overlay for popups --- src/Avalonia.Controls/Primitives/VisualLayerManager.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/VisualLayerManager.cs b/src/Avalonia.Controls/Primitives/VisualLayerManager.cs index d8d3450c6f..457a9ea282 100644 --- a/src/Avalonia.Controls/Primitives/VisualLayerManager.cs +++ b/src/Avalonia.Controls/Primitives/VisualLayerManager.cs @@ -67,8 +67,6 @@ namespace Avalonia.Controls.Primitives { get { - if (IsPopup) - return null; var rv = FindLayer(); if (rv == null) { From 32b8cc811c087ddd8cda77668a7babed025b5093 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 20 Oct 2020 15:46:06 +0100 Subject: [PATCH 087/115] pass surfaceorigin to FboSkiaSurface. --- src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 7 ++++++- src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs | 2 +- src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs | 2 ++ src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs | 4 ++-- src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs | 4 ++++ src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs | 4 ++-- src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs | 3 ++- src/Skia/Avalonia.Skia/PlatformRenderInterface.cs | 2 +- src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs | 6 +++--- 9 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index cbc896813f..dac284ce1a 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -36,6 +36,7 @@ namespace Avalonia.Skia private readonly SKPaint _fillPaint = new SKPaint(); private readonly SKPaint _boxShadowPaint = new SKPaint(); private static SKShader s_acrylicNoiseShader; + private readonly GRSurfaceOrigin _surfaceOrigin; /// /// Context create info. @@ -76,6 +77,8 @@ namespace Avalonia.Skia /// Skia GPU provider context (optional) /// public ISkiaGpu Gpu; + + public ISkiaGpuRenderSession CurrentSession; } /// @@ -96,6 +99,8 @@ namespace Avalonia.Skia Surface = createInfo.Surface; Canvas = createInfo.Canvas ?? createInfo.Surface?.Canvas; + _surfaceOrigin = createInfo.CurrentSession?.SurfaceOrigin ?? GRSurfaceOrigin.TopLeft; + if (Canvas == null) { throw new ArgumentException("Invalid create info - no Canvas provided", nameof(createInfo)); @@ -972,7 +977,7 @@ namespace Avalonia.Skia Gpu = _gpu }; - return new SurfaceRenderTarget(createInfo); + return new SurfaceRenderTarget(createInfo, _surfaceOrigin); } /// diff --git a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs index 869c261f1b..7442f90ecf 100644 --- a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs +++ b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs @@ -21,7 +21,7 @@ namespace Avalonia.Skia /// Creates an offscreen render target surface /// /// size in pixels - ISkiaSurface TryCreateSurface(PixelSize size); + ISkiaSurface TryCreateSurface(PixelSize size, GRSurfaceOrigin surfaceOrigin); } public interface ISkiaSurface : IDisposable diff --git a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs index a4e2bfed52..5faa6a41ec 100644 --- a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs +++ b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs @@ -22,5 +22,7 @@ namespace Avalonia.Skia /// Scaling factor. /// double ScaleFactor { get; } + + GRSurfaceOrigin SurfaceOrigin { get; } } } diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs index 24464c39d9..8ab275df63 100644 --- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs +++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs @@ -14,7 +14,7 @@ namespace Avalonia.Skia private int _texture; private static readonly bool[] TrueFalse = new[] { true, false }; - public FboSkiaSurface(GRContext grContext, IGlContext glContext, PixelSize pixelSize) + public FboSkiaSurface(GRContext grContext, IGlContext glContext, PixelSize pixelSize, GRSurfaceOrigin surfaceOrigin) { _grContext = grContext; _glContext = glContext; @@ -93,7 +93,7 @@ namespace Avalonia.Skia var target = new GRBackendRenderTarget(pixelSize.Width, pixelSize.Height, 0, 8, new GRGlFramebufferInfo((uint)_fbo, SKColorType.Rgba8888.ToGlSizedFormat())); Surface = SKSurface.Create(_grContext, target, - GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888); + surfaceOrigin, SKColorType.Rgba8888); CanBlit = gl.BlitFramebuffer != null; } diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs index e109922a3f..b4c5619c85 100644 --- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs @@ -39,6 +39,8 @@ namespace Avalonia.Skia _backendRenderTarget = backendRenderTarget; _surface = surface; _glSession = glSession; + + SurfaceOrigin = glSession.IsYFlipped ? GRSurfaceOrigin.TopLeft : GRSurfaceOrigin.BottomLeft; } public void Dispose() { @@ -48,6 +50,8 @@ namespace Avalonia.Skia GrContext.Flush(); _glSession.Dispose(); } + + public GRSurfaceOrigin SurfaceOrigin { get; } public GRContext GrContext { get; } public SKSurface SkSurface => _surface; diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs index c02d813e24..02e3766d40 100644 --- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs +++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs @@ -47,7 +47,7 @@ namespace Avalonia.Skia return null; } - public ISkiaSurface TryCreateSurface(PixelSize size) + public ISkiaSurface TryCreateSurface(PixelSize size, GRSurfaceOrigin surfaceOrigin) { // Only windows platform needs our FBO trickery if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -62,7 +62,7 @@ namespace Avalonia.Skia return null; try { - var surface = new FboSkiaSurface(_grContext, _glContext, size); + var surface = new FboSkiaSurface(_grContext, _glContext, size, surfaceOrigin); _canCreateSurfaces = true; return surface; } diff --git a/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs index 9992c9ba8c..6626546c0c 100644 --- a/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs @@ -33,7 +33,8 @@ namespace Avalonia.Skia Dpi = SkiaPlatform.DefaultDpi * session.ScaleFactor, VisualBrushRenderer = visualBrushRenderer, DisableTextLcdRendering = true, - Gpu = _skiaGpu + Gpu = _skiaGpu, + CurrentSession = session }; return new DrawingContextImpl(nfo, session); diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs index d6f76a2c20..6048482110 100644 --- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs +++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs @@ -127,7 +127,7 @@ namespace Avalonia.Skia DisableTextLcdRendering = false }; - return new SurfaceRenderTarget(createInfo); + return new SurfaceRenderTarget(createInfo, GRSurfaceOrigin.TopLeft); } /// diff --git a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs index 61b599a731..905c9160a7 100644 --- a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs @@ -42,7 +42,7 @@ namespace Avalonia.Skia /// Create new surface render target. /// /// Create info. - public SurfaceRenderTarget(CreateInfo createInfo) + public SurfaceRenderTarget(CreateInfo createInfo, GRSurfaceOrigin surfaceOrigin) { PixelSize = new PixelSize(createInfo.Width, createInfo.Height); Dpi = createInfo.Dpi; @@ -51,7 +51,7 @@ namespace Avalonia.Skia _grContext = createInfo.GrContext; _gpu = createInfo.Gpu; - _surface = _gpu?.TryCreateSurface(PixelSize); + _surface = _gpu?.TryCreateSurface(PixelSize, surfaceOrigin); if (_surface == null) _surface = new SkiaSurfaceWrapper(CreateSurface(createInfo.GrContext, PixelSize.Width, PixelSize.Height, createInfo.Format)); @@ -100,7 +100,7 @@ namespace Avalonia.Skia VisualBrushRenderer = visualBrushRenderer, DisableTextLcdRendering = _disableLcdRendering, GrContext = _grContext, - Gpu = _gpu + Gpu = _gpu, }; return new DrawingContextImpl(createInfo, Disposable.Create(() => Version++)); From d218e2be2074a39cc0348c90c2cfe7334fdab73b Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 20 Oct 2020 20:32:32 +0100 Subject: [PATCH 088/115] dont save surfaceorigin as a field of drawing context. --- src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index dac284ce1a..136b14140e 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -36,7 +36,7 @@ namespace Avalonia.Skia private readonly SKPaint _fillPaint = new SKPaint(); private readonly SKPaint _boxShadowPaint = new SKPaint(); private static SKShader s_acrylicNoiseShader; - private readonly GRSurfaceOrigin _surfaceOrigin; + private readonly ISkiaGpuRenderSession _session; /// /// Context create info. @@ -99,7 +99,7 @@ namespace Avalonia.Skia Surface = createInfo.Surface; Canvas = createInfo.Canvas ?? createInfo.Surface?.Canvas; - _surfaceOrigin = createInfo.CurrentSession?.SurfaceOrigin ?? GRSurfaceOrigin.TopLeft; + _session = createInfo.CurrentSession; if (Canvas == null) { @@ -977,7 +977,7 @@ namespace Avalonia.Skia Gpu = _gpu }; - return new SurfaceRenderTarget(createInfo, _surfaceOrigin); + return new SurfaceRenderTarget(createInfo, _session?.SurfaceOrigin ?? GRSurfaceOrigin.TopLeft); } /// From ce08964f0371452ce8301cd2206d6e32f295982f Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 20 Oct 2020 20:34:51 +0100 Subject: [PATCH 089/115] refactor how surface origin is passed. --- src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 5 +++-- src/Skia/Avalonia.Skia/PlatformRenderInterface.cs | 2 +- src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 136b14140e..98692b7483 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -974,10 +974,11 @@ namespace Avalonia.Skia Format = format, DisableTextLcdRendering = !_canTextUseLcdRendering, GrContext = _grContext, - Gpu = _gpu + Gpu = _gpu, + SurfaceOrigin = _session?.SurfaceOrigin ?? GRSurfaceOrigin.TopLeft }; - return new SurfaceRenderTarget(createInfo, _session?.SurfaceOrigin ?? GRSurfaceOrigin.TopLeft); + return new SurfaceRenderTarget(createInfo); } /// diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs index 6048482110..d6f76a2c20 100644 --- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs +++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs @@ -127,7 +127,7 @@ namespace Avalonia.Skia DisableTextLcdRendering = false }; - return new SurfaceRenderTarget(createInfo, GRSurfaceOrigin.TopLeft); + return new SurfaceRenderTarget(createInfo); } /// diff --git a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs index 905c9160a7..d3d4515689 100644 --- a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs @@ -42,7 +42,7 @@ namespace Avalonia.Skia /// Create new surface render target. /// /// Create info. - public SurfaceRenderTarget(CreateInfo createInfo, GRSurfaceOrigin surfaceOrigin) + public SurfaceRenderTarget(CreateInfo createInfo) { PixelSize = new PixelSize(createInfo.Width, createInfo.Height); Dpi = createInfo.Dpi; @@ -51,7 +51,7 @@ namespace Avalonia.Skia _grContext = createInfo.GrContext; _gpu = createInfo.Gpu; - _surface = _gpu?.TryCreateSurface(PixelSize, surfaceOrigin); + _surface = _gpu?.TryCreateSurface(PixelSize, createInfo.SurfaceOrigin); if (_surface == null) _surface = new SkiaSurfaceWrapper(CreateSurface(createInfo.GrContext, PixelSize.Width, PixelSize.Height, createInfo.Format)); @@ -218,6 +218,8 @@ namespace Avalonia.Skia public GRContext GrContext; public ISkiaGpu Gpu; + + public GRSurfaceOrigin SurfaceOrigin; } } } From e04fe994fb9c032992c07380749933b4f8b6dca8 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Wed, 21 Oct 2020 00:06:10 +0300 Subject: [PATCH 090/115] do not make any layout in ItemVirtualizer while not attached to visual tree --- src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs index bdc68bee7e..7d50ef7d33 100644 --- a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs +++ b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs @@ -512,6 +512,13 @@ namespace Avalonia.Controls.Presenters var generator = Owner.ItemContainerGenerator; var newOffset = -1.0; + //better not trigger any container generation/recycle while or layout stuff + //before panel is attached/visible + if (!panel.IsAttachedToVisualTree) + { + return null; + } + if (!panel.IsMeasureValid && panel.PreviousMeasure.HasValue) { //before any kind of scrolling we need to make sure panel measure is valid From a93ecd1c66d0126409fdfaea5cfc73124fed069d Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 21 Oct 2020 12:47:33 +0300 Subject: [PATCH 091/115] [X11] Handle PointerLeave through XI2 --- src/Avalonia.X11/XI2Manager.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.X11/XI2Manager.cs b/src/Avalonia.X11/XI2Manager.cs index 742973e0da..9349824525 100644 --- a/src/Avalonia.X11/XI2Manager.cs +++ b/src/Avalonia.X11/XI2Manager.cs @@ -162,7 +162,9 @@ namespace Avalonia.X11 | XEventMask.Button4MotionMask | XEventMask.Button5MotionMask | XEventMask.ButtonPressMask - | XEventMask.ButtonReleaseMask; + | XEventMask.ButtonReleaseMask + | XEventMask.LeaveWindowMask + | XEventMask.EnterWindowMask; } public void OnWindowDestroyed(IntPtr xid) => _clients.Remove(xid); @@ -201,6 +203,12 @@ namespace Avalonia.X11 return; } + if (ev.Type == XiEventType.XI_Leave) + { + client.ScheduleXI2Input(new RawPointerEventArgs(client.MouseDevice, ev.Timestamp, client.InputRoot, + RawPointerEventType.LeaveWindow, ev.Position, ev.Modifiers)); + } + if (_multitouch && ev.Emulated) return; From fb7b7a002ce8f46a924ea307a8b6710be1de0670 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 21 Oct 2020 13:04:05 +0300 Subject: [PATCH 092/115] Fixed initial pointerover at (0, 0) when window is just shown --- src/Avalonia.Input/MouseDevice.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Input/MouseDevice.cs b/src/Avalonia.Input/MouseDevice.cs index cec5029c18..5c63546f5d 100644 --- a/src/Avalonia.Input/MouseDevice.cs +++ b/src/Avalonia.Input/MouseDevice.cs @@ -19,6 +19,7 @@ namespace Avalonia.Input private readonly Pointer _pointer; private bool _disposed; + private PixelPoint? _position; public MouseDevice(Pointer? pointer = null) { @@ -39,10 +40,11 @@ namespace Avalonia.Input /// /// Gets the mouse position, in screen coordinates. /// + [Obsolete("Use events instead")] public PixelPoint Position { - get; - protected set; + get => _position ?? new PixelPoint(-1, -1); + protected set => _position = value; } /// @@ -91,7 +93,16 @@ namespace Avalonia.Input public void SceneInvalidated(IInputRoot root, Rect rect) { - var clientPoint = root.PointToClient(Position); + // Pointer is outside of the target area + if (_position == null ) + { + if (root.PointerOverElement != null) + ClearPointerOver(this, 0, root, PointerPointProperties.None, KeyModifiers.None); + return; + } + + + var clientPoint = root.PointToClient(_position.Value); if (rect.Contains(clientPoint)) { @@ -132,7 +143,7 @@ namespace Avalonia.Input if(mouse._disposed) return; - Position = e.Root.PointToScreen(e.Position); + _position = e.Root.PointToScreen(e.Position); var props = CreateProperties(e); var keyModifiers = KeyModifiersUtils.ConvertToKey(e.InputModifiers); switch (e.Type) @@ -176,6 +187,7 @@ namespace Avalonia.Input device = device ?? throw new ArgumentNullException(nameof(device)); root = root ?? throw new ArgumentNullException(nameof(root)); + _position = null; ClearPointerOver(this, timestamp, root, properties, inputModifiers); } From aa48b5733e14be820a01c452e15c947144cb81bc Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 21 Oct 2020 12:52:23 +0200 Subject: [PATCH 093/115] Replaced LogToDebug with LogToTrace. Calls to `System.Diagnostics.Debug` are removed in release builds meaning nothing was getting logged. Fixes #4901 --- samples/BindingDemo/App.xaml.cs | 2 +- samples/ControlCatalog.Desktop/Program.cs | 2 +- samples/ControlCatalog.NetCore/Program.cs | 2 +- samples/RenderDemo/App.xaml.cs | 2 +- samples/Sandbox/Program.cs | 2 +- samples/VirtualizationDemo/Program.cs | 2 +- src/Avalonia.Base/ApiCompatBaseline.txt | 3 ++- .../{DebugLogSink.cs => TraceLogSink.cs} | 14 +++++++------- src/Avalonia.Controls/LoggingExtensions.cs | 19 +++++++++++++++---- 9 files changed, 30 insertions(+), 18 deletions(-) rename src/Avalonia.Base/Logging/{DebugLogSink.cs => TraceLogSink.cs} (92%) diff --git a/samples/BindingDemo/App.xaml.cs b/samples/BindingDemo/App.xaml.cs index 5c38ab8305..eb2da03a7e 100644 --- a/samples/BindingDemo/App.xaml.cs +++ b/samples/BindingDemo/App.xaml.cs @@ -26,6 +26,6 @@ namespace BindingDemo => AppBuilder.Configure() .UsePlatformDetect() .UseReactiveUI() - .LogToDebug(); + .LogToTrace(); } } diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs index e0cc8cc904..5af646b180 100644 --- a/samples/ControlCatalog.Desktop/Program.cs +++ b/samples/ControlCatalog.Desktop/Program.cs @@ -18,7 +18,7 @@ namespace ControlCatalog /// public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() - .LogToDebug() + .LogToTrace() .UsePlatformDetect() .UseReactiveUI(); diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index 142736a0bb..c1fcdd6216 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -121,7 +121,7 @@ namespace ControlCatalog.NetCore .UseSkia() .UseReactiveUI() .UseManagedSystemDialogs() - .LogToDebug(); + .LogToTrace(); static void SilenceConsole() { diff --git a/samples/RenderDemo/App.xaml.cs b/samples/RenderDemo/App.xaml.cs index 2247fd7c5a..e6ec963d75 100644 --- a/samples/RenderDemo/App.xaml.cs +++ b/samples/RenderDemo/App.xaml.cs @@ -33,6 +33,6 @@ namespace RenderDemo }) .UsePlatformDetect() .UseReactiveUI() - .LogToDebug(); + .LogToTrace(); } } diff --git a/samples/Sandbox/Program.cs b/samples/Sandbox/Program.cs index 4d7eda8d9f..7d41a8b8c0 100644 --- a/samples/Sandbox/Program.cs +++ b/samples/Sandbox/Program.cs @@ -10,7 +10,7 @@ namespace Sandbox AppBuilder.Configure() .UsePlatformDetect() .UseReactiveUI() - .LogToDebug() + .LogToTrace() .StartWithClassicDesktopLifetime(args); } } diff --git a/samples/VirtualizationDemo/Program.cs b/samples/VirtualizationDemo/Program.cs index c23bfd7ad9..46c05f74b2 100644 --- a/samples/VirtualizationDemo/Program.cs +++ b/samples/VirtualizationDemo/Program.cs @@ -9,7 +9,7 @@ namespace VirtualizationDemo => AppBuilder.Configure() .UsePlatformDetect() .UseReactiveUI() - .LogToDebug(); + .LogToTrace(); public static int Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); diff --git a/src/Avalonia.Base/ApiCompatBaseline.txt b/src/Avalonia.Base/ApiCompatBaseline.txt index 4668a572c5..5d19373a92 100644 --- a/src/Avalonia.Base/ApiCompatBaseline.txt +++ b/src/Avalonia.Base/ApiCompatBaseline.txt @@ -1,3 +1,4 @@ Compat issues with assembly Avalonia.Base: CannotAddAbstractMembers : Member 'protected System.IObservable Avalonia.AvaloniaProperty.GetChanged()' is abstract in the implementation but is missing in the contract. -Total Issues: 1 +TypesMustExist : Type 'Avalonia.Logging.DebugLogSink' does not exist in the implementation but it does exist in the contract. +Total Issues: 2 diff --git a/src/Avalonia.Base/Logging/DebugLogSink.cs b/src/Avalonia.Base/Logging/TraceLogSink.cs similarity index 92% rename from src/Avalonia.Base/Logging/DebugLogSink.cs rename to src/Avalonia.Base/Logging/TraceLogSink.cs index 3695afa860..f597844378 100644 --- a/src/Avalonia.Base/Logging/DebugLogSink.cs +++ b/src/Avalonia.Base/Logging/TraceLogSink.cs @@ -6,12 +6,12 @@ using Avalonia.Utilities; namespace Avalonia.Logging { - public class DebugLogSink : ILogSink + public class TraceLogSink : ILogSink { private readonly LogEventLevel _level; private readonly IList _areas; - public DebugLogSink( + public TraceLogSink( LogEventLevel minimumLevel, IList areas = null) { @@ -28,7 +28,7 @@ namespace Avalonia.Logging { if (IsEnabled(level, area)) { - Debug.WriteLine(Format(area, messageTemplate, source)); + Trace.WriteLine(Format(area, messageTemplate, source)); } } @@ -36,7 +36,7 @@ namespace Avalonia.Logging { if (IsEnabled(level, area)) { - Debug.WriteLine(Format(area, messageTemplate, source, propertyValue0)); + Trace.WriteLine(Format(area, messageTemplate, source, propertyValue0)); } } @@ -44,7 +44,7 @@ namespace Avalonia.Logging { if (IsEnabled(level, area)) { - Debug.WriteLine(Format(area, messageTemplate, source, propertyValue0, propertyValue1)); + Trace.WriteLine(Format(area, messageTemplate, source, propertyValue0, propertyValue1)); } } @@ -52,7 +52,7 @@ namespace Avalonia.Logging { if (IsEnabled(level, area)) { - Debug.WriteLine(Format(area, messageTemplate, source, propertyValue0, propertyValue1, propertyValue2)); + Trace.WriteLine(Format(area, messageTemplate, source, propertyValue0, propertyValue1, propertyValue2)); } } @@ -60,7 +60,7 @@ namespace Avalonia.Logging { if (IsEnabled(level, area)) { - Debug.WriteLine(Format(area, messageTemplate, source, propertyValues)); + Trace.WriteLine(Format(area, messageTemplate, source, propertyValues)); } } diff --git a/src/Avalonia.Controls/LoggingExtensions.cs b/src/Avalonia.Controls/LoggingExtensions.cs index 44e570bdfa..9eb3b140f6 100644 --- a/src/Avalonia.Controls/LoggingExtensions.cs +++ b/src/Avalonia.Controls/LoggingExtensions.cs @@ -1,25 +1,36 @@ -using Avalonia.Controls; +using System; +using Avalonia.Controls; using Avalonia.Logging; namespace Avalonia { public static class LoggingExtensions { + [Obsolete("Use LogToTrace")] + public static T LogToDebug( + this T builder, + LogEventLevel level = LogEventLevel.Warning, + params string[] areas) + where T : AppBuilderBase, new() + { + return LogToTrace(builder, level, areas); + } + /// - /// Logs Avalonia events to the sink. + /// Logs Avalonia events to the sink. /// /// The application class type. /// The app builder instance. /// The minimum level to log. /// The areas to log. Valid values are listed in . /// The app builder instance. - public static T LogToDebug( + public static T LogToTrace( this T builder, LogEventLevel level = LogEventLevel.Warning, params string[] areas) where T : AppBuilderBase, new() { - Logger.Sink = new DebugLogSink(level, areas); + Logger.Sink = new TraceLogSink(level, areas); return builder; } } From 4f6dd5a44a9da62446b91ed0f620b645bff00f60 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 21 Oct 2020 14:42:00 +0300 Subject: [PATCH 094/115] [X11] XI2 fix --- src/Avalonia.X11/XI2Manager.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Avalonia.X11/XI2Manager.cs b/src/Avalonia.X11/XI2Manager.cs index 9349824525..d0655d05c1 100644 --- a/src/Avalonia.X11/XI2Manager.cs +++ b/src/Avalonia.X11/XI2Manager.cs @@ -13,7 +13,8 @@ namespace Avalonia.X11 { XiEventType.XI_Motion, XiEventType.XI_ButtonPress, - XiEventType.XI_ButtonRelease + XiEventType.XI_ButtonRelease, + XiEventType.XI_Leave }; private static readonly XiEventType[] MultiTouchEventTypes = new XiEventType[] @@ -177,9 +178,10 @@ namespace Avalonia.X11 _pointerDevice.Update(changed->Classes, changed->NumClasses); } - + if ((xev->evtype >= XiEventType.XI_ButtonPress && xev->evtype <= XiEventType.XI_Motion) - || (xev->evtype>=XiEventType.XI_TouchBegin&&xev->evtype<=XiEventType.XI_TouchEnd)) + || (xev->evtype >= XiEventType.XI_TouchBegin && xev->evtype <= XiEventType.XI_TouchEnd) + || xev->evtype == XiEventType.XI_Leave) { var dev = (XIDeviceEvent*)xev; if (_clients.TryGetValue(dev->EventWindow, out var client)) @@ -306,7 +308,7 @@ namespace Avalonia.X11 if (state.HasFlag(XModifierMask.Mod4Mask)) Modifiers |= RawInputModifiers.Meta; - if (ev->buttons.MaskLen > 0) + if (ev->buttons.MaskLen > 1 && Type != XiEventType.XI_Leave) { var buttons = ev->buttons.Mask; if (XIMaskIsSet(buttons, 1)) @@ -324,9 +326,11 @@ namespace Avalonia.X11 Valuators = new Dictionary(); Position = new Point(ev->event_x, ev->event_y); var values = ev->valuators.Values; - for (var c = 0; c < ev->valuators.MaskLen * 8; c++) - if (XIMaskIsSet(ev->valuators.Mask, c)) - Valuators[c] = *values++; + if(ev->valuators.Mask != null) + for (var c = 0; c < ev->valuators.MaskLen * 8; c++) + if (XIMaskIsSet(ev->valuators.Mask, c)) + Valuators[c] = *values++; + if (Type == XiEventType.XI_ButtonPress || Type == XiEventType.XI_ButtonRelease) Button = ev->detail; Detail = ev->detail; From 5f3d81bbfcd33ad5bca32b188135355dcbde08c3 Mon Sep 17 00:00:00 2001 From: Mikhail Poliudov Date: Wed, 21 Oct 2020 19:10:25 +0700 Subject: [PATCH 095/115] 1. implemented Label control (again) 2. changed implementation of ControlPresenter to be same as WPF one. Added additional prebuild DataTemplate (for ContentPresenter) 3. added default style for Label control (both Default and Fluent themes) 4. Added sample to TextBox page (not sure needed other sample) 5. Added styles for Label in ControlCatalog/App.xaml --- samples/ControlCatalog/App.xaml | 10 +++ samples/ControlCatalog/Pages/TextBoxPage.xaml | 36 ++++----- src/Avalonia.Controls/Label.cs | 74 +++++++++++++++++++ .../Presenters/ContentPresenter.cs | 25 ++++++- .../Templates/FuncDataTemplate.cs | 28 ++++++- src/Avalonia.Themes.Default/DefaultTheme.xaml | 3 +- src/Avalonia.Themes.Default/Label.xaml | 17 +++++ src/Avalonia.Themes.Fluent/FluentTheme.xaml | 3 +- src/Avalonia.Themes.Fluent/Label.xaml | 17 +++++ 9 files changed, 191 insertions(+), 22 deletions(-) create mode 100644 src/Avalonia.Controls/Label.cs create mode 100644 src/Avalonia.Themes.Default/Label.xaml create mode 100644 src/Avalonia.Themes.Fluent/Label.xaml diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml index 9bac320c79..6aad44c0d5 100644 --- a/samples/ControlCatalog/App.xaml +++ b/samples/ControlCatalog/App.xaml @@ -12,6 +12,16 @@ + + + diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml index 481a459159..8b07ac3f85 100644 --- a/samples/ControlCatalog/Pages/TextBoxPage.xaml +++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml @@ -2,8 +2,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ControlCatalog.Pages.TextBoxPage"> - TextBox - A control into which the user can input text + + - + - - resm fonts - - - - - - - - res fonts - - - - - + + + + + + + + + + + + + + + diff --git a/src/Avalonia.Controls/Label.cs b/src/Avalonia.Controls/Label.cs new file mode 100644 index 0000000000..76708b8f00 --- /dev/null +++ b/src/Avalonia.Controls/Label.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; +using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; +using Avalonia.Data; +using Avalonia.Input; +using Avalonia.Interactivity; + +namespace Avalonia.Controls +{ + /// + /// Label control. Focuses on pointer click or access key press (Alt + accessKey) + /// + public class Label : ContentControl + { + /// + /// Defines the Direct property + /// + public static readonly DirectProperty TargetProperty = + AvaloniaProperty.RegisterDirect(nameof(Target), lbl => lbl.Target, (lbl, inp) => lbl.Target = inp); + + /// + /// Label focus target storage field + /// + private IInputElement _target; + + /// + /// Label focus Target + /// + public IInputElement Target + { + get => _target; + set => SetAndRaise(TargetProperty, ref _target, value); + } + + static Label() + { + AccessKeyHandler.AccessKeyPressedEvent.AddClassHandler