[PATCH 2/2] opengl32: Fix extension checks on OpenGL core profile contexts. (v3)
Matteo Bruni
mbruni at codeweavers.com
Fri Jan 16 12:38:55 CST 2015
v2: Also filter the extensions reported by glGetStringi() and the GL
functions depending on the disabled extensions.
v3: Adapt to the removal of the separate enum in the previous patch.
---
dlls/opengl32/make_opengl | 1 +
dlls/opengl32/opengl_norm.c | 9 --
dlls/opengl32/wgl.c | 246 +++++++++++++++++++++++++++++++++++++-------
3 files changed, 208 insertions(+), 48 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl
index 9ca5ebd..82c9919 100755
--- a/dlls/opengl32/make_opengl
+++ b/dlls/opengl32/make_opengl
@@ -237,6 +237,7 @@ sub GenerateThunk($$$$)
return "" if $name eq "glDebugEntry";
return "" if $name eq "glGetString";
+ return "" if $name eq "glGetIntegerv";
return "" if $func_ref->[2] && $func_ref->[2]->[0] =~ /WGL_/;
# If for opengl_norm.c, generate a nice heading otherwise Patrik won't be happy :-)
diff --git a/dlls/opengl32/opengl_norm.c b/dlls/opengl32/opengl_norm.c
index 52fb00b..34a4892 100644
--- a/dlls/opengl32/opengl_norm.c
+++ b/dlls/opengl32/opengl_norm.c
@@ -948,15 +948,6 @@ void WINAPI glGetFloatv( GLenum pname, GLfloat* data ) {
}
/***********************************************************************
- * glGetIntegerv (OPENGL32.@)
- */
-void WINAPI glGetIntegerv( GLenum pname, GLint* data ) {
- const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
- TRACE("(%d, %p)\n", pname, data );
- funcs->gl.p_glGetIntegerv( pname, data );
-}
-
-/***********************************************************************
* glGetLightfv (OPENGL32.@)
*/
void WINAPI glGetLightfv( GLenum light, GLenum pname, GLfloat* params ) {
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index 32d241c..1b4c968 100644
--- a/dlls/opengl32/wgl.c
+++ b/dlls/opengl32/wgl.c
@@ -59,11 +59,12 @@ enum wgl_handle_type
struct opengl_context
{
- DWORD tid; /* thread that the context is current in */
- HDC draw_dc; /* current drawing DC */
- HDC read_dc; /* current reading DC */
- GLubyte *extensions; /* extension string */
- struct wgl_context *drv_ctx; /* driver context */
+ DWORD tid; /* thread that the context is current in */
+ HDC draw_dc; /* current drawing DC */
+ HDC read_dc; /* current reading DC */
+ GLubyte *extensions; /* extension string */
+ GLuint *disabled_exts; /* indices of disabled extensions */
+ struct wgl_context *drv_ctx; /* driver context */
};
struct wgl_handle
@@ -162,6 +163,12 @@ static void free_handle_ptr( struct wgl_handle *ptr )
LeaveCriticalSection( &wgl_section );
}
+static inline enum wgl_handle_type get_current_context_type(void)
+{
+ if (!NtCurrentTeb()->glCurrentRC) return HANDLE_CONTEXT;
+ return (LOWORD(NtCurrentTeb()->glCurrentRC) & HANDLE_TYPE_MASK) >> 12;
+}
+
/***********************************************************************
* wglCopyContext (OPENGL32.@)
*/
@@ -199,6 +206,7 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc)
}
if (hglrc == NtCurrentTeb()->glCurrentRC) wglMakeCurrent( 0, 0 );
ptr->funcs->wgl.p_wglDeleteContext( ptr->u.context->drv_ctx );
+ HeapFree( GetProcessHeap(), 0, ptr->u.context->disabled_exts );
HeapFree( GetProcessHeap(), 0, ptr->u.context->extensions );
HeapFree( GetProcessHeap(), 0, ptr->u.context );
free_handle_ptr( ptr );
@@ -681,9 +689,82 @@ int WINAPI wglGetLayerPaletteEntries(HDC hdc,
return 0;
}
+static BOOL filter_extensions(const char *extensions, GLubyte **exts_list, GLuint **disabled_exts);
+
+void WINAPI glGetIntegerv(GLenum pname, GLint *data)
+{
+ const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
+
+ TRACE("(%d, %p)\n", pname, data);
+ if (pname == GL_NUM_EXTENSIONS)
+ {
+ struct wgl_handle *ptr = get_current_context_ptr();
+ if (ptr->u.context->disabled_exts ||
+ filter_extensions(NULL, NULL, &ptr->u.context->disabled_exts))
+ {
+ unsigned int disabled_count = 0;
+ GLuint *disabled_exts = ptr->u.context->disabled_exts;
+ GLint count;
+
+ funcs->gl.p_glGetIntegerv(pname, &count);
+ while (*(disabled_exts++) != ~0u)
+ disabled_count++;
+ *data = count - disabled_count;
+ return;
+ }
+ }
+ return funcs->gl.p_glGetIntegerv(pname, data);
+}
+
+static const GLubyte * WINAPI glGetStringi(GLenum name, GLuint index)
+{
+ const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
+
+ TRACE("(%d, %d)\n", name, index);
+ 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;
+ }
+
+ if (name == GL_EXTENSIONS)
+ {
+ struct wgl_handle *ptr = get_current_context_ptr();
+ if (ptr->u.context->disabled_exts ||
+ filter_extensions(NULL, NULL, &ptr->u.context->disabled_exts))
+ {
+ unsigned int disabled_count = 0;
+ GLuint *disabled_exts = ptr->u.context->disabled_exts;
+
+ while (index + disabled_count >= *(disabled_exts++))
+ disabled_count++;
+ return funcs->ext.p_glGetStringi(name, index + disabled_count);
+ }
+ }
+ return funcs->ext.p_glGetStringi(name, index);
+}
+
/* check if the extension is present in the list */
-static BOOL has_extension( const char *list, const char *ext, size_t len )
+static BOOL has_extension(const char *list, const char *ext, size_t len)
{
+ if (!list)
+ {
+ const char *gl_ext;
+ unsigned int i;
+ GLint extensions_count;
+
+ glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count);
+ for (i = 0; i < extensions_count; ++i)
+ {
+ gl_ext = (const char *)glGetStringi(GL_EXTENSIONS, i);
+ if (!strcmp(gl_ext, ext))
+ return TRUE;
+ }
+ return FALSE;
+ }
+
while (list)
{
while (*list == ' ') list++;
@@ -701,15 +782,21 @@ static int compar(const void *elt_a, const void *elt_b) {
/* Check if a GL extension is supported */
static BOOL is_extension_supported(const char* extension)
{
+ enum wgl_handle_type type = get_current_context_type();
const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
- const char *gl_ext_string = (const char*)glGetString(GL_EXTENSIONS);
+ const char *gl_ext_string = NULL;
size_t len;
TRACE("Checking for extension '%s'\n", extension);
- if(!gl_ext_string) {
- ERR("No OpenGL extensions found, check if your OpenGL setup is correct!\n");
- return FALSE;
+ if (type == HANDLE_CONTEXT)
+ {
+ gl_ext_string = (const char*)glGetString(GL_EXTENSIONS);
+ if (!gl_ext_string)
+ {
+ ERR("No OpenGL extensions found, check if your OpenGL setup is correct!\n");
+ return FALSE;
+ }
}
/* We use the GetProcAddress function from the display driver to retrieve function pointers
@@ -798,6 +885,11 @@ PROC WINAPI wglGetProcAddress( LPCSTR name )
*func_ptr = driver_func;
}
+ if (!strcmp(name, "glGetIntegerv"))
+ return (void *)glGetIntegerv;
+ else if (!strcmp(name, "glGetStringi"))
+ return (void *)glGetStringi;
+
TRACE("returning %s -> %p\n", name, ext_ret->func);
return ext_ret->func;
}
@@ -1657,17 +1749,106 @@ GLint WINAPI glDebugEntry( GLint unknown1, GLint unknown2 )
return 0;
}
+static GLubyte *filter_extensions_list(const char *extensions, const char *disabled)
+{
+ char *p, *str = NULL;
+ const char *end;
+
+ p = str = HeapAlloc(GetProcessHeap(), 0, strlen(extensions) + 2);
+ if (!str)
+ return NULL;
+ 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;
+ const char *ext, *end, *gl_ext;
+ GLuint *disabled_exts = NULL, *new_disabled_exts;
+ unsigned int i = 0, j, disabled_size;
+ GLint extensions_count;
+
+ 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_size = 2;
+ disabled_exts = HeapAlloc(GetProcessHeap(), 0, disabled_size * sizeof(*disabled_exts));
+ if (!disabled_exts)
+ return disabled_exts;
+ for (j = 0; j < extensions_count; ++j)
+ {
+ gl_ext = (const char *)funcs->ext.p_glGetStringi(GL_EXTENSIONS, j);
+ ext = disabled;
+ for (;;)
+ {
+ while (*ext == ' ')
+ ext++;
+ if (!*ext)
+ break;
+ if (!(end = strchr(ext, ' ')))
+ end = ext + strlen(ext);
+
+ if (!strncmp(gl_ext, ext, end - ext) && !gl_ext[end - ext])
+ {
+ TRACE("-- %s (disabled by config)\n", gl_ext);
+ if (i + 1 == disabled_size)
+ {
+ disabled_size *= 2;
+ new_disabled_exts = HeapReAlloc(GetProcessHeap(), 0, disabled_exts, disabled_size * sizeof(*disabled_exts));
+ if (!new_disabled_exts)
+ {
+ disabled_exts[i] = ~0u;
+ return disabled_exts;
+ }
+ disabled_exts = new_disabled_exts;
+ }
+ disabled_exts[i++] = j;
+ break;
+ }
+ ext = end;
+ }
+ }
+ disabled_exts[i] = ~0u;
+ return disabled_exts;
+}
+
/* build the extension string by filtering out the disabled extensions */
-static GLubyte *filter_extensions( const char *extensions )
+static BOOL filter_extensions(const char *extensions, GLubyte **exts_list, GLuint **disabled_exts)
{
static const char *disabled;
- char *p, *str;
- const char *end;
+ char *str = NULL;
TRACE( "GL_EXTENSIONS:\n" );
- if (!extensions) extensions = "";
-
if (!disabled)
{
HKEY hkey;
@@ -1692,29 +1873,16 @@ static GLubyte *filter_extensions( const char *extensions )
else disabled = "";
}
- if (!disabled[0]) return NULL;
- if ((str = HeapAlloc( GetProcessHeap(), 0, strlen(extensions) + 2 )))
- {
- p = str;
- 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;
+ 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;
}
/***********************************************************************
@@ -1729,7 +1897,7 @@ const GLubyte * WINAPI glGetString( GLenum name )
{
struct wgl_handle *ptr = get_current_context_ptr();
if (ptr->u.context->extensions ||
- ((ptr->u.context->extensions = filter_extensions( (const char *)ret ))))
+ filter_extensions((const char *)ret, &ptr->u.context->extensions, &ptr->u.context->disabled_exts))
ret = ptr->u.context->extensions;
}
return ret;
--
2.0.5
More information about the wine-patches
mailing list