mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-25 17:05:37 +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
394cc1f769
commit
5598019f01
|
@ -105,7 +105,7 @@ namespace OpenTK.OpenGL
|
|||
|
||||
#endregion
|
||||
|
||||
#region --- Methods ---
|
||||
#region --- Public Methods ---
|
||||
|
||||
#region public static bool SupportsExtension(string name)
|
||||
|
||||
|
@ -193,43 +193,11 @@ namespace OpenTK.OpenGL
|
|||
/// </remarks>
|
||||
public static void LoadAll()
|
||||
{
|
||||
// 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.
|
||||
//TODO: Route GameWindow context creation through GLContext.
|
||||
//if (GLContext.CurrentContext == null)
|
||||
// throw new InvalidOperationException("You must create an OpenGL context before using the GL class.");
|
||||
|
||||
int supported = 0;
|
||||
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;
|
||||
OpenTK.Platform.Utilities.LoadExtensions(glClass);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -25,20 +25,20 @@ namespace OpenTK.OpenGL
|
|||
private static Dictionary<string, bool> AvailableExtensions = new Dictionary<string, bool>();
|
||||
private static bool rebuildExtensionList = true;
|
||||
|
||||
private static Assembly assembly;
|
||||
private static Type glClass;
|
||||
private static Type delegatesClass;
|
||||
private static Type importsClass;
|
||||
//private static Assembly assembly;
|
||||
//private static Type glClass;
|
||||
//private static Type delegatesClass;
|
||||
private static Type importsClass = typeof(Imports);
|
||||
|
||||
static Glu()
|
||||
{
|
||||
assembly = Assembly.GetExecutingAssembly();//Assembly.Load("OpenTK.OpenGL");
|
||||
glClass = assembly.GetType("OpenTK.OpenGL.Glu");
|
||||
delegatesClass = glClass.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
importsClass = glClass.GetNestedType("Imports", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
//assembly = Assembly.GetExecutingAssembly();//Assembly.Load("OpenTK.OpenGL");
|
||||
//glClass = assembly.GetType("OpenTK.OpenGL.Glu");
|
||||
//delegatesClass = glClass.GetNestedType("Delegates", 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>
|
||||
/// 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
|
||||
/// function name did not correspond to an GLU function.
|
||||
/// </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);
|
||||
return
|
||||
|
@ -72,14 +72,7 @@ namespace OpenTK.OpenGL
|
|||
/// </remarks>
|
||||
public static void LoadAll()
|
||||
{
|
||||
FieldInfo[] v = delegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
|
||||
foreach (FieldInfo f in v)
|
||||
{
|
||||
f.SetValue(null, GetDelegate(f.Name, f.FieldType));
|
||||
}
|
||||
|
||||
AvailableExtensions.Clear();
|
||||
rebuildExtensionList = true;
|
||||
OpenTK.Platform.Utilities.LoadExtensions(typeof(Glu));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -107,14 +100,7 @@ namespace OpenTK.OpenGL
|
|||
/// </remarks>
|
||||
public static bool Load(string function)
|
||||
{
|
||||
FieldInfo f = delegatesClass.GetField(function);
|
||||
if (f == null)
|
||||
return false;
|
||||
|
||||
f.SetValue(null, GetDelegate(f.Name, f.FieldType));
|
||||
|
||||
rebuildExtensionList = true;
|
||||
return f.GetValue(null) != null;
|
||||
return OpenTK.Platform.Utilities.TryLoadExtension(typeof(Glu), function);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace OpenTK.Platform
|
|||
/// A pointer to the specified function or IntPtr.Zero if the function isn't
|
||||
/// available in the current opengl context.
|
||||
/// </returns>
|
||||
/// <see cref="Marshal.GetDelegateForFunctionPointer"/>
|
||||
// /// <see cref="Marshal.GetDelegateForFunctionPointer"/>
|
||||
IntPtr GetAddress(string function);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ using System.Collections.Generic;
|
|||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -21,6 +23,8 @@ namespace OpenTK.Platform
|
|||
/// </summary>
|
||||
public static class Utilities
|
||||
{
|
||||
#region internal static bool ThrowOnX11Error
|
||||
|
||||
static bool throw_on_error;
|
||||
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
|
||||
|
||||
interface IIsIdle { bool IsIdle { get; } }
|
||||
|
|
|
@ -41,12 +41,11 @@ namespace OpenTK.Platform.Windows
|
|||
private static Type delegatesClass;
|
||||
private static Type importsClass;
|
||||
|
||||
private static bool reload_ext_extension_strings = true;
|
||||
private static bool reload_arb_extension_strings = true;
|
||||
private static bool rebuildExtensionList = true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static Delegate GetDelegate(string name, Type signature)
|
||||
#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.
|
||||
|
@ -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
|
||||
/// function name did not correspond to an OpenGL function.
|
||||
/// </returns>
|
||||
public static Delegate GetDelegate(string name, Type signature)
|
||||
static Delegate LoadDelegate(string name, Type signature)
|
||||
{
|
||||
Delegate d;
|
||||
string realName = name.StartsWith("wgl") ? name.Substring(3) : name;
|
||||
|
||||
if (importsClass.GetMethod(realName,
|
||||
BindingFlags.NonPublic | BindingFlags.Static) != null)
|
||||
{
|
||||
d = GetExtensionDelegate(name, signature) ??
|
||||
Delegate.CreateDelegate(signature, typeof(Imports), realName);
|
||||
}
|
||||
else
|
||||
{
|
||||
d = GetExtensionDelegate(name, signature);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
@ -114,13 +109,7 @@ namespace OpenTK.Platform.Windows
|
|||
/// </summary>
|
||||
public static void LoadAll()
|
||||
{
|
||||
FieldInfo[] v = delegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
|
||||
foreach (FieldInfo f in v)
|
||||
{
|
||||
f.SetValue(null, GetDelegate(f.Name, f.FieldType));
|
||||
}
|
||||
reload_ext_extension_strings = true;
|
||||
reload_arb_extension_strings = true;
|
||||
OpenTK.Platform.Utilities.LoadExtensions(typeof(Wgl));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -134,22 +123,7 @@ namespace OpenTK.Platform.Windows
|
|||
/// <returns></returns>
|
||||
public static bool Load(string function)
|
||||
{
|
||||
FieldInfo f = delegatesClass.GetField(function, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
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;
|
||||
return OpenTK.Platform.Utilities.TryLoadExtension(typeof(Wgl), function);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -200,11 +174,11 @@ namespace OpenTK.Platform.Windows
|
|||
{
|
||||
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);
|
||||
Array.Sort(extensions);
|
||||
reload_arb_extension_strings = false;
|
||||
rebuildExtensionList = false;
|
||||
}
|
||||
|
||||
return Array.BinarySearch(extensions, ext) != -1;
|
||||
|
@ -227,11 +201,11 @@ namespace OpenTK.Platform.Windows
|
|||
{
|
||||
if (Wgl.Delegates.wglGetExtensionsStringEXT != null)
|
||||
{
|
||||
if (extensions == null || reload_ext_extension_strings)
|
||||
if (extensions == null || rebuildExtensionList)
|
||||
{
|
||||
extensions = Wgl.Ext.GetExtensionsString().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
Array.Sort(extensions);
|
||||
reload_ext_extension_strings = false;
|
||||
rebuildExtensionList = false;
|
||||
}
|
||||
|
||||
return Array.BinarySearch(extensions, ext) != -1;
|
||||
|
|
Loading…
Reference in a new issue