From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/opengl_ext.h | 4 + dlls/opengl32/unix_wgl.c | 181 +++++++++++++++++++++++++++++++++++++ dlls/opengl32/wgl.c | 178 ------------------------------------ 3 files changed, 185 insertions(+), 178 deletions(-)
diff --git a/dlls/opengl32/opengl_ext.h b/dlls/opengl32/opengl_ext.h index 2a579e142b6..b2c3c681a41 100644 --- a/dlls/opengl32/opengl_ext.h +++ b/dlls/opengl32/opengl_ext.h @@ -101,4 +101,8 @@ static inline enum wgl_handle_type get_current_context_type(void)
extern int WINAPI wglDescribePixelFormat( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd );
+extern BOOL filter_extensions( const char *extensions, GLubyte **exts_list, GLuint **disabled_exts ) DECLSPEC_HIDDEN; +extern const GLuint *disabled_extensions_index(void) DECLSPEC_HIDDEN; +extern BOOL check_extension_support( const char *extension, const char *available_extensions ) DECLSPEC_HIDDEN; + #endif /* __DLLS_OPENGL32_OPENGL_EXT_H */ diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 4771205a47e..9a96f78dacb 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -27,6 +27,7 @@ #define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" +#include "winreg.h" #include "ntuser.h"
#include "opengl_ext.h" @@ -35,6 +36,8 @@
#include "wine/debug.h"
+WINE_DEFAULT_DEBUG_CHANNEL(wgl); + struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; static struct wgl_handle *next_free; static unsigned int handle_count; @@ -105,6 +108,184 @@ static void free_handle_ptr( struct wgl_handle *ptr ) LeaveCriticalSection( &wgl_section ); }
+/* check if the extension is present in the list */ +static BOOL has_extension( const char *list, const char *ext, size_t len ) +{ + while (list) + { + while (*list == ' ') list++; + if (!strncmp( list, ext, len ) && (!list[len] || list[len] == ' ')) return TRUE; + list = strchr( list, ' ' ); + } + return FALSE; +} + +static GLubyte *filter_extensions_list( const char *extensions, const char *disabled ) +{ + const char *end; + char *p, *str; + + p = str = HeapAlloc( GetProcessHeap(), 0, strlen( extensions ) + 2 ); + if (!str) return NULL; + + TRACE( "GL_EXTENSIONS:\n" ); + + for (;;) + { + while (*extensions == ' ') extensions++; + if (!*extensions) break; + + if (!(end = strchr( extensions, ' ' ))) end = extensions + strlen( extensions ); + memcpy( p, extensions, end - extensions ); + p[end - extensions] = 0; + + if (!has_extension( disabled, p, strlen( p ) )) + { + TRACE( "++ %s\n", p ); + p += end - extensions; + *p++ = ' '; + } + else + { + TRACE( "-- %s (disabled by config)\n", p ); + } + extensions = end; + } + *p = 0; + return (GLubyte *)str; +} + +static GLuint *filter_extensions_index( const char *disabled ) +{ + const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; + GLuint *disabled_index; + GLint extensions_count; + unsigned int i = 0, j; + const char *ext; + + if (!funcs->ext.p_glGetStringi) + { + void **func_ptr = (void **)&funcs->ext.p_glGetStringi; + *func_ptr = funcs->wgl.p_wglGetProcAddress( "glGetStringi" ); + if (!funcs->ext.p_glGetStringi) return NULL; + } + + funcs->gl.p_glGetIntegerv( GL_NUM_EXTENSIONS, &extensions_count ); + disabled_index = HeapAlloc( GetProcessHeap(), 0, extensions_count * sizeof(*disabled_index) ); + if (!disabled_index) return NULL; + + TRACE( "GL_EXTENSIONS:\n" ); + + for (j = 0; j < extensions_count; ++j) + { + ext = (const char *)funcs->ext.p_glGetStringi( GL_EXTENSIONS, j ); + if (!has_extension( disabled, ext, strlen( ext ) )) + { + TRACE( "++ %s\n", ext ); + } + else + { + TRACE( "-- %s (disabled by config)\n", ext ); + disabled_index[i++] = j; + } + } + + disabled_index[i] = ~0u; + return disabled_index; +} + +/* build the extension string by filtering out the disabled extensions */ +BOOL filter_extensions( const char *extensions, GLubyte **exts_list, GLuint **disabled_exts ) +{ + static const char *disabled; + + if (!disabled) + { + HKEY hkey; + DWORD size; + char *str = NULL; + + /* @@ Wine registry key: HKCU\Software\Wine\OpenGL */ + if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\Wine\OpenGL", &hkey )) + { + if (!RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, NULL, &size )) + { + str = HeapAlloc( GetProcessHeap(), 0, size ); + if (RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, (BYTE *)str, &size )) *str = 0; + } + RegCloseKey( hkey ); + } + if (str) + { + if (InterlockedCompareExchangePointer( (void **)&disabled, str, NULL )) + HeapFree( GetProcessHeap(), 0, str ); + } + else disabled = ""; + } + + if (!disabled[0]) return FALSE; + if (extensions && !*exts_list) *exts_list = filter_extensions_list( extensions, disabled ); + if (!*disabled_exts) *disabled_exts = filter_extensions_index( disabled ); + return (exts_list && *exts_list) || *disabled_exts; +} + +const GLuint *disabled_extensions_index(void) +{ + struct wgl_handle *ptr = get_current_context_ptr(); + GLuint **disabled = &ptr->u.context->disabled_exts; + if (*disabled || filter_extensions( NULL, NULL, disabled )) return *disabled; + return NULL; +} + +/* Check if a GL extension is supported */ +BOOL check_extension_support( const char *extension, const char *available_extensions ) +{ + const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; + size_t len; + + TRACE( "Checking for extension '%s'\n", extension ); + + /* We use the GetProcAddress function from the display driver to retrieve function pointers + * for OpenGL and WGL extensions. In case of winex11.drv the OpenGL extension lookup is done + * using glXGetProcAddress. This function is quite unreliable in the sense that its specs don't + * require the function to return NULL when an extension isn't found. For this reason we check + * if the OpenGL extension required for the function we are looking up is supported. */ + + while ((len = strcspn( extension, " " ))) + { + /* Check if the extension is part of the GL extension string to see if it is supported. */ + if (has_extension( available_extensions, extension, len )) return TRUE; + + /* In general an OpenGL function starts as an ARB/EXT extension and at some stage + * it becomes part of the core OpenGL library and can be reached without the ARB/EXT + * suffix as well. In the extension table, these functions contain GL_VERSION_major_minor. + * Check if we are searching for a core GL function */ + if (!strncmp( extension, "GL_VERSION_", 11 )) + { + const GLubyte *gl_version = funcs->gl.p_glGetString( GL_VERSION ); + const char *version = extension + 11; /* Move past 'GL_VERSION_' */ + + if (!gl_version) + { + ERR( "No OpenGL version found!\n" ); + return FALSE; + } + + /* Compare the major/minor version numbers of the native OpenGL library and what is required by the function. + * The gl_version string is guaranteed to have at least a major/minor and sometimes it has a release number as well. */ + if ((gl_version[0] > version[0]) || ((gl_version[0] == version[0]) && (gl_version[2] >= version[2]))) return TRUE; + + WARN( "The function requires OpenGL version '%c.%c' while your drivers only provide '%c.%c'\n", + version[0], version[2], gl_version[0], gl_version[2] ); + } + + if (extension[len] == ' ') len++; + extension += len; + } + + return FALSE; +} + static BOOL wrap_wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) { struct wgl_handle *src, *dst; diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index a9039d606c1..60ba7bf3bdf 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -334,135 +334,6 @@ int WINAPI wglGetLayerPaletteEntries(HDC hdc, return 0; }
-/* check if the extension is present in the list */ -static BOOL has_extension( const char *list, const char *ext, size_t len ) -{ - while (list) - { - while (*list == ' ') list++; - if (!strncmp( list, ext, len ) && (!list[len] || list[len] == ' ')) return TRUE; - list = strchr( list, ' ' ); - } - return FALSE; -} - -static GLubyte *filter_extensions_list( const char *extensions, const char *disabled ) -{ - const char *end; - char *p, *str; - - p = str = HeapAlloc( GetProcessHeap(), 0, strlen( extensions ) + 2 ); - if (!str) return NULL; - - TRACE( "GL_EXTENSIONS:\n" ); - - for (;;) - { - while (*extensions == ' ') extensions++; - if (!*extensions) break; - - if (!(end = strchr( extensions, ' ' ))) end = extensions + strlen( extensions ); - memcpy( p, extensions, end - extensions ); - p[end - extensions] = 0; - - if (!has_extension( disabled, p, strlen( p ) )) - { - TRACE( "++ %s\n", p ); - p += end - extensions; - *p++ = ' '; - } - else - { - TRACE( "-- %s (disabled by config)\n", p ); - } - extensions = end; - } - *p = 0; - return (GLubyte *)str; -} - -static GLuint *filter_extensions_index( const char *disabled ) -{ - const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; - GLuint *disabled_index; - GLint extensions_count; - unsigned int i = 0, j; - const char *ext; - - if (!funcs->ext.p_glGetStringi) - { - void **func_ptr = (void **)&funcs->ext.p_glGetStringi; - *func_ptr = funcs->wgl.p_wglGetProcAddress( "glGetStringi" ); - if (!funcs->ext.p_glGetStringi) return NULL; - } - - funcs->gl.p_glGetIntegerv( GL_NUM_EXTENSIONS, &extensions_count ); - disabled_index = HeapAlloc( GetProcessHeap(), 0, extensions_count * sizeof(*disabled_index) ); - if (!disabled_index) return NULL; - - TRACE( "GL_EXTENSIONS:\n" ); - - for (j = 0; j < extensions_count; ++j) - { - ext = (const char *)funcs->ext.p_glGetStringi( GL_EXTENSIONS, j ); - if (!has_extension( disabled, ext, strlen( ext ) )) - { - TRACE( "++ %s\n", ext ); - } - else - { - TRACE( "-- %s (disabled by config)\n", ext ); - disabled_index[i++] = j; - } - } - - disabled_index[i] = ~0u; - return disabled_index; -} - -/* build the extension string by filtering out the disabled extensions */ -static BOOL filter_extensions( const char *extensions, GLubyte **exts_list, GLuint **disabled_exts ) -{ - static const char *disabled; - - if (!disabled) - { - HKEY hkey; - DWORD size; - char *str = NULL; - - /* @@ Wine registry key: HKCU\Software\Wine\OpenGL */ - if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\Wine\OpenGL", &hkey )) - { - if (!RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, NULL, &size )) - { - str = HeapAlloc( GetProcessHeap(), 0, size ); - if (RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, (BYTE *)str, &size )) *str = 0; - } - RegCloseKey( hkey ); - } - if (str) - { - if (InterlockedCompareExchangePointer( (void **)&disabled, str, NULL )) - HeapFree( GetProcessHeap(), 0, str ); - } - else disabled = ""; - } - - if (!disabled[0]) return FALSE; - if (extensions && !*exts_list) *exts_list = filter_extensions_list( extensions, disabled ); - if (!*disabled_exts) *disabled_exts = filter_extensions_index( disabled ); - return (exts_list && *exts_list) || *disabled_exts; -} - -static const GLuint *disabled_extensions_index(void) -{ - struct wgl_handle *ptr = get_current_context_ptr(); - GLuint **disabled = &ptr->u.context->disabled_exts; - if (*disabled || filter_extensions( NULL, NULL, disabled )) return *disabled; - return NULL; -} - void WINAPI glGetIntegerv(GLenum pname, GLint *data) { struct glGetIntegerv_params args = { .pname = pname, .data = data, }; @@ -501,55 +372,6 @@ static int compar(const void *elt_a, const void *elt_b) { ((const OpenGL_extension *) elt_b)->name); }
-/* Check if a GL extension is supported */ -static BOOL check_extension_support( const char *extension, const char *available_extensions ) -{ - const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; - size_t len; - - TRACE("Checking for extension '%s'\n", extension); - - /* We use the GetProcAddress function from the display driver to retrieve function pointers - * for OpenGL and WGL extensions. In case of winex11.drv the OpenGL extension lookup is done - * using glXGetProcAddress. This function is quite unreliable in the sense that its specs don't - * require the function to return NULL when an extension isn't found. For this reason we check - * if the OpenGL extension required for the function we are looking up is supported. */ - - while ((len = strcspn( extension, " " ))) - { - /* Check if the extension is part of the GL extension string to see if it is supported. */ - if (has_extension( available_extensions, extension, len )) return TRUE; - - /* In general an OpenGL function starts as an ARB/EXT extension and at some stage - * it becomes part of the core OpenGL library and can be reached without the ARB/EXT - * suffix as well. In the extension table, these functions contain GL_VERSION_major_minor. - * Check if we are searching for a core GL function */ - if (!strncmp( extension, "GL_VERSION_", 11 )) - { - const GLubyte *gl_version = funcs->gl.p_glGetString(GL_VERSION); - const char *version = extension + 11; /* Move past 'GL_VERSION_' */ - - if (!gl_version) - { - ERR( "No OpenGL version found!\n" ); - return FALSE; - } - - /* Compare the major/minor version numbers of the native OpenGL library and what is required by the function. - * The gl_version string is guaranteed to have at least a major/minor and sometimes it has a release number as well. */ - if ((gl_version[0] > version[0]) || ((gl_version[0] == version[0]) && (gl_version[2] >= version[2]))) return TRUE; - - WARN( "The function requires OpenGL version '%c.%c' while your drivers only provide '%c.%c'\n", - version[0], version[2], gl_version[0], gl_version[2] ); - } - - if (extension[len] == ' ') len++; - extension += len; - } - - return FALSE; -} - static char *build_extension_list(void) { GLint len = 0, capacity, i, extensions_count;