From fafd730d295a0ce74d14ac6f2e51e6a1dadb4b8e Mon Sep 17 00:00:00 2001 From: Emmanuel Date: Thu, 10 Sep 2020 16:23:24 +0000 Subject: [PATCH] add extensions --- GLWidget/GLWidget.cs | 19 ++++++ .../OpenTK/Platform/DesktopGraphicsContext.cs | 35 +--------- GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs | 66 ++++++++++--------- GLWidget/OpenTK/Platform/X11/X11GLContext.cs | 14 ++-- GLWidgetTestGTK3/Program.cs | 2 +- 5 files changed, 64 insertions(+), 72 deletions(-) diff --git a/GLWidget/GLWidget.cs b/GLWidget/GLWidget.cs index 440f425..8ca3319 100644 --- a/GLWidget/GLWidget.cs +++ b/GLWidget/GLWidget.cs @@ -59,6 +59,7 @@ namespace OpenTK private IGraphicsContext _graphicsContext; private IWindowInfo _windowInfo; private bool _initialized; + private int swapInterval = 0; #endregion @@ -92,6 +93,18 @@ namespace OpenTK /// The minor version of OpenGL to use. public int GLVersionMinor { get; set; } + public int SwapInterval + { + get => swapInterval; set + { + swapInterval = value; + + if (GraphicsContext != null) + { + GraphicsContext.SwapInterval = value; + } + } + } public GraphicsContextFlags GraphicsContextFlags { get; @@ -266,6 +279,8 @@ namespace OpenTK { _initialized = true; + Gdk.GLContext.ClearCurrent(); + // If this looks uninitialized... initialize. if (ColorBPP == 0) { @@ -326,6 +341,10 @@ namespace OpenTK OnGraphicsContextInitialized(); } + GraphicsContext.SwapInterval = SwapInterval; + + var swap = GraphicsContext.SwapInterval; + OnInitialized(); } diff --git a/GLWidget/OpenTK/Platform/DesktopGraphicsContext.cs b/GLWidget/OpenTK/Platform/DesktopGraphicsContext.cs index 07acb79..14e735f 100644 --- a/GLWidget/OpenTK/Platform/DesktopGraphicsContext.cs +++ b/GLWidget/OpenTK/Platform/DesktopGraphicsContext.cs @@ -41,39 +41,8 @@ namespace OpenTK.Platform Stopwatch time = Stopwatch.StartNew(); - Assembly assembly; - try - { - assembly = Assembly.Load("OpenTK.Graphics"); - } - catch - { - // Failed to load graphics, oh well. - // Up to the user I guess? - // TODO: Should we expose this load failure to the user better? - return; - } - - var provider = new GTKBindingHelper(); - - void LoadBindings(string typeNamespace) - { - var type = assembly.GetType($"OpenTK.Graphics.{typeNamespace}.GL"); - if (type == null) - { - return; - } - - var load = type.GetMethod("LoadBindings"); - load.Invoke(null, new object[] { provider }); - } - - LoadBindings("ES11"); - LoadBindings("ES20"); - LoadBindings("ES30"); - LoadBindings("OpenGL"); - LoadBindings("OpenGL4"); - + GTKBindingHelper.InitializeGlBindings(); + Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds); } } diff --git a/GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs b/GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs index 9f07494..d1e0a3e 100644 --- a/GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs +++ b/GLWidget/OpenTK/Platform/X11/Bindings/Glx.cs @@ -253,7 +253,7 @@ namespace OpenTK.Platform.X11 /// /// Provides access to GLX functions. /// - internal class Glx : Graphics.GraphicsBindingsBase + internal unsafe class Glx : Graphics.GraphicsBindingsBase { private const string Library = "libGL.so.1"; private static readonly object sync_root = new object(); @@ -314,31 +314,45 @@ namespace OpenTK.Platform.X11 { for (int i = 0; i < _EntryPointsInstance.Length; i++) { - _EntryPointsInstance[i] = Arb.GetProcAddress(new IntPtr(name + _EntryPointNameOffsetsInstance[i])); + _EntryPointsInstance[i] = GetProcAddressARB(new IntPtr(name + _EntryPointNameOffsetsInstance[i])); } } } - IntPtr pointer = Arb.GetProcAddress("glXCreateContextAttribsARB"); + IntPtr pointer = GetProcAddressARB("glXCreateContextAttribsARB"); if (pointer != null && pointer != IntPtr.Zero) { - Arb.glXCreateContextAttribsARB = (Arb.CreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer( - pointer, typeof(Arb.CreateContextAttribsARB)); + pglXCreateContextAttribsARB = (glXCreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer( + pointer, typeof(glXCreateContextAttribsARB)); } + + glXSwapIntervalEXT = GetProcAddress("glXSwapIntervalEXT"); + glXSwapIntervalMESA = GetProcAddress("glXSwapIntervalMESA"); + glXGetSwapIntervalMESA = GetProcAddress("glXGetSwapIntervalMESA"); + glXSwapIntervalSGI = GetProcAddress("glXSwapIntervalSGI"); } - public partial class Arb - { - [DllImport(Library, EntryPoint = "glXGetProcAddressARB")] - public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName); + [DllImport(Library, EntryPoint = "glXGetProcAddressARB")] + public static extern IntPtr GetProcAddressARB([MarshalAs(UnmanagedType.LPTStr)] string procName); - [DllImport(Library, EntryPoint = "glXGetProcAddressARB")] - public static extern IntPtr GetProcAddress(IntPtr procName); + [DllImport(Library, EntryPoint = "glXGetProcAddressARB")] + public static extern IntPtr GetProcAddressARB(IntPtr procName); - public unsafe delegate IntPtr CreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs); - public static unsafe CreateContextAttribsARB glXCreateContextAttribsARB = null; - } + internal delegate IntPtr glXCreateContextAttribsARB(IntPtr dpy, IntPtr config, IntPtr share_context, bool direct, int* attrib_list); + internal static glXCreateContextAttribsARB pglXCreateContextAttribsARB; + + public delegate void SwapIntervalEXT(IntPtr dpy, IntPtr drawable, int interval); + public static SwapIntervalEXT glXSwapIntervalEXT; + + public delegate int SwapIntervalMESA(uint interval); + public static SwapIntervalMESA glXSwapIntervalMESA; + + public delegate int GetSwapIntervalMESA(); + public static GetSwapIntervalMESA glXGetSwapIntervalMESA; + + public delegate int SwapIntervalSGI(int interval); + public static SwapIntervalSGI glXSwapIntervalSGI; internal static bool SupportsFunction(string name) { @@ -423,6 +437,12 @@ namespace OpenTK.Platform.X11 } } } + public static TDelegate GetProcAddress(string name) where TDelegate : class + { + IntPtr addr = GetProcAddress(name); + if (addr == IntPtr.Zero) return null; + return (TDelegate)(object)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(addr, typeof(TDelegate)); + } // Returns an array of GLXFBConfig structures. [DllImport(Library, EntryPoint = "glXChooseFBConfig")] @@ -430,23 +450,7 @@ namespace OpenTK.Platform.X11 // Returns a pointer to an XVisualInfo structure. [DllImport(Library, EntryPoint = "glXGetVisualFromFBConfig")] - public unsafe extern static IntPtr GetVisualFromFBConfig(IntPtr dpy, IntPtr fbconfig); - - [Slot(0)] - [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - 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.Cdecl)] - internal static extern ErrorCode glXSwapIntervalEXT(IntPtr display, IntPtr drawable, int interval); - [Slot(2)] - [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - internal static extern ErrorCode glXSwapIntervalMESA(int interval); - [Slot(3)] - [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - internal static extern int glXGetSwapIntervalMESA(); - [Slot(4)] - [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - internal static extern ErrorCode glXSwapIntervalSGI(int interval); + public unsafe extern static IntPtr GetVisualFromFBConfig(IntPtr dpy, IntPtr fbconfig); } } diff --git a/GLWidget/OpenTK/Platform/X11/X11GLContext.cs b/GLWidget/OpenTK/Platform/X11/X11GLContext.cs index 121fe15..2f7ef45 100644 --- a/GLWidget/OpenTK/Platform/X11/X11GLContext.cs +++ b/GLWidget/OpenTK/Platform/X11/X11GLContext.cs @@ -186,11 +186,11 @@ namespace OpenTK.Platform.X11 { fixed (int* attribs_ptr = attributes.ToArray()) { - context = Glx.Arb.glXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, direct, attribs_ptr); + context = Glx.pglXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, direct, attribs_ptr); if (context == IntPtr.Zero) { Debug.Write(String.Format("failed. Trying direct: {0}... ", !direct)); - context = Glx.Arb.glXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, !direct, attribs_ptr); + context = Glx.pglXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, !direct, attribs_ptr); } } } @@ -390,7 +390,7 @@ namespace OpenTK.Platform.X11 } else if (vsync_mesa_supported) { - return OpenGL.Glx.GetSwapIntervalMESA(); + return Glx.glXGetSwapIntervalMESA(); } else if (vsync_sgi_supported) { @@ -418,15 +418,15 @@ namespace OpenTK.Platform.X11 { if (vsync_ext_supported) { - OpenGL.Glx.SwapIntervalEXT(Display, currentWindow.Handle, value); + Glx.glXSwapIntervalEXT(Display, currentWindow.Handle, value); } else if (vsync_mesa_supported) { - error_code = (ErrorCode)OpenGL.Glx.SwapIntervalMESA((uint)value); + error_code = (ErrorCode)Glx.glXSwapIntervalMESA((uint)value); } else if (vsync_sgi_supported) { - error_code = (ErrorCode)OpenGL.Glx.SwapIntervalSGI(value); + error_code = (ErrorCode)Glx.glXSwapIntervalMESA((uint)value); } } @@ -462,7 +462,7 @@ namespace OpenTK.Platform.X11 Debug.Print("Context supports adaptive vsync: {0}.", vsync_tear_supported); - base.LoadAll(); + GTKBindingHelper.InitializeGlBindings(); } public override IntPtr GetAddress(IntPtr function) diff --git a/GLWidgetTestGTK3/Program.cs b/GLWidgetTestGTK3/Program.cs index f70e6bd..383cead 100644 --- a/GLWidgetTestGTK3/Program.cs +++ b/GLWidgetTestGTK3/Program.cs @@ -10,7 +10,7 @@ namespace GLWidgetTestGTK3 { public static void Main(string[] args) { - GTKBindingHelper.InitXThreads(); + // GTKBindingHelper.InitXThreads(); // GTK Application.Init(); MainWindow win = MainWindow.Create();