mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-12 02:55:41 +00:00
Refactored extension loading to remove duplicate code. The logic is now contained in OpenTK/Platform/Utilities.cs
This commit is contained in:
parent
2864c0235b
commit
448e3a476f
|
@ -105,7 +105,7 @@ namespace OpenTK.OpenGL
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region --- Methods ---
|
#region --- Public Methods ---
|
||||||
|
|
||||||
#region public static bool SupportsExtension(string name)
|
#region public static bool SupportsExtension(string name)
|
||||||
|
|
||||||
|
@ -193,43 +193,11 @@ namespace OpenTK.OpenGL
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static void LoadAll()
|
public static void LoadAll()
|
||||||
{
|
{
|
||||||
// Using reflection is more than 3 times faster than directly loading delegates on the first
|
//TODO: Route GameWindow context creation through GLContext.
|
||||||
// run, probably due to code generation overhead. Subsequent runs are faster with direct loading
|
//if (GLContext.CurrentContext == null)
|
||||||
// than with reflection, but the first time is more significant.
|
// throw new InvalidOperationException("You must create an OpenGL context before using the GL class.");
|
||||||
|
|
||||||
int supported = 0;
|
OpenTK.Platform.Utilities.LoadExtensions(glClass);
|
||||||
if (delegates == null)
|
|
||||||
{
|
|
||||||
delegates = delegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
|
|
||||||
}
|
|
||||||
|
|
||||||
Trace.Write("GL.LoadAll(): ");
|
|
||||||
|
|
||||||
System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
|
|
||||||
time.Reset();
|
|
||||||
time.Start();
|
|
||||||
|
|
||||||
foreach (FieldInfo f in delegates)
|
|
||||||
{
|
|
||||||
Delegate d = LoadDelegate(f.Name, f.FieldType);
|
|
||||||
if (d != null)
|
|
||||||
{
|
|
||||||
++supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
f.SetValue(null, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Stop();
|
|
||||||
Trace.WriteLine(String.Format("{0} OpenGL extensions loaded in {1} milliseconds.", supported, time.ElapsedMilliseconds));
|
|
||||||
time.Reset();
|
|
||||||
|
|
||||||
rebuildExtensionList = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set(object d, Delegate value)
|
|
||||||
{
|
|
||||||
d = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -25,20 +25,20 @@ namespace OpenTK.OpenGL
|
||||||
private static Dictionary<string, bool> AvailableExtensions = new Dictionary<string, bool>();
|
private static Dictionary<string, bool> AvailableExtensions = new Dictionary<string, bool>();
|
||||||
private static bool rebuildExtensionList = true;
|
private static bool rebuildExtensionList = true;
|
||||||
|
|
||||||
private static Assembly assembly;
|
//private static Assembly assembly;
|
||||||
private static Type glClass;
|
//private static Type glClass;
|
||||||
private static Type delegatesClass;
|
//private static Type delegatesClass;
|
||||||
private static Type importsClass;
|
private static Type importsClass = typeof(Imports);
|
||||||
|
|
||||||
static Glu()
|
static Glu()
|
||||||
{
|
{
|
||||||
assembly = Assembly.GetExecutingAssembly();//Assembly.Load("OpenTK.OpenGL");
|
//assembly = Assembly.GetExecutingAssembly();//Assembly.Load("OpenTK.OpenGL");
|
||||||
glClass = assembly.GetType("OpenTK.OpenGL.Glu");
|
//glClass = assembly.GetType("OpenTK.OpenGL.Glu");
|
||||||
delegatesClass = glClass.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic);
|
//delegatesClass = glClass.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
importsClass = glClass.GetNestedType("Imports", BindingFlags.Static | BindingFlags.NonPublic);
|
//importsClass = glClass.GetNestedType("Imports", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region private static Delegate GetDelegate(string name, Type signature)
|
#region private static Delegate LoadDelegate(string name, Type signature)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a System.Delegate that can be used to call a GLU function, core or extension.
|
/// Creates a System.Delegate that can be used to call a GLU function, core or extension.
|
||||||
|
@ -49,7 +49,7 @@ namespace OpenTK.OpenGL
|
||||||
/// A System.Delegate that can be used to call this GLU function, or null if the specified
|
/// A System.Delegate that can be used to call this GLU function, or null if the specified
|
||||||
/// function name did not correspond to an GLU function.
|
/// function name did not correspond to an GLU function.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
private static Delegate GetDelegate(string name, Type signature)
|
private static Delegate LoadDelegate(string name, Type signature)
|
||||||
{
|
{
|
||||||
MethodInfo m = importsClass.GetMethod(name.Substring(3), BindingFlags.Static | BindingFlags.NonPublic);
|
MethodInfo m = importsClass.GetMethod(name.Substring(3), BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
return
|
return
|
||||||
|
@ -72,14 +72,7 @@ namespace OpenTK.OpenGL
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static void LoadAll()
|
public static void LoadAll()
|
||||||
{
|
{
|
||||||
FieldInfo[] v = delegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
|
OpenTK.Platform.Utilities.LoadExtensions(typeof(Glu));
|
||||||
foreach (FieldInfo f in v)
|
|
||||||
{
|
|
||||||
f.SetValue(null, GetDelegate(f.Name, f.FieldType));
|
|
||||||
}
|
|
||||||
|
|
||||||
AvailableExtensions.Clear();
|
|
||||||
rebuildExtensionList = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -107,14 +100,7 @@ namespace OpenTK.OpenGL
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static bool Load(string function)
|
public static bool Load(string function)
|
||||||
{
|
{
|
||||||
FieldInfo f = delegatesClass.GetField(function);
|
return OpenTK.Platform.Utilities.TryLoadExtension(typeof(Glu), function);
|
||||||
if (f == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
f.SetValue(null, GetDelegate(f.Name, f.FieldType));
|
|
||||||
|
|
||||||
rebuildExtensionList = true;
|
|
||||||
return f.GetValue(null) != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace OpenTK.Platform
|
||||||
/// A pointer to the specified function or IntPtr.Zero if the function isn't
|
/// A pointer to the specified function or IntPtr.Zero if the function isn't
|
||||||
/// available in the current opengl context.
|
/// available in the current opengl context.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
/// <see cref="Marshal.GetDelegateForFunctionPointer"/>
|
// /// <see cref="Marshal.GetDelegateForFunctionPointer"/>
|
||||||
IntPtr GetAddress(string function);
|
IntPtr GetAddress(string function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -21,6 +23,8 @@ namespace OpenTK.Platform
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Utilities
|
public static class Utilities
|
||||||
{
|
{
|
||||||
|
#region internal static bool ThrowOnX11Error
|
||||||
|
|
||||||
static bool throw_on_error;
|
static bool throw_on_error;
|
||||||
internal static bool ThrowOnX11Error
|
internal static bool ThrowOnX11Error
|
||||||
{
|
{
|
||||||
|
@ -46,6 +50,127 @@ namespace OpenTK.Platform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region internal static void LoadExtensions(Type type)
|
||||||
|
|
||||||
|
delegate Delegate LoadDelegateFunction(string name, Type signature);
|
||||||
|
|
||||||
|
/// <internal />
|
||||||
|
/// <summary>Loads all extensions for the specified class. This function is intended
|
||||||
|
/// for OpenGL, Wgl, Glx, OpenAL etc.</summary>
|
||||||
|
/// <param name="type">The class to load extensions for.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>The Type must contain a nested class called "Delegates".</para>
|
||||||
|
/// <para>
|
||||||
|
/// The Type must also implement a static function called LoadDelegate with the
|
||||||
|
/// following signature:
|
||||||
|
/// <code>static Delegate LoadDelegate(string name, Type signature)</code>
|
||||||
|
/// </para>
|
||||||
|
/// <para>This function allocates memory.</para>
|
||||||
|
/// </remarks>
|
||||||
|
internal static void LoadExtensions(Type type)
|
||||||
|
{
|
||||||
|
// Using reflection is more than 3 times faster than directly loading delegates on the first
|
||||||
|
// run, probably due to code generation overhead. Subsequent runs are faster with direct loading
|
||||||
|
// than with reflection, but the first time is more significant.
|
||||||
|
|
||||||
|
int supported = 0;
|
||||||
|
Type extensions_class = type.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if (extensions_class == null)
|
||||||
|
throw new InvalidOperationException("The specified type does not have any loadable extensions.");
|
||||||
|
|
||||||
|
FieldInfo[] delegates = extensions_class.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if (delegates == null)
|
||||||
|
throw new InvalidOperationException("The specified type does not have any loadable extensions.");
|
||||||
|
|
||||||
|
MethodInfo load_delegate_method_info = type.GetMethod("LoadDelegate", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if (load_delegate_method_info == null)
|
||||||
|
throw new InvalidOperationException(type.ToString() + " does not contain a static LoadDelegate method.");
|
||||||
|
LoadDelegateFunction LoadDelegate = (LoadDelegateFunction)Delegate.CreateDelegate(
|
||||||
|
typeof(LoadDelegateFunction), load_delegate_method_info);
|
||||||
|
|
||||||
|
Debug.Write("Load extensions for " + type.ToString() + "... ");
|
||||||
|
|
||||||
|
System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
|
||||||
|
time.Reset();
|
||||||
|
time.Start();
|
||||||
|
|
||||||
|
foreach (FieldInfo f in delegates)
|
||||||
|
{
|
||||||
|
Delegate d = LoadDelegate(f.Name, f.FieldType);
|
||||||
|
if (d != null)
|
||||||
|
++supported;
|
||||||
|
|
||||||
|
f.SetValue(null, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldInfo rebuildExtensionList = type.GetField("rebuildExtensionList", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if (rebuildExtensionList != null)
|
||||||
|
rebuildExtensionList.SetValue(null, true);
|
||||||
|
|
||||||
|
time.Stop();
|
||||||
|
Debug.Print("{0} extensions loaded in {1} ms.", supported, time.ElapsedMilliseconds);
|
||||||
|
time.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region internal static void LoadExtension()
|
||||||
|
|
||||||
|
/// <internal />
|
||||||
|
/// <summary>Loads the specified extension for the specified class. This function is intended
|
||||||
|
/// for OpenGL, Wgl, Glx, OpenAL etc.</summary>
|
||||||
|
/// <param name="type">The class to load extensions for.</param>
|
||||||
|
/// <param name="extension">The extension to load.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>The Type must contain a nested class called "Delegates".</para>
|
||||||
|
/// <para>
|
||||||
|
/// The Type must also implement a static function called LoadDelegate with the
|
||||||
|
/// following signature:
|
||||||
|
/// <code>static Delegate LoadDelegate(string name, Type signature)</code>
|
||||||
|
/// </para>
|
||||||
|
/// <para>This function allocates memory.</para>
|
||||||
|
/// </remarks>
|
||||||
|
internal static bool TryLoadExtension(Type type, string extension)
|
||||||
|
{
|
||||||
|
Type extensions_class = type.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if (extensions_class == null)
|
||||||
|
{
|
||||||
|
Debug.Print(type.ToString(), " does not contain extensions.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadDelegateFunction LoadDelegate = (LoadDelegateFunction)Delegate.CreateDelegate(typeof(LoadDelegateFunction),
|
||||||
|
type.GetMethod("LoadDelegate", BindingFlags.Static | BindingFlags.NonPublic));
|
||||||
|
if (LoadDelegate == null)
|
||||||
|
{
|
||||||
|
Debug.Print(type.ToString(), " does not contain a static LoadDelegate method.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldInfo f = type.GetField(extension, BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if (f == null)
|
||||||
|
{
|
||||||
|
Debug.Print("Extension \"", extension, "\" not found in ", type.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Delegate old = f.GetValue(null) as Delegate;
|
||||||
|
Delegate @new = LoadDelegate(f.Name, f.FieldType);
|
||||||
|
if (old.Target != @new.Target)
|
||||||
|
{
|
||||||
|
f.SetValue(null, @new);
|
||||||
|
FieldInfo rebuildExtensionList = type.GetField("rebuildExtensionList", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if (rebuildExtensionList != null)
|
||||||
|
rebuildExtensionList.SetValue(null, true);
|
||||||
|
}
|
||||||
|
return @new != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region public bool IsIdle
|
#region public bool IsIdle
|
||||||
|
|
||||||
interface IIsIdle { bool IsIdle { get; } }
|
interface IIsIdle { bool IsIdle { get; } }
|
||||||
|
|
|
@ -41,12 +41,11 @@ namespace OpenTK.Platform.Windows
|
||||||
private static Type delegatesClass;
|
private static Type delegatesClass;
|
||||||
private static Type importsClass;
|
private static Type importsClass;
|
||||||
|
|
||||||
private static bool reload_ext_extension_strings = true;
|
private static bool rebuildExtensionList = true;
|
||||||
private static bool reload_arb_extension_strings = true;
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public static Delegate GetDelegate(string name, Type signature)
|
#region static Delegate LoadDelegate(string name, Type signature)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a System.Delegate that can be used to call an OpenGL function, core or extension.
|
/// Creates a System.Delegate that can be used to call an OpenGL function, core or extension.
|
||||||
|
@ -57,21 +56,17 @@ namespace OpenTK.Platform.Windows
|
||||||
/// A System.Delegate that can be used to call this OpenGL function, or null if the specified
|
/// 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.
|
/// function name did not correspond to an OpenGL function.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public static Delegate GetDelegate(string name, Type signature)
|
static Delegate LoadDelegate(string name, Type signature)
|
||||||
{
|
{
|
||||||
Delegate d;
|
Delegate d;
|
||||||
string realName = name.StartsWith("wgl") ? name.Substring(3) : name;
|
string realName = name.StartsWith("wgl") ? name.Substring(3) : name;
|
||||||
|
|
||||||
if (importsClass.GetMethod(realName,
|
if (importsClass.GetMethod(realName,
|
||||||
BindingFlags.NonPublic | BindingFlags.Static) != null)
|
BindingFlags.NonPublic | BindingFlags.Static) != null)
|
||||||
{
|
|
||||||
d = GetExtensionDelegate(name, signature) ??
|
d = GetExtensionDelegate(name, signature) ??
|
||||||
Delegate.CreateDelegate(signature, typeof(Imports), realName);
|
Delegate.CreateDelegate(signature, typeof(Imports), realName);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
d = GetExtensionDelegate(name, signature);
|
d = GetExtensionDelegate(name, signature);
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
@ -114,13 +109,7 @@ namespace OpenTK.Platform.Windows
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LoadAll()
|
public static void LoadAll()
|
||||||
{
|
{
|
||||||
FieldInfo[] v = delegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
|
OpenTK.Platform.Utilities.LoadExtensions(typeof(Wgl));
|
||||||
foreach (FieldInfo f in v)
|
|
||||||
{
|
|
||||||
f.SetValue(null, GetDelegate(f.Name, f.FieldType));
|
|
||||||
}
|
|
||||||
reload_ext_extension_strings = true;
|
|
||||||
reload_arb_extension_strings = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -134,22 +123,7 @@ namespace OpenTK.Platform.Windows
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool Load(string function)
|
public static bool Load(string function)
|
||||||
{
|
{
|
||||||
FieldInfo f = delegatesClass.GetField(function, BindingFlags.Static | BindingFlags.NonPublic);
|
return OpenTK.Platform.Utilities.TryLoadExtension(typeof(Wgl), function);
|
||||||
if (f == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Delegate old = f.GetValue(null) as Delegate;
|
|
||||||
Delegate @new = GetDelegate(f.Name, f.FieldType);
|
|
||||||
|
|
||||||
if (old.Target != @new.Target)
|
|
||||||
{
|
|
||||||
f.SetValue(null, @new);
|
|
||||||
if (function.EndsWith("EXT"))
|
|
||||||
reload_ext_extension_strings = true;
|
|
||||||
else if (function.EndsWith("ARB"))
|
|
||||||
reload_arb_extension_strings = true;
|
|
||||||
}
|
|
||||||
return @new != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -200,11 +174,11 @@ namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
if (Wgl.Delegates.wglGetExtensionsStringARB != null)
|
if (Wgl.Delegates.wglGetExtensionsStringARB != null)
|
||||||
{
|
{
|
||||||
if (extensions == null || reload_arb_extension_strings)
|
if (extensions == null || rebuildExtensionList)
|
||||||
{
|
{
|
||||||
extensions = Wgl.Arb.GetExtensionsString(deviceContext).Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
extensions = Wgl.Arb.GetExtensionsString(deviceContext).Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||||
Array.Sort(extensions);
|
Array.Sort(extensions);
|
||||||
reload_arb_extension_strings = false;
|
rebuildExtensionList = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Array.BinarySearch(extensions, ext) != -1;
|
return Array.BinarySearch(extensions, ext) != -1;
|
||||||
|
@ -227,11 +201,11 @@ namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
if (Wgl.Delegates.wglGetExtensionsStringEXT != null)
|
if (Wgl.Delegates.wglGetExtensionsStringEXT != null)
|
||||||
{
|
{
|
||||||
if (extensions == null || reload_ext_extension_strings)
|
if (extensions == null || rebuildExtensionList)
|
||||||
{
|
{
|
||||||
extensions = Wgl.Ext.GetExtensionsString().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
extensions = Wgl.Ext.GetExtensionsString().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||||
Array.Sort(extensions);
|
Array.Sort(extensions);
|
||||||
reload_ext_extension_strings = false;
|
rebuildExtensionList = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Array.BinarySearch(extensions, ext) != -1;
|
return Array.BinarySearch(extensions, ext) != -1;
|
||||||
|
|
Loading…
Reference in a new issue