Przeglądaj źródła

Merge branch 'master' into fixes/TypefaceLeak

danwalmsley 5 lat temu
rodzic
commit
a085395c1c

+ 3 - 1
src/Avalonia.Controls/ApiCompatBaseline.txt

@@ -12,7 +12,9 @@ MembersMustExist : Member 'public Avalonia.DirectProperty<Avalonia.Controls.Tree
 MembersMustExist : Member 'public Avalonia.Interactivity.RoutedEvent<Avalonia.Controls.SelectionChangedEventArgs> Avalonia.Interactivity.RoutedEvent<Avalonia.Controls.SelectionChangedEventArgs> 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.Controls.Primitives.SelectingItemsControl, Avalonia.Controls.ISelectionModel> Avalonia.DirectProperty<Avalonia.Controls.Primitives.SelectingItemsControl, Avalonia.Controls.ISelectionModel> 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

+ 10 - 4
src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs

@@ -47,6 +47,11 @@ namespace Avalonia.Controls.ApplicationLifetimes
         /// <inheritdoc/>
         public event EventHandler<ControlledApplicationLifetimeExitEventArgs> Exit;
 
+        /// <summary>
+        /// Gets the arguments passed to the AppBuilder Start method.
+        /// </summary>
+        public string[] Args { get; set; }
+        
         /// <inheritdoc/>
         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<T>, new()
         {
-            var lifetime = new ClassicDesktopStyleApplicationLifetime() {ShutdownMode = shutdownMode};
+            var lifetime = new ClassicDesktopStyleApplicationLifetime()
+            {
+                Args = args,
+                ShutdownMode = shutdownMode
+            };
             builder.SetupWithLifetime(lifetime);
             return lifetime.Start(args);
         }

+ 7 - 0
src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs

@@ -8,6 +8,13 @@ namespace Avalonia.Controls.ApplicationLifetimes
     /// </summary>
     public interface IClassicDesktopStyleApplicationLifetime : IControlledApplicationLifetime
     {
+        /// <summary>
+        /// Gets the arguments passed to the
+        /// <see cref="ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime{T}(T, string[], ShutdownMode)"/>
+        /// method.
+        /// </summary>
+        string[] Args { get; }
+        
         /// <summary>
         /// Gets or sets the <see cref="ShutdownMode"/>. This property indicates whether the application is shutdown explicitly or implicitly. 
         /// If <see cref="ShutdownMode"/> is set to OnExplicitShutdown the application is only closes if Shutdown is called.

+ 31 - 0
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<string, IntPtr> 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;
+            }
+        }
+
+    }
+}

+ 88 - 0
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<AngleOptions>()?.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 });
+        }
+    }
+}

+ 10 - 0
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;
     }
 }

+ 35 - 45
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<AngleOptions>()?.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);
+        }
     }
 }

+ 4 - 3
src/Avalonia.OpenGL/EglGlPlatformFeature.cs

@@ -20,12 +20,13 @@ namespace Avalonia.OpenGL
             if (feature != null)
                 AvaloniaLocator.CurrentMutable.Bind<IWindowingPlatformGlFeature>().ToConstant(feature);
         }
-        
-        public static EglGlPlatformFeature TryCreate()
+
+        public static EglGlPlatformFeature TryCreate() => TryCreate(() => new EglDisplay());
+        public static EglGlPlatformFeature TryCreate(Func<EglDisplay> displayFactory)
         {
             try
             {
-                var disp = new EglDisplay();
+                var disp = displayFactory();
                 return new EglGlPlatformFeature
                 {
                     _display = disp,

+ 9 - 75
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);
         }
     }
 }

+ 103 - 0
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; }
+        }
+    }
+}

+ 20 - 9
src/Avalonia.OpenGL/EglInterface.cs

@@ -17,25 +17,21 @@ namespace Avalonia.OpenGL
             
         }
         
+        public EglInterface(Func<string, IntPtr> getProcAddress) : base(getProcAddress)
+        {
+            
+        }
+        
         public EglInterface(string library) : base(Load(library))
         {
         }
 
-        [DllImport("libegl.dll", CharSet = CharSet.Ansi)]
-        static extern IntPtr eglGetProcAddress(string proc);
         
         static Func<string, IntPtr> Load()
         {
             var os = AvaloniaLocator.Current.GetService<IRuntimePlatform>().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
     }

+ 1 - 2
src/Avalonia.Themes.Fluent/CheckBox.xaml

@@ -8,11 +8,10 @@
     <Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUnchecked}" />
     <Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUnchecked}" />
     <Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUnchecked}" />
-    <Setter Property="Padding" Value="8,5,0,0" />
     <Setter Property="HorizontalAlignment" Value="Left" />
     <Setter Property="VerticalAlignment" Value="Center" />
     <Setter Property="HorizontalContentAlignment" Value="Left" />
-    <Setter Property="VerticalContentAlignment" Value="Top" />    
+    <Setter Property="VerticalContentAlignment" Value="Center" />    
     <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
     <Setter Property="MinWidth" Value="120" />
     <Setter Property="MinHeight" Value="32" />

+ 1 - 2
src/Avalonia.Themes.Fluent/RadioButton.xaml

@@ -13,11 +13,10 @@
     <Setter Property="Background" Value="{DynamicResource RadioButtonBackground}" />
     <Setter Property="Foreground" Value="{DynamicResource RadioButtonForeground}" />
     <Setter Property="BorderBrush" Value="{DynamicResource RadioButtonBorderBrush}" />
-    <Setter Property="Padding" Value="8,6,0,0" />
     <Setter Property="HorizontalAlignment" Value="Left" />
     <Setter Property="VerticalAlignment" Value="Center" />
     <Setter Property="HorizontalContentAlignment" Value="Left" />
-    <Setter Property="VerticalContentAlignment" Value="Top" />    
+    <Setter Property="VerticalContentAlignment" Value="Center" />    
     <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
     <Setter Property="MinWidth" Value="120" />
     <Setter Property="Template">

+ 2 - 1
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;

+ 2 - 1
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;
                 }
 

+ 7 - 4
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)
             {