From ef5aedba6f751874e90c7a16de9ff2ec2efe0243 Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Fri, 10 Jan 2014 09:24:59 +0100 Subject: [PATCH] [Win] More robust WGL extension detection Affects issue #42 and issue #45 --- Source/OpenTK/Platform/Windows/WglHelper.cs | 87 +++++++++++++------------- Source/OpenTK/Platform/Windows/WinGLContext.cs | 12 +++- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/Source/OpenTK/Platform/Windows/WglHelper.cs b/Source/OpenTK/Platform/Windows/WglHelper.cs index fd1c3de..0e86321 100644 --- a/Source/OpenTK/Platform/Windows/WglHelper.cs +++ b/Source/OpenTK/Platform/Windows/WglHelper.cs @@ -8,6 +8,7 @@ #endregion using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Reflection; @@ -34,6 +35,9 @@ namespace OpenTK.Platform.Windows internal const string Library = "OPENGL32.DLL"; + readonly static Dictionary extensions = + new Dictionary(); + private static Assembly assembly; private static Type wglClass; private static Type delegatesClass; @@ -121,43 +125,61 @@ namespace OpenTK.Platform.Windows #endregion - #region public static partial class Arb + public static bool SupportsExtension(string name) + { + return SupportsExtension(Wgl.GetCurrentDC(), name); + } - /// Contains ARB extensions for WGL. - public static partial class Arb + /// + /// Checks if a Wgl extension is supported by the given context. + /// + /// The device context. + /// The extension to check. + /// True if the extension is supported by the given context, false otherwise + public static bool SupportsExtension(IntPtr dc, string name) { - /// - /// Checks if a Wgl extension is supported by the given context. - /// - /// The device context. - /// The extension to check. - /// True if the extension is supported by the given context, false otherwise - public static bool SupportsExtension(WinGLContext context, string ext) + if (extensions.Count == 0) { // We cache this locally, as another thread might create a context which doesn't support this method. // The design is far from ideal, but there's no good solution to this issue as long as we are using // static WGL/GL classes. Fortunately, this issue is extremely unlikely to arise in practice, as you'd // have to create one accelerated and one non-accelerated context in the same application, with the // non-accelerated context coming second. - Wgl.Delegates.GetExtensionsStringARB get = Wgl.Delegates.wglGetExtensionsStringARB; - - if (get != null) + Wgl.Delegates.GetExtensionsStringARB get_arb = Wgl.Delegates.wglGetExtensionsStringARB; + Wgl.Delegates.GetExtensionsStringEXT get_ext = Wgl.Delegates.wglGetExtensionsStringEXT; + IntPtr str_ptr = + get_arb != null ? get_arb(dc) : + get_ext != null ? get_ext() : + IntPtr.Zero; + + if (str_ptr != IntPtr.Zero) { - string[] extensions = null; + string str; + unsafe { - extensions = new string((sbyte*)get(context.DeviceContext)) - .Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + str = new string((sbyte*)str_ptr); } - if (extensions == null || extensions.Length == 0) - return false; - foreach (string s in extensions) - if (s == ext) - return true; + foreach (string ext in str.Split(' ')) + { + extensions.Add(ext, true); + } } - return false; } + + if (extensions.Count > 0) + { + return extensions.ContainsKey(name); + } + return false; + } + + #region public static partial class Arb + + /// Contains ARB extensions for WGL. + public static partial class Arb + { } #endregion @@ -167,27 +189,6 @@ namespace OpenTK.Platform.Windows /// Contains EXT extensions for WGL. public static partial class Ext { - private static string[] extensions; - /// - /// Checks if a Wgl extension is supported by the given context. - /// - /// The extension to check. - /// True if the extension is supported by the given context, false otherwise - public static bool SupportsExtension(string ext) - { - if (Wgl.Delegates.wglGetExtensionsStringEXT != null) - { - if (extensions == null || rebuildExtensionList) - { - extensions = Wgl.Ext.GetExtensionsString().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); - Array.Sort(extensions); - rebuildExtensionList = false; - } - - return Array.BinarySearch(extensions, ext) != -1; - } - return false; - } } #endregion diff --git a/Source/OpenTK/Platform/Windows/WinGLContext.cs b/Source/OpenTK/Platform/Windows/WinGLContext.cs index 837c3e7..af55d3e 100644 --- a/Source/OpenTK/Platform/Windows/WinGLContext.cs +++ b/Source/OpenTK/Platform/Windows/WinGLContext.cs @@ -31,6 +31,7 @@ namespace OpenTK.Platform.Windows IntPtr device_context; bool vsync_supported; + bool vsync_tear_supported; readonly WinGraphicsMode ModeSelector; @@ -325,7 +326,13 @@ namespace OpenTK.Platform.Windows lock (LoadLock) { if (vsync_supported) + { + if (value < 0 && !vsync_tear_supported) + { + value = 1; + } Wgl.Ext.SwapInterval(value); + } } } } @@ -339,8 +346,11 @@ namespace OpenTK.Platform.Windows lock (LoadLock) { Wgl.LoadAll(); - vsync_supported = Wgl.Arb.SupportsExtension(this, "WGL_EXT_swap_control") && + vsync_supported = + Wgl.SupportsExtension(DeviceContext, "WGL_EXT_swap_control") && Wgl.Load("wglGetSwapIntervalEXT") && Wgl.Load("wglSwapIntervalEXT"); + vsync_tear_supported = + Wgl.SupportsExtension(DeviceContext, "WGL_EXT_swap_tear"); } base.LoadAll(); -- 2.7.4