mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-24 18:35:32 +00:00
Serialize context construction to avoid threading issues with shared contexts.
This commit is contained in:
parent
7e1ebfea6b
commit
544cf9d405
|
@ -32,7 +32,7 @@ namespace OpenTK.Graphics
|
|||
|
||||
static bool share_contexts = true;
|
||||
static bool direct_rendering = true;
|
||||
readonly static object context_lock = new object();
|
||||
readonly static object SyncRoot = new object();
|
||||
// Maps OS-specific context handles to GraphicsContext weak references.
|
||||
readonly static Dictionary<ContextHandle, WeakReference> available_contexts = new Dictionary<ContextHandle, WeakReference>();
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace OpenTK.Graphics
|
|||
{
|
||||
implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle);
|
||||
|
||||
lock (context_lock)
|
||||
lock (SyncRoot)
|
||||
{
|
||||
available_contexts.Add((implementation as IGraphicsContextInternal).Context, new WeakReference(this));
|
||||
}
|
||||
|
@ -77,6 +77,8 @@ namespace OpenTK.Graphics
|
|||
/// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored.
|
||||
/// </remarks>
|
||||
public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
bool designMode = false;
|
||||
if (mode == null && window == null)
|
||||
|
@ -101,8 +103,6 @@ namespace OpenTK.Graphics
|
|||
|
||||
IGraphicsContext shareContext = null;
|
||||
if (GraphicsContext.ShareContexts)
|
||||
{
|
||||
lock (context_lock)
|
||||
{
|
||||
// A small hack to create a shared context with the first available context.
|
||||
foreach (WeakReference r in GraphicsContext.available_contexts.Values)
|
||||
|
@ -111,7 +111,6 @@ namespace OpenTK.Graphics
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: Add a DummyFactory implementing IPlatformFactory.
|
||||
if (designMode)
|
||||
|
@ -123,16 +122,14 @@ namespace OpenTK.Graphics
|
|||
case true: implementation = Factory.Embedded.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break;
|
||||
}
|
||||
|
||||
lock (context_lock)
|
||||
{
|
||||
available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Debug.Unindent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -201,7 +198,7 @@ namespace OpenTK.Graphics
|
|||
{
|
||||
get
|
||||
{
|
||||
lock (context_lock)
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (available_contexts.Count > 0)
|
||||
{
|
||||
|
@ -282,7 +279,7 @@ namespace OpenTK.Graphics
|
|||
/// </remarks>
|
||||
void CreateContext(bool direct, IGraphicsContext source)
|
||||
{
|
||||
lock (context_lock)
|
||||
lock (SyncRoot)
|
||||
{
|
||||
available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
|
||||
}
|
||||
|
@ -418,7 +415,7 @@ namespace OpenTK.Graphics
|
|||
if (!IsDisposed)
|
||||
{
|
||||
Debug.Print("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString());
|
||||
lock (context_lock)
|
||||
lock (SyncRoot)
|
||||
{
|
||||
available_contexts.Remove((this as IGraphicsContextInternal).Context);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace OpenTK.Platform.Windows
|
|||
/// </summary>
|
||||
internal sealed class WinGLContext : DesktopGraphicsContext
|
||||
{
|
||||
static object SyncRoot = new object();
|
||||
|
||||
static IntPtr opengl32Handle;
|
||||
static bool wgl_loaded;
|
||||
const string opengl32Name = "OPENGL32.DLL";
|
||||
|
@ -35,6 +37,8 @@ namespace OpenTK.Platform.Windows
|
|||
#region --- Contructors ---
|
||||
|
||||
static WinGLContext()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
// Dynamically load the OpenGL32.dll in order to use the extension loading capabilities of Wgl.
|
||||
if (opengl32Handle == IntPtr.Zero)
|
||||
|
@ -46,9 +50,15 @@ namespace OpenTK.Platform.Windows
|
|||
Debug.WriteLine(String.Format("Loaded opengl32.dll: {0}", opengl32Handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public WinGLContext(GraphicsMode format, WinWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
// There are many ways this code can break when accessed by multiple threads. The biggest offender is
|
||||
// the sharedContext stuff, which will only become valid *after* this constructor returns.
|
||||
// The easiest solution is to serialize all context construction - hence the big lock, below.
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (window == null)
|
||||
throw new ArgumentNullException("window", "Must point to a valid window.");
|
||||
|
@ -89,6 +99,7 @@ namespace OpenTK.Platform.Windows
|
|||
if (flags != 0)
|
||||
{
|
||||
attributes.Add((int)ArbCreateContext.Flags);
|
||||
#warning "This is not entirely correct: Embedded is not a valid flag! We need to add a GetARBContextFlags(GraphicsContextFlags) method."
|
||||
attributes.Add((int)flags);
|
||||
}
|
||||
attributes.Add(0);
|
||||
|
@ -128,6 +139,7 @@ namespace OpenTK.Platform.Windows
|
|||
Wgl.Imports.ShareLists((sharedContext as IGraphicsContextInternal).Context.Handle, Handle.Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
Loading…
Reference in a new issue