From 95f73310d8c50fd5091b7bee9e5c14b9c3e75feb Mon Sep 17 00:00:00 2001 From: thefiddler Date: Sat, 26 Apr 2014 18:24:13 +0200 Subject: [PATCH] [X11] Implemented new-style bindings for GLX Replaced delegates with call instructions and completely removed the old extension loading code. --- Source/OpenTK/OpenTK.csproj | 3 - Source/OpenTK/Platform/X11/Bindings/Glx.cs | 83 +++++++++------ Source/OpenTK/Platform/X11/GlxHelper.cs | 111 --------------------- Source/OpenTK/Platform/X11/X11GLContext.cs | 5 +- 4 files changed, 53 insertions(+), 149 deletions(-) delete mode 100644 Source/OpenTK/Platform/X11/GlxHelper.cs diff --git a/Source/OpenTK/OpenTK.csproj b/Source/OpenTK/OpenTK.csproj index c0cff003..bfca0b29 100644 --- a/Source/OpenTK/OpenTK.csproj +++ b/Source/OpenTK/OpenTK.csproj @@ -345,9 +345,6 @@ Code - - Code - Code diff --git a/Source/OpenTK/Platform/X11/Bindings/Glx.cs b/Source/OpenTK/Platform/X11/Bindings/Glx.cs index 9c1920f6..4a312b9d 100644 --- a/Source/OpenTK/Platform/X11/Bindings/Glx.cs +++ b/Source/OpenTK/Platform/X11/Bindings/Glx.cs @@ -259,8 +259,38 @@ namespace OpenTK.Platform.X11 /// /// Provides access to GLX functions. /// - partial class Glx + class Glx { + const string Library = "libGL.so.1"; + + static string[] EntryPointNames = new string[] + { + "glXCreateContextAttribs", + "glXSwapIntervalSGI", + }; + static IntPtr[] EntryPoints = new IntPtr[EntryPointNames.Length]; + + static Glx() + { + // GLX entry points are not bound to a context. + // This means we can load them without creating + // a context first! (unlike WGL) + for (int i = 0; i < EntryPointNames.Length; i++) + { + EntryPoints[i] = Arb.GetProcAddress(EntryPointNames[i]); + } + } + + internal static bool SupportsFunction(string name) + { + int index = Array.IndexOf(EntryPointNames, name); + if (index >= 0) + { + return EntryPoints[index] != IntPtr.Zero; + } + return false; + } + #region GLX functions [DllImport(Library, EntryPoint = "glXIsDirect")] @@ -343,40 +373,26 @@ namespace OpenTK.Platform.X11 #endregion - #region Extensions - - public partial class Sgi - { - public static ErrorCode SwapInterval(int interval) - { - return (ErrorCode)Delegates.glXSwapIntervalSGI(interval); - } - } - public partial class Arb { - #region CreateContextAttri + #region CreateContextAttribs + [AutoGenerated(EntryPoint = "glXCreateContextAttribsARB")] unsafe public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs) { - return Delegates.glXCreateContextAttribsARB(display, fbconfig, share_context, direct, attribs); + throw new NotImplementedException(); } + [AutoGenerated(EntryPoint = "glXCreateContextAttribsARB")] public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int[] attribs) { - unsafe - { - fixed (int* attribs_ptr = attribs) - { - return Delegates.glXCreateContextAttribsARB(display, fbconfig, share_context, direct, attribs_ptr); - } - } + throw new NotImplementedException(); } #endregion - + #region GetProcAddress - + // The linux OpenGL ABI 3.6 (1999) requires // that glXGetProcAddressARB be available as // a static export. The same is *not* true @@ -385,22 +401,25 @@ namespace OpenTK.Platform.X11 // See http://www.opengl.org/registry/ABI/ [DllImport(Library, EntryPoint = "glXGetProcAddressARB")] public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName); - + #endregion } - internal static partial class Delegates + public partial class Sgi { - [SuppressUnmanagedCodeSecurity] - public delegate int SwapIntervalSGI(int interval); - public static SwapIntervalSGI glXSwapIntervalSGI = null; - - [SuppressUnmanagedCodeSecurity] - unsafe public delegate IntPtr CreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs); - unsafe public static CreateContextAttribsARB glXCreateContextAttribsARB = null; + [AutoGenerated(EntryPoint = "glXSwapIntervalSGI")] + public static ErrorCode SwapInterval(int interval) + { + throw new NotImplementedException(); + } } - #endregion + [Slot(0)] + [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + internal unsafe static extern IntPtr glXCreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs); + [Slot(1)] + [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + internal static extern IntPtr glXSwapIntervalSGI(int interval); #endregion } diff --git a/Source/OpenTK/Platform/X11/GlxHelper.cs b/Source/OpenTK/Platform/X11/GlxHelper.cs deleted file mode 100644 index 36d4022f..00000000 --- a/Source/OpenTK/Platform/X11/GlxHelper.cs +++ /dev/null @@ -1,111 +0,0 @@ -#region --- License --- -/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos - * See license.txt for license info - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Diagnostics; - -using OpenTK.Graphics; - -namespace OpenTK.Platform.X11 -{ - partial class Glx : BindingsBase - { - const string Library = "libGL.so.1"; - static readonly object sync_root = new object(); - - static Glx() - { - // GLX entry points are not bound to a context. - // This means we can load them without creating - // a context first! (unlike WGL) - // See - // for more details. - Debug.WriteLine("Loading GLX entry points."); - new Glx().LoadEntryPoints(); - } - - protected override object SyncRoot - { - get { return sync_root; } - } - - protected override IntPtr GetAddress(string funcname) - { - // We must use glXGetProcAddressARB, *not* - // glXGetProcAddress. See comment on function - // signature. - return Glx.Arb.GetProcAddress(funcname); - } - -#if false - #region static Delegate LoadDelegate(string name, Type signature) - - /// - /// Creates a System.Delegate that can be used to call an OpenGL function, core or extension. - /// - /// The name of the Wgl function (eg. "wglNewList") - /// The signature of the OpenGL function. - /// - /// A System.Delegate that can be used to call this OpenGL function, or null if the specified - /// function name did not correspond to an OpenGL function. - /// - static Delegate LoadDelegate(string name, Type signature) - { - Delegate d; - string realName = name.ToLower().StartsWith("glx") ? name.Substring(3) : name; - - if (typeof(Glx).GetMethod(realName, - BindingFlags.NonPublic | BindingFlags.Static) != null) - d = GetExtensionDelegate(name, signature) ?? - Delegate.CreateDelegate(signature, typeof(Glx), realName); - else - d = GetExtensionDelegate(name, signature); - - return d; - } - - #endregion - - #region private static Delegate GetExtensionDelegate(string name, Type signature) - - /// - /// Creates a System.Delegate that can be used to call a dynamically exported OpenGL function. - /// - /// The name of the OpenGL function (eg. "glNewList") - /// The signature of the OpenGL function. - /// - /// A System.Delegate that can be used to call this OpenGL function or null - /// if the function is not available in the current OpenGL context. - /// - private static Delegate GetExtensionDelegate(string name, Type signature) - { - IntPtr address = Glx.GetProcAddress(name); - - if (address == IntPtr.Zero || - address == new IntPtr(1) || // Workaround for buggy nvidia drivers which return - address == new IntPtr(2)) // 1 or 2 instead of IntPtr.Zero for some extensions. - return null; - else - return Marshal.GetDelegateForFunctionPointer(address, signature); - } - - #endregion - - #region internal static void LoadAll - - public static void LoadAll() - { - OpenTK.Platform.Utilities.LoadExtensions(typeof(Glx)); - } - - #endregion -#endif - } -} diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index 9904b4f7..d4e73cca 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -253,7 +253,7 @@ namespace OpenTK.Platform.X11 return SupportsExtension(display, window, "GLX_ARB_create_context") && SupportsExtension(display, window, "GLX_ARB_create_context_profile") && - Glx.Delegates.glXCreateContextAttribsARB != null; + Glx.SupportsFunction("glXCreateContextAttribsARB"); } #endregion @@ -380,8 +380,7 @@ namespace OpenTK.Platform.X11 public override void LoadAll() { - new Glx().LoadEntryPoints(); - vsync_supported = this.GetAddress("glXSwapIntervalSGI") != IntPtr.Zero; + vsync_supported = Glx.SupportsFunction("glXSwapIntervalSGI"); Debug.Print("Context supports vsync: {0}.", vsync_supported); base.LoadAll();