From: Jacek Caban jacek@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 188 +++++++++++++++++++++------------------ 1 file changed, 100 insertions(+), 88 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 35600e79e02..9081c9ff615 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -26,6 +26,7 @@
#include <stdarg.h> #include <stdlib.h> +#include <assert.h>
#include <pthread.h>
@@ -138,10 +139,11 @@ struct context UINT64 debug_callback; /* client pointer */ UINT64 debug_user; /* client pointer */ GLubyte *extensions; /* extension string */ - GLuint *disabled_exts; /* indices of disabled extensions */ char *wow64_version; /* wow64 GL version override */ struct buffers *buffers; /* wow64 buffers map */ GLenum gl_error; /* wrapped GL error */ + const char **exts; /* array of supported extensions */ + size_t exts_count; /* size of supported extensions */
/* semi-stub state tracker for wglCopyContext */ GLbitfield used; /* context state used bits */ @@ -555,60 +557,6 @@ static const char *parse_gl_version( const char *gl_version, int *major, int *mi return ptr; }
-static GLuint *filter_extensions_index( TEB *teb, const char *disabled, const char *enabled ) -{ - const struct opengl_funcs *funcs = teb->glTable; - const char *ext, *version; - GLuint *disabled_index; - GLint extensions_count; - unsigned int i = 0, j, len; - int major, minor; - - if (!funcs->p_glGetStringi) - { - void **func_ptr = (void **)&funcs->p_glGetStringi; - *func_ptr = funcs->p_wglGetProcAddress( "glGetStringi" ); - if (!funcs->p_glGetStringi) return NULL; - } - - version = (const char *)funcs->p_glGetString( GL_VERSION ); - parse_gl_version( version, &major, &minor ); - if (major < 3) - return NULL; - - funcs->p_glGetIntegerv( GL_NUM_EXTENSIONS, &extensions_count ); - disabled_index = malloc( 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->p_glGetStringi( GL_EXTENSIONS, j ); - len = strlen( ext ); - - /* We do not support GL_MAP_PERSISTENT_BIT, and hence - * ARB_buffer_storage, on wow64. */ - if (is_win64 && is_wow64() && (!strcmp( ext, "GL_ARB_buffer_storage" ) || !strcmp( ext, "GL_EXT_buffer_storage" ))) - { - TRACE( "-- %s (disabled due to wow64)\n", ext ); - disabled_index[i++] = j; - } - else if (!has_extension( disabled, ext, len ) && (!*enabled || has_extension( enabled, ext, len ))) - { - TRACE( "++ %s\n", ext ); - } - else - { - TRACE( "-- %s (disabled by config)\n", ext ); - disabled_index[i++] = j; - } - } - - disabled_index[i] = ~0u; - return disabled_index; -} - static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len ) { while (len--) *dst++ = (unsigned char)*src++; @@ -762,7 +710,7 @@ static char *query_opengl_option( const char *name ) }
/* build the extension string by filtering out the disabled extensions */ -static BOOL filter_extensions( TEB * teb, const char *extensions, GLubyte **exts_list, GLuint **disabled_exts ) +static BOOL filter_extensions( TEB * teb, const char *extensions, GLubyte **exts_list ) { static const char *disabled, *enabled; char *str; @@ -779,16 +727,20 @@ static BOOL filter_extensions( TEB * teb, const char *extensions, GLubyte **exts }
if (extensions && !*exts_list) *exts_list = filter_extensions_list( extensions, disabled, enabled ); - if (!*disabled_exts) *disabled_exts = filter_extensions_index( teb, disabled, enabled ); - return (exts_list && *exts_list) || *disabled_exts; + return exts_list && *exts_list; }
-static const GLuint *disabled_extensions_index( TEB *teb ) +static int extensions_entry_cmp( const void *p1, const void *p2 ) { - struct context *ctx = get_current_context( teb, NULL, NULL ); - GLuint **disabled = &ctx->disabled_exts; - if (*disabled || filter_extensions( teb, NULL, NULL, disabled )) return *disabled; - return NULL; + const char *s1 = *(const char **)p1; + const char *s2 = *(const char **)p2; + while (*s1 && *s1 != ' ') + { + if (*s1 != *s2) return (int)*s1 - (int)*s2; + s1++; + s2++; + } + return (!*s2 || *s2 == ' ') ? 0 : -1; }
/* Check if a GL extension is supported */ @@ -869,20 +821,9 @@ static BOOL get_default_fbo_integer( struct context *ctx, struct opengl_drawable
static BOOL get_integer( TEB *teb, GLenum pname, GLint *data ) { - const struct opengl_funcs *funcs = teb->glTable; struct opengl_drawable *draw, *read; - const GLuint *disabled; struct context *ctx;
- if (pname == GL_NUM_EXTENSIONS) - { - funcs->p_glGetIntegerv( pname, data ); - if ((disabled = disabled_extensions_index( teb ))) - while (*disabled++ != ~0u) (*data)--; - *data += ARRAY_SIZE(legacy_extensions) - 1; - return TRUE; - } - if (!(ctx = get_current_context( teb, &draw, &read ))) return FALSE;
switch (pname) @@ -893,6 +834,9 @@ static BOOL get_integer( TEB *teb, GLenum pname, GLint *data ) case GL_MINOR_VERSION: *data = ctx->minor_version; return TRUE; + case GL_NUM_EXTENSIONS: + *data = ctx->exts_count; + return TRUE; case GL_DRAW_FRAMEBUFFER_BINDING: if (!draw->draw_fbo) break; *data = ctx->draw_fbo; @@ -917,8 +861,7 @@ const GLubyte *wrap_glGetString( TEB *teb, GLenum name ) { struct context *ctx = get_current_context( teb, NULL, NULL ); GLubyte **extensions = &ctx->extensions; - GLuint **disabled = &ctx->disabled_exts; - if (*extensions || filter_extensions( teb, (const char *)ret, extensions, disabled )) return *extensions; + if (*extensions || filter_extensions( teb, (const char *)ret, extensions )) return *extensions; } else if (name == GL_VERSION) { @@ -933,8 +876,6 @@ const GLubyte *wrap_glGetString( TEB *teb, GLenum name ) const GLubyte *wrap_glGetStringi( TEB *teb, GLenum name, GLuint index ) { const struct opengl_funcs *funcs = teb->glTable; - const GLuint *disabled; - GLint count;
if (!funcs->p_glGetStringi) { @@ -944,13 +885,9 @@ const GLubyte *wrap_glGetStringi( TEB *teb, GLenum name, GLuint index )
if (name == GL_EXTENSIONS) { - funcs->p_glGetIntegerv( GL_NUM_EXTENSIONS, &count ); - - if ((disabled = disabled_extensions_index( teb ))) - while (index >= *disabled++) index++; - - if (index >= count && index - count < ARRAY_SIZE(legacy_extensions)) - return (const GLubyte *)legacy_extensions[index - count]; + struct context *ctx = get_current_context( teb, NULL, NULL ); + if (index < ctx->exts_count) return (const GLubyte *)ctx->exts[index]; + index = -1; }
return funcs->p_glGetStringi( name, index ); @@ -958,7 +895,7 @@ const GLubyte *wrap_glGetStringi( TEB *teb, GLenum name, GLuint index )
static char *build_extension_list( TEB *teb ) { - GLint len = 0, capacity, i, extensions_count; + GLint len = 0, capacity, i, extensions_count = 0; char *extension, *tmp, *available_extensions;
get_integer( teb, GL_NUM_EXTENSIONS, &extensions_count ); @@ -1081,7 +1018,12 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD HGLRC hglrc, struct context *ctx ) { DWORD tid = HandleToULong(teb->ClientId.UniqueThread); + size_t size = ARRAYSIZE(legacy_extensions) - 1, count = 0; const char *version, *rest = ""; + const char **extensions; + int i, j; + + static const char *disabled, *enabled;
ctx->tid = tid; teb->glReserved1[0] = draw_hdc; @@ -1093,10 +1035,70 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD if (ctx->major_version) return; /* already synced */
version = (const char *)funcs->p_glGetString( GL_VERSION ); - if (version) parse_gl_version( version, &ctx->major_version, &ctx->minor_version ); + if (version) rest = parse_gl_version( version, &ctx->major_version, &ctx->minor_version ); if (!ctx->major_version) ctx->major_version = 1; TRACE( "context %p version %d.%d\n", ctx, ctx->major_version, ctx->minor_version );
+ if (ctx->major_version >= 3) + { + GLint extensions_count; + + if (!funcs->p_glGetStringi) + { + void **func_ptr = (void **)&funcs->p_glGetStringi; + *func_ptr = funcs->p_wglGetProcAddress( "glGetStringi" ); + } + + funcs->p_glGetIntegerv( GL_NUM_EXTENSIONS, &extensions_count ); + size += extensions_count; + if (!(extensions = malloc( size * sizeof(*extensions) ))) return; + for (i = 0; i < extensions_count; i++) extensions[count++] = (const char *)funcs->p_glGetStringi( GL_EXTENSIONS, i ); + } + else + { + const char *str = (const char *)funcs->p_glGetString( GL_EXTENSIONS ); + size_t len = strlen( str ); + const char *p; + char *out; + if (!str) str = ""; + if ((len = strlen( str )) && str[len - 1] == ' ') len--; + if (*str) size++; + for (p = str; p < str + len; p++) if (*p == ' ') size++; + if (!(extensions = malloc( size * sizeof(*extensions) + len + 1 ))) return; + out = (char *)&extensions[size]; + memcpy( out, str, len ); + out[len] = 0; + if (*out) extensions[count++] = out; + while (*out) + { + if (*out == ' ') + { + *out = 0; + extensions[count++] = out + 1; + } + out++; + } + assert( count + ARRAYSIZE(legacy_extensions) - 1 == size ); + } + + if (!disabled && !(disabled = query_opengl_option( "DisabledExtensions" ))) disabled = ""; + if (!enabled && !(enabled = query_opengl_option( "EnabledExtensions" ))) enabled = ""; + if (*enabled || *disabled) + { + for (i = 0, j = 0; i < count; i++) + { + size_t len = strlen( extensions[i] ); + if (!has_extension( disabled, extensions[i], len ) && (!*enabled || has_extension( enabled, extensions[i], len ))) + extensions[j++] = extensions[i]; + else + TRACE( "-- %s (disabled by config)\n", extensions[i] ); + } + count = j; + } + + for (i = 0; legacy_extensions[i]; i++) extensions[count++] = legacy_extensions[i]; + qsort( extensions, count, sizeof(*extensions), extensions_entry_cmp ); + if (is_win64 && is_wow64()) { if (ctx->major_version > 4 || (ctx->major_version == 4 && ctx->minor_version > 3)) @@ -1106,7 +1108,17 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD ctx->minor_version = 3; asprintf( &ctx->wow64_version, "4.3%s", rest ); } + for (i = 0; i < count; i++) + { + if (strcmp( extensions[i], "GL_ARB_buffer_storage" ) && strcmp( extensions[i], "GL_ARB_buffer_storage" )) continue; + FIXME( "Disabling %s extension on wow64\n", extensions[i] ); + if (i != --count) memmove( &extensions[i], &extensions[i + 1], (count - i) * sizeof(extensions[0]) ); + } } + + ctx->exts = extensions; + ctx->exts_count = count; + if (TRACE_ON(opengl)) for (i = 0; i < count; i++) TRACE( "++ %s\n", extensions[i] ); }
BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) @@ -1147,7 +1159,7 @@ BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) static void free_context( struct context *ctx ) { free( ctx->wow64_version ); - free( ctx->disabled_exts ); + free( ctx->exts ); free( ctx->extensions ); free( ctx->attribs ); free( ctx );
From: Jacek Caban jacek@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 50 ++++++++-------------------------------- 1 file changed, 9 insertions(+), 41 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 9081c9ff615..1533f0b7624 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -744,7 +744,13 @@ static int extensions_entry_cmp( const void *p1, const void *p2 ) }
/* Check if a GL extension is supported */ -static BOOL check_extension_support( struct context *ctx, const char *extension, const char *available_extensions ) +static BOOL is_extension_supported( struct context *ctx, const char *extension ) +{ + return bsearch( &extension, ctx->exts, ctx->exts_count, sizeof(ctx->exts[0]), extensions_entry_cmp ) != NULL; +} + +/* Check if any GL extension from the list is supported */ +static BOOL is_any_extension_supported( struct context *ctx, const char *extension ) { size_t len;
@@ -759,7 +765,7 @@ static BOOL check_extension_support( struct context *ctx, const char *extension, 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; + if (is_extension_supported( ctx, extension )) 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 @@ -893,44 +899,6 @@ const GLubyte *wrap_glGetStringi( TEB *teb, GLenum name, GLuint index ) return funcs->p_glGetStringi( name, index ); }
-static char *build_extension_list( TEB *teb ) -{ - GLint len = 0, capacity, i, extensions_count = 0; - char *extension, *tmp, *available_extensions; - - get_integer( teb, GL_NUM_EXTENSIONS, &extensions_count ); - capacity = 128 * extensions_count; - - if (!(available_extensions = malloc( capacity ))) return NULL; - for (i = 0; i < extensions_count; ++i) - { - extension = (char *)wrap_glGetStringi( teb, GL_EXTENSIONS, i ); - capacity = max( capacity, len + strlen( extension ) + 2 ); - if (!(tmp = realloc( available_extensions, capacity ))) break; - available_extensions = tmp; - len += snprintf( available_extensions + len, capacity - len, "%s ", extension ); - } - if (len) available_extensions[len - 1] = 0; - - return available_extensions; -} - -/* Check if a GL extension is supported */ -static BOOL is_extension_supported( TEB *teb, struct context *ctx, const char *extension ) -{ - char *available_extensions = NULL; - BOOL ret = FALSE; - - if (ctx->major_version < 3) available_extensions = strdup( (const char *)wrap_glGetString( teb, GL_EXTENSIONS ) ); - if (!available_extensions) available_extensions = build_extension_list( teb ); - - if (!available_extensions) ERR( "No OpenGL extensions found, check if your OpenGL setup is correct!\n" ); - else ret = check_extension_support( ctx, extension, available_extensions ); - - free( available_extensions ); - return ret; -} - static int registry_entry_cmp( const void *a, const void *b ) { const struct registry_entry *entry_a = a, *entry_b = b; @@ -964,7 +932,7 @@ PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR name ) { void *driver_func = funcs->p_wglGetProcAddress( name );
- if (!is_extension_supported( teb, ctx, found->extension )) + if (!is_any_extension_supported( ctx, found->extension )) { unsigned int i; static const struct { const char *name, *alt; } alternatives[] =
From: Jacek Caban jacek@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 123 +++++++++++++++------------------------ 1 file changed, 47 insertions(+), 76 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 1533f0b7624..c445c4bae1d 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -485,60 +485,6 @@ static const char *legacy_extensions[] = NULL, };
-static GLubyte *filter_extensions_list( const char *extensions, const char *disabled, const char *enabled ) -{ - const char *end, **extra; - char *p, *str; - size_t size, len; - - size = strlen( extensions ) + 2; - for (extra = legacy_extensions; *extra; extra++) size += strlen( *extra ) + 1; - if (!(p = str = malloc( size ))) 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 ); - len = end - extensions; - p[len] = 0; - - /* We do not support GL_MAP_PERSISTENT_BIT, and hence - * ARB_buffer_storage, on wow64. */ - if (is_win64 && is_wow64() && (!strcmp( p, "GL_ARB_buffer_storage" ) || !strcmp( p, "GL_EXT_buffer_storage" ))) - { - TRACE( "-- %s (disabled due to wow64)\n", p ); - } - else if (!has_extension( disabled, p, len ) && (!*enabled || has_extension( enabled, p, len ))) - { - TRACE( "++ %s\n", p ); - p += end - extensions; - *p++ = ' '; - } - else - { - TRACE( "-- %s (disabled by config)\n", p ); - } - extensions = end; - } - - for (extra = legacy_extensions; *extra; extra++) - { - size = strlen( *extra ); - memcpy( p, *extra, size ); - p += size; - *p++ = ' '; - } - - if (p != str) --p; - *p = 0; - return (GLubyte *)str; -} - static const char *parse_gl_version( const char *gl_version, int *major, int *minor ) { const char *ptr = gl_version; @@ -709,27 +655,6 @@ static char *query_opengl_option( const char *name ) return str; }
-/* build the extension string by filtering out the disabled extensions */ -static BOOL filter_extensions( TEB * teb, const char *extensions, GLubyte **exts_list ) -{ - static const char *disabled, *enabled; - char *str; - - if (!disabled) - { - if (!(str = query_opengl_option( "DisabledExtensions" ))) disabled = ""; - else if (InterlockedCompareExchangePointer( (void **)&disabled, str, NULL )) free( str ); - } - if (!enabled) - { - if (!(str = query_opengl_option( "EnabledExtensions" ))) enabled = ""; - else if (InterlockedCompareExchangePointer( (void **)&enabled, str, NULL )) free( str ); - } - - if (extensions && !*exts_list) *exts_list = filter_extensions_list( extensions, disabled, enabled ); - return exts_list && *exts_list; -} - static int extensions_entry_cmp( const void *p1, const void *p2 ) { const char *s1 = *(const char **)p1; @@ -749,6 +674,52 @@ static BOOL is_extension_supported( struct context *ctx, const char *extension ) return bsearch( &extension, ctx->exts, ctx->exts_count, sizeof(ctx->exts[0]), extensions_entry_cmp ) != NULL; }
+/* build the extension string by filtering out the disabled extensions */ +static GLubyte *filter_extensions( struct context *ctx, const char *extensions ) +{ + const char *end, **extra; + size_t size, len; + char *p, *str; + + size = strlen( extensions ) + 2; + for (extra = legacy_extensions; *extra; extra++) size += strlen( *extra ) + 1; + if (!(p = str = malloc( size ))) return NULL; + + TRACE( "GL_EXTENSIONS:\n" ); + + for (;;) + { + while (*extensions == ' ') extensions++; + if (!*extensions) break; + len = (end = strchr( extensions, ' ' )) ? end - extensions : strlen( extensions ); + memcpy( p, extensions, len ); + p[len] = 0; + if (is_extension_supported( ctx, extensions )) + { + TRACE( "++ %s\n", p ); + p += len; + *p++ = ' '; + } + else + { + TRACE( "-- %s (disabled in context)\n", p ); + } + extensions = end; + } + + for (extra = legacy_extensions; *extra; extra++) + { + size = strlen( *extra ); + memcpy( p, *extra, size ); + p += size; + *p++ = ' '; + } + + if (p != str) --p; + *p = 0; + return (GLubyte *)str; +} + /* Check if any GL extension from the list is supported */ static BOOL is_any_extension_supported( struct context *ctx, const char *extension ) { @@ -867,7 +838,7 @@ const GLubyte *wrap_glGetString( TEB *teb, GLenum name ) { struct context *ctx = get_current_context( teb, NULL, NULL ); GLubyte **extensions = &ctx->extensions; - if (*extensions || filter_extensions( teb, (const char *)ret, extensions )) return *extensions; + if (*extensions || (*extensions = filter_extensions( ctx, (const char *)ret ))) return *extensions; } else if (name == GL_VERSION) {
Rémi Bernon (@rbernon) commented about dlls/opengl32/unix_wgl.c:
HGLRC hglrc, struct context *ctx ){ DWORD tid = HandleToULong(teb->ClientId.UniqueThread);
- size_t size = ARRAYSIZE(legacy_extensions) - 1, count = 0; const char *version, *rest = "";
- const char **extensions;
- int i, j;
```suggestion:-2+0 const char *version, *rest = "", **extensions; int i, j; ```
Rémi Bernon (@rbernon) commented about dlls/opengl32/unix_wgl.c:
for (p = str; p < str + len; p++) if (*p == ' ') size++;if (!(extensions = malloc( size * sizeof(*extensions) + len + 1 ))) return;out = (char *)&extensions[size];memcpy( out, str, len );out[len] = 0;if (*out) extensions[count++] = out;while (*out){if (*out == ' '){*out = 0;extensions[count++] = out + 1;}out++;}assert( count + ARRAYSIZE(legacy_extensions) - 1 == size );
Can glGetString really return NULL? What about making this more readable?
```suggestion:-22+0 const char *str, *ptr; char *out;
if (!(str = (const char *)funcs->p_glGetString( GL_EXTENSIONS ))) str = ""; for (ptr = str; *ptr; ptr++) if (ptr == str || (ptr[0] == ' ' && ptr[1])) size++; if (ptr > str && ptr[-1] == ' ') ptr--; /* strip trailing space */
if (!(extensions = malloc( size * sizeof(*extensions) + (ptr - str) ))) return; out = (char *)&extensions[size]; memcpy( out, str, ptr - str );
for (ptr = strtok( out, " " ); ptr; ptr = strtok( NULL, " " )) extensions[count++] = ptr; assert( count + ARRAY_SIZE(legacy_extensions) - 1 == size ); ```
Rémi Bernon (@rbernon) commented about dlls/opengl32/unix_wgl.c:
ctx->minor_version = 3; asprintf( &ctx->wow64_version, "4.3%s", rest ); }
for (i = 0; i < count; i++){if (strcmp( extensions[i], "GL_ARB_buffer_storage" ) && strcmp( extensions[i], "GL_ARB_buffer_storage" )) continue;FIXME( "Disabling %s extension on wow64\n", extensions[i] );if (i != --count) memmove( &extensions[i], &extensions[i + 1], (count - i) * sizeof(extensions[0]) );}
Why move this out of the loop? I think it could be kept more like it was and avoid the memmove.
Rémi Bernon (@rbernon) commented about dlls/opengl32/unix_wgl.c:
-static const GLuint *disabled_extensions_index( TEB *teb ) +static int extensions_entry_cmp( const void *p1, const void *p2 ) {
- struct context *ctx = get_current_context( teb, NULL, NULL );
- GLuint **disabled = &ctx->disabled_exts;
- if (*disabled || filter_extensions( teb, NULL, NULL, disabled )) return *disabled;
- return NULL;
- const char *s1 = *(const char **)p1;
- const char *s2 = *(const char **)p2;
- while (*s1 && *s1 != ' ')
- {
if (*s1 != *s2) return (int)*s1 - (int)*s2;s1++;s2++;- }
- return (!*s2 || *s2 == ' ') ? 0 : -1;
Is this really necessary? Extensions should be tokenized already no? What about strcmp?
Rémi Bernon (@rbernon) commented about dlls/opengl32/unix_wgl.c:
UINT64 debug_callback; /* client pointer */ UINT64 debug_user; /* client pointer */ GLubyte *extensions; /* extension string */
- GLuint *disabled_exts; /* indices of disabled extensions */ char *wow64_version; /* wow64 GL version override */ struct buffers *buffers; /* wow64 buffers map */ GLenum gl_error; /* wrapped GL error */
- const char **exts; /* array of supported extensions */
- size_t exts_count; /* size of supported extensions */
I would rather have some more explicit name, because it's getting quite confusing with `extensions`. Something like `extension_array` for instance. Or rename the other `extension_string`.
Rémi Bernon (@rbernon) commented about dlls/opengl32/unix_wgl.c:
}
/* Check if a GL extension is supported */ -static BOOL check_extension_support( struct context *ctx, const char *extension, const char *available_extensions ) +static BOOL is_extension_supported( struct context *ctx, const char *extension ) +{
- return bsearch( &extension, ctx->exts, ctx->exts_count, sizeof(ctx->exts[0]), extensions_entry_cmp ) != NULL;
What about using a local buffer so we can simply call `strcmp` in `extensions_entry_cmp`? Extension names are likely to be bounded in length.
Rémi Bernon (@rbernon) commented about dlls/opengl32/unix_wgl.c:
{ struct context *ctx = get_current_context( teb, NULL, NULL ); GLubyte **extensions = &ctx->extensions;
if (*extensions || filter_extensions( teb, (const char *)ret, extensions )) return *extensions;
if (*extensions || (*extensions = filter_extensions( ctx, (const char *)ret ))) return *extensions;
Do we really need to filter extensions there again? What about pre-computing the extension string right away from the extension array after we've initialized it?