[X11] Implemented new-style bindings for GLX

Replaced delegates with call instructions and completely removed the
old extension loading code.
This commit is contained in:
thefiddler 2014-04-26 18:24:13 +02:00
parent 44526229be
commit 95f73310d8
4 changed files with 53 additions and 149 deletions

View file

@ -345,9 +345,6 @@
<Compile Include="Platform\X11\Functions.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Platform\X11\GlxHelper.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Platform\X11\API.cs">
<SubType>Code</SubType>
</Compile>

View file

@ -259,8 +259,38 @@ namespace OpenTK.Platform.X11
/// <summary>
/// Provides access to GLX functions.
/// </summary>
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
}

View file

@ -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)
/// <summary>
/// Creates a System.Delegate that can be used to call an OpenGL function, core or extension.
/// </summary>
/// <param name="name">The name of the Wgl function (eg. "wglNewList")</param>
/// <param name="signature">The signature of the OpenGL function.</param>
/// <returns>
/// 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.
/// </returns>
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)
/// <summary>
/// Creates a System.Delegate that can be used to call a dynamically exported OpenGL function.
/// </summary>
/// <param name="name">The name of the OpenGL function (eg. "glNewList")</param>
/// <param name="signature">The signature of the OpenGL function.</param>
/// <returns>
/// 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.
/// </returns>
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
}
}

View file

@ -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();