diff --git a/src/Avalonia.Controls/ApiCompatBaseline.txt b/src/Avalonia.Controls/ApiCompatBaseline.txt index 11708b360f..af88c569a6 100644 --- a/src/Avalonia.Controls/ApiCompatBaseline.txt +++ b/src/Avalonia.Controls/ApiCompatBaseline.txt @@ -12,7 +12,9 @@ MembersMustExist : Member 'public Avalonia.DirectProperty Avalonia.Interactivity.RoutedEvent Avalonia.Controls.TreeView.SelectionChangedEvent' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public Avalonia.Controls.ISelectionModel Avalonia.Controls.TreeView.Selection.get()' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public void Avalonia.Controls.TreeView.Selection.set(Avalonia.Controls.ISelectionModel)' does not exist in the implementation but it does exist in the contract. +InterfacesShouldHaveSameMembers : Interface member 'public System.String[] Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime.Args' is present in the implementation but not in the contract. +InterfacesShouldHaveSameMembers : Interface member 'public System.String[] Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime.Args.get()' is present in the implementation but not in the contract. MembersMustExist : Member 'public Avalonia.DirectProperty Avalonia.DirectProperty Avalonia.Controls.Primitives.SelectingItemsControl.SelectionProperty' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'protected Avalonia.Controls.ISelectionModel Avalonia.Controls.Primitives.SelectingItemsControl.Selection.get()' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'protected void Avalonia.Controls.Primitives.SelectingItemsControl.Selection.set(Avalonia.Controls.ISelectionModel)' does not exist in the implementation but it does exist in the contract. -Total Issues: 16 +Total Issues: 18 diff --git a/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs index 6dd5b8cc81..e2c8e7e8e2 100644 --- a/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs @@ -47,6 +47,11 @@ namespace Avalonia.Controls.ApplicationLifetimes /// public event EventHandler Exit; + /// + /// Gets the arguments passed to the AppBuilder Start method. + /// + public string[] Args { get; set; } + /// public ShutdownMode ShutdownMode { get; set; } @@ -68,9 +73,6 @@ namespace Avalonia.Controls.ApplicationLifetimes else if (ShutdownMode == ShutdownMode.OnMainWindowClose && window == MainWindow) Shutdown(); } - - - public void Shutdown(int exitCode = 0) { @@ -123,7 +125,11 @@ namespace Avalonia this T builder, string[] args, ShutdownMode shutdownMode = ShutdownMode.OnLastWindowClose) where T : AppBuilderBase, new() { - var lifetime = new ClassicDesktopStyleApplicationLifetime() {ShutdownMode = shutdownMode}; + var lifetime = new ClassicDesktopStyleApplicationLifetime() + { + Args = args, + ShutdownMode = shutdownMode + }; builder.SetupWithLifetime(lifetime); return lifetime.Start(args); } diff --git a/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs index a1006d907b..212f0b8617 100644 --- a/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs @@ -8,6 +8,13 @@ namespace Avalonia.Controls.ApplicationLifetimes /// public interface IClassicDesktopStyleApplicationLifetime : IControlledApplicationLifetime { + /// + /// Gets the arguments passed to the + /// + /// method. + /// + string[] Args { get; } + /// /// Gets or sets the . This property indicates whether the application is shutdown explicitly or implicitly. /// If is set to OnExplicitShutdown the application is only closes if Shutdown is called. diff --git a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs new file mode 100644 index 0000000000..375b93c27c --- /dev/null +++ b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs @@ -0,0 +1,31 @@ +using System; +using System.Runtime.InteropServices; +using Avalonia.Platform; +using Avalonia.Platform.Interop; + +namespace Avalonia.OpenGL.Angle +{ + public class AngleEglInterface : EglInterface + { + [DllImport("libegl.dll", CharSet = CharSet.Ansi)] + static extern IntPtr eglGetProcAddress(string proc); + + public AngleEglInterface() : base(LoadAngle()) + { + + } + + static Func LoadAngle() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + throw new PlatformNotSupportedException(); + { + var disp = eglGetProcAddress("eglGetPlatformDisplayEXT"); + if (disp == IntPtr.Zero) + throw new OpenGlException("libegl.dll doesn't have eglGetPlatformDisplayEXT entry point"); + return eglGetProcAddress; + } + } + + } +} diff --git a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs new file mode 100644 index 0000000000..1a42ed90c2 --- /dev/null +++ b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +using static Avalonia.OpenGL.EglConsts; + +namespace Avalonia.OpenGL.Angle +{ + public class AngleWin32EglDisplay : EglDisplay + { + struct AngleInfo + { + public IntPtr Display { get; set; } + public AngleOptions.PlatformApi PlatformApi { get; set; } + } + + static AngleInfo CreateAngleDisplay(EglInterface _egl) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + throw new PlatformNotSupportedException(); + var display = IntPtr.Zero; + AngleOptions.PlatformApi angleApi = default; + { + if (_egl.GetPlatformDisplayEXT == null) + throw new OpenGlException("eglGetPlatformDisplayEXT is not supported by libegl.dll"); + + var allowedApis = AvaloniaLocator.Current.GetService()?.AllowedPlatformApis + ?? new [] { AngleOptions.PlatformApi.DirectX11, AngleOptions.PlatformApi.DirectX9 }; + + foreach (var platformApi in allowedApis) + { + int dapi; + if (platformApi == AngleOptions.PlatformApi.DirectX9) + dapi = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE; + else if (platformApi == AngleOptions.PlatformApi.DirectX11) + dapi = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; + else + continue; + + display = _egl.GetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, IntPtr.Zero, + new[] { EGL_PLATFORM_ANGLE_TYPE_ANGLE, dapi, EGL_NONE }); + if (display != IntPtr.Zero) + { + angleApi = platformApi; + break; + } + } + + if (display == IntPtr.Zero) + throw new OpenGlException("Unable to create ANGLE display"); + return new AngleInfo { Display = display, PlatformApi = angleApi }; + } + } + + private AngleWin32EglDisplay(EglInterface egl, AngleInfo info) : base(egl, info.Display) + { + PlatformApi = info.PlatformApi; + } + + public AngleWin32EglDisplay(EglInterface egl) : this(egl, CreateAngleDisplay(egl)) + { + + } + + public AngleWin32EglDisplay() : this(new AngleEglInterface()) + { + + } + + public AngleOptions.PlatformApi PlatformApi { get; } + + public IntPtr GetDirect3DDevice() + { + if (!EglInterface.QueryDisplayAttribExt(Handle, EglConsts.EGL_DEVICE_EXT, out var eglDevice)) + throw new OpenGlException("Unable to get EGL_DEVICE_EXT"); + if (!EglInterface.QueryDeviceAttribExt(eglDevice, PlatformApi == AngleOptions.PlatformApi.DirectX9 ? EGL_D3D9_DEVICE_ANGLE : EGL_D3D11_DEVICE_ANGLE, out var d3dDeviceHandle)) + throw new OpenGlException("Unable to get EGL_D3D9_DEVICE_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_NONE, EGL_NONE }); + } + } +} diff --git a/src/Avalonia.OpenGL/EglConsts.cs b/src/Avalonia.OpenGL/EglConsts.cs index 5cc732ef6a..8e44004f2d 100644 --- a/src/Avalonia.OpenGL/EglConsts.cs +++ b/src/Avalonia.OpenGL/EglConsts.cs @@ -195,5 +195,15 @@ namespace Avalonia.OpenGL public const int EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE = 0x320F; public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE = 0x320B; public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE = 0x320C; + + //EXT_device_query + public const int EGL_DEVICE_EXT = 0x322C; + + //ANGLE_device_d3d + public const int EGL_D3D9_DEVICE_ANGLE = 0x33A0; + public const int EGL_D3D11_DEVICE_ANGLE = 0x33A1; + + public const int EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200; + public const int EGL_D3D_TEXTURE_ANGLE = 0x33A3; } } diff --git a/src/Avalonia.OpenGL/EglDisplay.cs b/src/Avalonia.OpenGL/EglDisplay.cs index ce5fd50a07..7b194e4346 100644 --- a/src/Avalonia.OpenGL/EglDisplay.cs +++ b/src/Avalonia.OpenGL/EglDisplay.cs @@ -15,7 +15,6 @@ namespace Avalonia.OpenGL private readonly int _surfaceType; public IntPtr Handle => _display; - private AngleOptions.PlatformApi? _angleApi; private int _sampleCount; private int _stencilSize; private GlVersion _version; @@ -24,60 +23,41 @@ namespace Avalonia.OpenGL { } - public EglDisplay(EglInterface egl, int platformType, IntPtr platformDisplay, int[] attrs) - { - _egl = egl; + static IntPtr CreateDisplay(EglInterface egl, int platformType, IntPtr platformDisplay, int[] attrs) + { + var display = IntPtr.Zero; if (platformType == -1 && platformDisplay == IntPtr.Zero) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - if (_egl.GetPlatformDisplayEXT == null) - throw new OpenGlException("eglGetPlatformDisplayEXT is not supported by libegl.dll"); - - var allowedApis = AvaloniaLocator.Current.GetService()?.AllowedPlatformApis - ?? new [] - { - AngleOptions.PlatformApi.DirectX11, - AngleOptions.PlatformApi.DirectX9 - }; - - foreach (var platformApi in allowedApis) - { - int dapi; - if (platformApi == AngleOptions.PlatformApi.DirectX9) - dapi = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE; - else if (platformApi == AngleOptions.PlatformApi.DirectX11) - dapi = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; - else - continue; - - _display = _egl.GetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, IntPtr.Zero, - new[] {EGL_PLATFORM_ANGLE_TYPE_ANGLE, dapi, EGL_NONE}); - if (_display != IntPtr.Zero) - { - _angleApi = platformApi; - break; - } - } - - if (_display == IntPtr.Zero) - throw new OpenGlException("Unable to create ANGLE display"); - } - - if (_display == IntPtr.Zero) - _display = _egl.GetDisplay(IntPtr.Zero); + if (display == IntPtr.Zero) + display = egl.GetDisplay(IntPtr.Zero); } else { - if (_egl.GetPlatformDisplayEXT == null) + if (egl.GetPlatformDisplayEXT == null) throw new OpenGlException("eglGetPlatformDisplayEXT is not supported by libegl"); - _display = _egl.GetPlatformDisplayEXT(platformType, platformDisplay, attrs); + display = egl.GetPlatformDisplayEXT(platformType, platformDisplay, attrs); } + + if (display == IntPtr.Zero) + throw OpenGlException.GetFormattedException("eglGetDisplay", egl); + return display; + } - if (_display == IntPtr.Zero) - throw OpenGlException.GetFormattedException("eglGetDisplay", _egl); + public EglDisplay(EglInterface egl, int platformType, IntPtr platformDisplay, int[] attrs) + : this(egl, CreateDisplay(egl, platformType, platformDisplay, attrs)) + { + + } + public EglDisplay(EglInterface egl, IntPtr display) + { + _egl = egl; + _display = display; + if(_display == IntPtr.Zero) + throw new ArgumentException(); + + if (!_egl.Initialize(_display, out var major, out var minor)) throw OpenGlException.GetFormattedException("eglInitialize", _egl); @@ -176,5 +156,15 @@ namespace Avalonia.OpenGL throw OpenGlException.GetFormattedException("eglCreateWindowSurface", _egl); return new EglSurface(this, _egl, s); } + + public EglSurface CreatePBufferFromClientBuffer (int bufferType, IntPtr handle, int[] attribs) + { + var s = _egl.CreatePbufferFromClientBuffer(_display, bufferType, handle, + _config, attribs); + + if (s == IntPtr.Zero) + throw OpenGlException.GetFormattedException("eglCreatePbufferFromClientBuffer", _egl); + return new EglSurface(this, _egl, s); + } } } diff --git a/src/Avalonia.OpenGL/EglGlPlatformFeature.cs b/src/Avalonia.OpenGL/EglGlPlatformFeature.cs index f59c6b7751..7e9383432c 100644 --- a/src/Avalonia.OpenGL/EglGlPlatformFeature.cs +++ b/src/Avalonia.OpenGL/EglGlPlatformFeature.cs @@ -20,12 +20,13 @@ namespace Avalonia.OpenGL if (feature != null) AvaloniaLocator.CurrentMutable.Bind().ToConstant(feature); } - - public static EglGlPlatformFeature TryCreate() + + public static EglGlPlatformFeature TryCreate() => TryCreate(() => new EglDisplay()); + public static EglGlPlatformFeature TryCreate(Func displayFactory) { try { - var disp = new EglDisplay(); + var disp = displayFactory(); return new EglGlPlatformFeature { _display = disp, diff --git a/src/Avalonia.OpenGL/EglGlPlatformSurface.cs b/src/Avalonia.OpenGL/EglGlPlatformSurface.cs index 3e4befe2c6..21fadff19e 100644 --- a/src/Avalonia.OpenGL/EglGlPlatformSurface.cs +++ b/src/Avalonia.OpenGL/EglGlPlatformSurface.cs @@ -3,33 +3,26 @@ using System.Threading; namespace Avalonia.OpenGL { - public class EglGlPlatformSurface : IGlPlatformSurface + public class EglGlPlatformSurface : EglGlPlatformSurfaceBase { - public interface IEglWindowGlPlatformSurfaceInfo - { - IntPtr Handle { get; } - PixelSize Size { get; } - double Scaling { get; } - } - private readonly EglDisplay _display; private readonly EglContext _context; private readonly IEglWindowGlPlatformSurfaceInfo _info; - public EglGlPlatformSurface(EglContext context, IEglWindowGlPlatformSurfaceInfo info) + public EglGlPlatformSurface(EglContext context, IEglWindowGlPlatformSurfaceInfo info) : base() { _display = context.Display; _context = context; _info = info; } - - public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() + + public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() { var glSurface = _display.CreateWindowSurface(_info.Handle); return new RenderTarget(_display, _context, glSurface, _info); } - class RenderTarget : IGlPlatformSurfaceRenderTargetWithCorruptionInfo + class RenderTarget : EglPlatformSurfaceRenderTargetBase { private readonly EglDisplay _display; private readonly EglContext _context; @@ -38,7 +31,7 @@ namespace Avalonia.OpenGL private PixelSize _initialSize; public RenderTarget(EglDisplay display, EglContext context, - EglSurface glSurface, IEglWindowGlPlatformSurfaceInfo info) + EglSurface glSurface, IEglWindowGlPlatformSurfaceInfo info) : base(display, context) { _display = display; _context = context; @@ -47,70 +40,11 @@ namespace Avalonia.OpenGL _initialSize = info.Size; } - public void Dispose() => _glSurface.Dispose(); + public override void Dispose() => _glSurface.Dispose(); - public bool IsCorrupted => _initialSize != _info.Size; - - public IGlPlatformSurfaceRenderingSession BeginDraw() - { - var l = _context.Lock(); - try - { - if (IsCorrupted) - throw new RenderTargetCorruptedException(); - var restoreContext = _context.MakeCurrent(_glSurface); - _display.EglInterface.WaitClient(); - _display.EglInterface.WaitGL(); - _display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); - - return new Session(_display, _context, _glSurface, _info, l, restoreContext); - } - catch - { - l.Dispose(); - throw; - } - } + public override bool IsCorrupted => _initialSize != _info.Size; - class Session : IGlPlatformSurfaceRenderingSession - { - private readonly EglContext _context; - private readonly EglSurface _glSurface; - private readonly IEglWindowGlPlatformSurfaceInfo _info; - private readonly EglDisplay _display; - private IDisposable _lock; - private readonly IDisposable _restoreContext; - - - public Session(EglDisplay display, EglContext context, - EglSurface glSurface, IEglWindowGlPlatformSurfaceInfo info, - IDisposable @lock, IDisposable restoreContext) - { - _context = context; - _display = display; - _glSurface = glSurface; - _info = info; - _lock = @lock; - _restoreContext = restoreContext; - } - - 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(); - } - - public IGlContext Context => _context; - public PixelSize Size => _info.Size; - public double Scaling => _info.Scaling; - public bool IsYFlipped { get; } - } + public override IGlPlatformSurfaceRenderingSession BeginDraw() => base.BeginDraw(_glSurface, _info); } } } diff --git a/src/Avalonia.OpenGL/EglGlPlatformSurfaceBase.cs b/src/Avalonia.OpenGL/EglGlPlatformSurfaceBase.cs new file mode 100644 index 0000000000..00c7c4796c --- /dev/null +++ b/src/Avalonia.OpenGL/EglGlPlatformSurfaceBase.cs @@ -0,0 +1,103 @@ +using System; + +namespace Avalonia.OpenGL +{ + public abstract class EglGlPlatformSurfaceBase : IGlPlatformSurface + { + public interface IEglWindowGlPlatformSurfaceInfo + { + IntPtr Handle { get; } + PixelSize Size { get; } + double Scaling { get; } + } + + public abstract IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(); + } + + public abstract class EglPlatformSurfaceRenderTargetBase : IGlPlatformSurfaceRenderTargetWithCorruptionInfo + { + private readonly EglDisplay _display; + private readonly EglContext _context; + + protected EglPlatformSurfaceRenderTargetBase(EglDisplay display, EglContext context) + { + _display = display; + _context = context; + } + + public abstract bool IsCorrupted { get; } + + public virtual void Dispose() + { + + } + + public abstract IGlPlatformSurfaceRenderingSession BeginDraw(); + + protected IGlPlatformSurfaceRenderingSession BeginDraw(EglSurface surface, + EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info, Action onFinish = null, bool isYFlipped = false) + { + var l = _context.Lock(); + try + { + if (IsCorrupted) + throw new RenderTargetCorruptedException(); + var restoreContext = _context.MakeCurrent(surface); + _display.EglInterface.WaitClient(); + _display.EglInterface.WaitGL(); + _display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); + + return new Session(_display, _context, surface, info, l, restoreContext, onFinish, isYFlipped); + } + catch + { + l.Dispose(); + throw; + } + } + + 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; } + } + } +} diff --git a/src/Avalonia.OpenGL/EglInterface.cs b/src/Avalonia.OpenGL/EglInterface.cs index c0665a1ea1..666c0d8351 100644 --- a/src/Avalonia.OpenGL/EglInterface.cs +++ b/src/Avalonia.OpenGL/EglInterface.cs @@ -17,25 +17,21 @@ namespace Avalonia.OpenGL } + public EglInterface(Func getProcAddress) : base(getProcAddress) + { + + } + public EglInterface(string library) : base(Load(library)) { } - [DllImport("libegl.dll", CharSet = CharSet.Ansi)] - static extern IntPtr eglGetProcAddress(string proc); static Func Load() { var os = AvaloniaLocator.Current.GetService().GetRuntimeInfo().OperatingSystem; if(os == OperatingSystemType.Linux || os == OperatingSystemType.Android) return Load("libEGL.so.1"); - if (os == OperatingSystemType.WinNT) - { - var disp = eglGetProcAddress("eglGetPlatformDisplayEXT"); - if (disp == IntPtr.Zero) - throw new OpenGlException("libegl.dll doesn't have eglGetPlatformDisplayEXT entry point"); - return eglGetProcAddress; - } throw new PlatformNotSupportedException(); } @@ -147,6 +143,21 @@ namespace Avalonia.OpenGL return null; return Marshal.PtrToStringAnsi(rv); } + + public delegate IntPtr EglCreatePbufferFromClientBuffer(IntPtr display, int buftype, IntPtr buffer, IntPtr config, int[] attrib_list); + [GlEntryPoint("eglCreatePbufferFromClientBuffer")] + + public EglCreatePbufferFromClientBuffer CreatePbufferFromClientBuffer { get; } + + public delegate bool EglQueryDisplayAttribEXT(IntPtr display, int attr, out IntPtr res); + + [GlEntryPoint("eglQueryDisplayAttribEXT"), GlOptionalEntryPoint] + public EglQueryDisplayAttribEXT QueryDisplayAttribExt { get; } + + public delegate bool EglQueryDeviceAttribEXT(IntPtr display, int attr, out IntPtr res); + + [GlEntryPoint("eglQueryDeviceAttribEXT"), GlOptionalEntryPoint] + public EglQueryDisplayAttribEXT QueryDeviceAttribExt { get; } // ReSharper restore UnassignedGetOnlyAutoProperty } diff --git a/src/Avalonia.Themes.Fluent/CheckBox.xaml b/src/Avalonia.Themes.Fluent/CheckBox.xaml index 5f82fed08c..04799b3bc2 100644 --- a/src/Avalonia.Themes.Fluent/CheckBox.xaml +++ b/src/Avalonia.Themes.Fluent/CheckBox.xaml @@ -8,11 +8,10 @@ - - + diff --git a/src/Avalonia.Themes.Fluent/RadioButton.xaml b/src/Avalonia.Themes.Fluent/RadioButton.xaml index acde4ea0be..8fd569816d 100644 --- a/src/Avalonia.Themes.Fluent/RadioButton.xaml +++ b/src/Avalonia.Themes.Fluent/RadioButton.xaml @@ -13,11 +13,10 @@ - - + diff --git a/src/Avalonia.Visuals/Rendering/RenderLayer.cs b/src/Avalonia.Visuals/Rendering/RenderLayer.cs index d6676e25ff..ddf5f4e5cf 100644 --- a/src/Avalonia.Visuals/Rendering/RenderLayer.cs +++ b/src/Avalonia.Visuals/Rendering/RenderLayer.cs @@ -30,12 +30,13 @@ namespace Avalonia.Rendering { if (Size != size || Scaling != scaling) { + Bitmap.Dispose(); var resized = RefCountable.Create(drawingContext.CreateLayer(size)); using (var context = resized.Item.CreateDrawingContext(null)) { context.Clear(Colors.Transparent); - Bitmap.Dispose(); + Bitmap = resized; Scaling = scaling; Size = size; diff --git a/src/Windows/Avalonia.Win32/Win32GlManager.cs b/src/Windows/Avalonia.Win32/Win32GlManager.cs index 585e68056b..bd188ad53a 100644 --- a/src/Windows/Avalonia.Win32/Win32GlManager.cs +++ b/src/Windows/Avalonia.Win32/Win32GlManager.cs @@ -1,4 +1,5 @@ using Avalonia.OpenGL; +using Avalonia.OpenGL.Angle; namespace Avalonia.Win32 { @@ -15,7 +16,7 @@ namespace Avalonia.Win32 { if (!s_attemptedToInitialize) { - EglFeature = EglGlPlatformFeature.TryCreate(); + EglFeature = EglGlPlatformFeature.TryCreate(() => new AngleWin32EglDisplay()); s_attemptedToInitialize = true; } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 4929283874..9c6bce1c90 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -853,7 +853,7 @@ namespace Avalonia.Win32 private void ShowWindow(WindowState state) { - ShowWindowCommand command; + ShowWindowCommand? command; var newWindowProperties = _windowProperties; @@ -875,8 +875,8 @@ namespace Avalonia.Win32 case WindowState.FullScreen: newWindowProperties.IsFullScreen = true; - UpdateWindowProperties(newWindowProperties); - return; + command = IsWindowVisible(_hwnd) ? (ShowWindowCommand?)null : ShowWindowCommand.Restore; + break; default: throw new ArgumentException("Invalid WindowState."); @@ -884,7 +884,10 @@ namespace Avalonia.Win32 UpdateWindowProperties(newWindowProperties); - UnmanagedMethods.ShowWindow(_hwnd, command); + if (command.HasValue) + { + UnmanagedMethods.ShowWindow(_hwnd, command.Value); + } if (state == WindowState.Maximized) {