diff options
author | Brian Paul <[email protected]> | 2015-03-13 11:43:44 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2015-03-18 09:01:50 -0600 |
commit | 4bdbb588a9d385509f9168e38bfdb76952ba469c (patch) | |
tree | 15bedfe72eeb0c233fd236ee3de6c88f5f7fa73c /src/mesa/main/context.c | |
parent | 201e36e77d6ca616f75f14d5f1c31f0062ae4366 (diff) |
mesa: reimplement dispatch table no-op function handling
Use the new _glapi_new_nop_table() and _glapi_set_nop_handler() to
improve how we handle calling no-op GL functions.
If there's a current context for the calling thread, generate a
GL_INVALID_OPERATION error. This will happen if the app calls an
unimplemented extension function or it calls an illegal function
between glBegin/glEnd.
If there's no current context, print an error to stdout if it's a debug
build.
The dispatch_sanity.cpp file has some previous checks removed since
the _mesa_generic_nop() function no longer exists.
This fixes the piglit gl-1.0-dlist-begin-end and gl-1.0-beginend-coverage
tests on Windows.
Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/mesa/main/context.c')
-rw-r--r-- | src/mesa/main/context.c | 66 |
1 files changed, 35 insertions, 31 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 22c2341d64f..e7d1f4d352a 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -882,18 +882,35 @@ update_default_objects(struct gl_context *ctx) /** - * This is the default function we plug into all dispatch table slots - * This helps prevents a segfault when someone calls a GL function without - * first checking if the extension's supported. + * This function is called by the glapi no-op functions. For each OpenGL + * function/entrypoint there's a simple no-op function. These "no-op" + * functions call this function. + * + * If there's a current OpenGL context for the calling thread, we record a + * GL_INVALID_OPERATION error. This can happen either because the app's + * calling an unsupported extension function, or calling an illegal function + * (such as glClear between glBegin/glEnd). + * + * If there's no current OpenGL context for the calling thread, we can + * print a message to stderr. + * + * \param name the name of the OpenGL function, without the "gl" prefix */ -int -_mesa_generic_nop(void) +static void +nop_handler(const char *name) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, - "unsupported function called " - "(unsupported extension or deprecated function?)"); - return 0; + if (ctx) { + _mesa_error(ctx, GL_INVALID_OPERATION, "gl%s(invalid call)", name); + } +#if defined(DEBUG) + else if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) { + fprintf(stderr, + "GL User Error: gl%s called without a rendering context\n", + name); + fflush(stderr); + } +#endif } @@ -909,13 +926,10 @@ nop_glFlush(void) #endif -extern void (*__glapi_noop_table[])(void); - - /** - * Allocate and initialize a new dispatch table. All the dispatch - * function pointers will point at the _mesa_generic_nop() function - * which raises GL_INVALID_OPERATION. + * Allocate and initialize a new dispatch table. The table will be + * populated with pointers to "no-op" functions. In turn, the no-op + * functions will call nop_handler() above. */ struct _glapi_table * _mesa_alloc_dispatch_table(void) @@ -926,23 +940,10 @@ _mesa_alloc_dispatch_table(void) * DRI drivers. */ GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT); - struct _glapi_table *table; - - table = malloc(numEntries * sizeof(_glapi_proc)); - if (table) { - _glapi_proc *entry = (_glapi_proc *) table; - GLint i; - for (i = 0; i < numEntries; i++) { -#if defined(_WIN32) - /* FIXME: This will not generate an error, but at least it won't - * corrupt the stack like _mesa_generic_nop does. */ - entry[i] = __glapi_noop_table[i]; -#else - entry[i] = (_glapi_proc) _mesa_generic_nop; -#endif - } + struct _glapi_table *table = _glapi_new_nop_table(numEntries); #if defined(_WIN32) + if (table) { /* This is a special case for Windows in the event that * wglGetProcAddress is called between glBegin/End(). * @@ -960,8 +961,11 @@ _mesa_alloc_dispatch_table(void) * assertion passes and the test continues. */ SET_Flush(table, nop_glFlush); -#endif } +#endif + + _glapi_set_nop_handler(nop_handler); + return table; } |