From f793f2b318b774feeb7811b4cb098718f0af52f7 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 9 Dec 2022 08:04:13 -0800 Subject: [PATCH] WGL: Lock shared context before creating a new one --- .../Avalonia.Win32/OpenGl/WglContext.cs | 7 ++++ .../Avalonia.Win32/OpenGl/WglDisplay.cs | 33 +++++++++++-------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglContext.cs b/src/Windows/Avalonia.Win32/OpenGl/WglContext.cs index a2c0d9203d..22d125fede 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglContext.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglContext.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reactive.Disposables; +using System.Threading; using Avalonia.OpenGL; using Avalonia.Platform; using Avalonia.Win32.Interop; @@ -69,6 +70,12 @@ namespace Avalonia.Win32.OpenGl public bool IsLost { get; private set; } public IDisposable EnsureCurrent() => MakeCurrent(); + internal IDisposable Lock() + { + Monitor.Enter(_lock); + return Disposable.Create(_lock, Monitor.Exit); + } + public IntPtr CreateConfiguredDeviceContext(IntPtr hWnd) { diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs b/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs index 976d226bdd..cac044e953 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs @@ -138,20 +138,25 @@ namespace Avalonia.Win32.OpenGl { if(version.Type != GlProfileType.OpenGL) continue; - var context = WglCreateContextAttribsArb(dc, shareContext?.Handle ?? IntPtr.Zero, - new[] - { - // major - WGL_CONTEXT_MAJOR_VERSION_ARB, version.Major, - // minor - WGL_CONTEXT_MINOR_VERSION_ARB, version.Minor, - // core profile - WGL_CONTEXT_PROFILE_MASK_ARB, 1, - // debug - // WGL_CONTEXT_FLAGS_ARB, 1, - // end - 0, 0 - }); + IntPtr context; + using (shareContext?.Lock()) + { + context = WglCreateContextAttribsArb(dc, shareContext?.Handle ?? IntPtr.Zero, + new[] + { + // major + WGL_CONTEXT_MAJOR_VERSION_ARB, version.Major, + // minor + WGL_CONTEXT_MINOR_VERSION_ARB, version.Minor, + // core profile + WGL_CONTEXT_PROFILE_MASK_ARB, 1, + // debug + // WGL_CONTEXT_FLAGS_ARB, 1, + // end + 0, 0 + }); + } + using(new WglRestoreContext(dc, context, null)) GlDebugMessageCallback(Marshal.GetFunctionPointerForDelegate(_debugCallback), IntPtr.Zero); if (context != IntPtr.Zero)