/*
* Mesa 3-D graphics library
- * Version: 7.8
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (C) 2010 VMware, Inc. All Rights Reserved.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
* This file defines a special dispatch table which is loaded with no-op
* functions.
*
- * When there's no current rendering context, calling a GL function like
- * glBegin() is a no-op. Apps should never normally do this. So as a
- * debugging aid, each of the no-op functions will emit a warning to
- * stderr if the MESA_DEBUG or LIBGL_DEBUG env var is set.
+ * Mesa can register a "no-op handler function" which will be called in
+ * the event that a no-op function is called.
+ *
+ * In the past, the dispatch table was loaded with pointers to a single
+ * no-op function. But that broke on Windows because the GL entrypoints
+ * use __stdcall convention. __stdcall means the callee cleans up the
+ * stack. So one no-op function can't properly clean up the stack. This
+ * would lead to crashes.
+ *
+ * Another benefit of unique no-op functions is we can accurately report
+ * the function's name in an error message.
*/
+#include <stdlib.h>
+#include <string.h>
+#include "glapi/glapi_priv.h"
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#include "glapi/mesa.h"
-#else
-#include "main/compiler.h"
-#include "main/glheader.h"
-#endif
-
-#include "glapi/glapi.h"
-
-
-/*
- * These stubs are kept so that the old DRI drivers still load.
- */
-PUBLIC void
-_glapi_noop_enable_warnings(GLboolean enable);
-
-PUBLIC void
-_glapi_set_warning_func(_glapi_proc func);
void
-_glapi_noop_enable_warnings(GLboolean enable)
+_glapi_noop_enable_warnings(unsigned char enable)
{
}
{
}
-#ifdef DEBUG
+
+/**
+ * We'll jump though this function pointer whenever a no-op function
+ * is called.
+ */
+static _glapi_nop_handler_proc nop_handler = NULL;
+
+
+/**
+ * Register the no-op handler call-back function.
+ */
+void
+_glapi_set_nop_handler(_glapi_nop_handler_proc func)
+{
+ nop_handler = func;
+}
+
/**
* Called by each of the no-op GL entrypoints.
*/
-static int
-Warn(const char *func)
+static void
+nop(const char *func)
{
-#if !defined(_WIN32_WCE)
- if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) {
- fprintf(stderr, "GL User Error: gl%s called without a rendering context\n",
- func);
- }
-#endif
- return 0;
+ if (nop_handler)
+ nop_handler(func);
}
static GLint
NoOpUnused(void)
{
- return Warn(" function");
+ nop("unused GL entry point");
+ return 0;
}
/*
#define KEYWORD1_ALT static
#define KEYWORD2 GLAPIENTRY
#define NAME(func) NoOp##func
-#define DISPATCH(func, args, msg) Warn(#func);
-#define RETURN_DISPATCH(func, args, msg) Warn(#func); return 0
+#define DISPATCH(func, args, msg) nop(#func);
+#define RETURN_DISPATCH(func, args, msg) nop(#func); return 0
/*
* Defines for the table of no-op entry points.
*/
#define TABLE_ENTRY(name) (_glapi_proc) NoOp##name
+#define DISPATCH_TABLE_NAME __glapi_noop_table
+#define UNUSED_TABLE_NAME __unused_noop_functions
-#else
+#include "glapitemp.h"
-static int
-NoOpGeneric(void)
+
+/** Return pointer to new dispatch table filled with no-op functions */
+struct _glapi_table *
+_glapi_new_nop_table(unsigned num_entries)
{
-#if !defined(_WIN32_WCE)
- if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) {
- fprintf(stderr, "GL User Error: calling GL function without a rendering context\n");
+ struct _glapi_table *table = malloc(num_entries * sizeof(_glapi_proc));
+ if (table) {
+ memcpy(table, __glapi_noop_table,
+ num_entries * sizeof(_glapi_proc));
}
-#endif
- return 0;
+ return table;
}
-
-#define TABLE_ENTRY(name) (_glapi_proc) NoOpGeneric
-
-#endif
-
-#define DISPATCH_TABLE_NAME __glapi_noop_table
-#define UNUSED_TABLE_NAME __unused_noop_functions
-
-#include "glapi/glapitemp.h"