glapi: Implement optional dispatch logging
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 9 Sep 2010 16:59:14 +0000 (12:59 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 9 Sep 2010 17:21:15 +0000 (13:21 -0400)
There's a useful feature buried in glapi to log all API calls to stderr.
Unfortunately it requires editing the code and then it's enabled
unconditionally for that build.  This patch builds in API logging for
debug builds and makes it run-time switchable by setting MESA_DEBUG=dispatch.

src/mapi/glapi/glapi.h
src/mapi/glapi/glapi_dispatch.c
src/mesa/drivers/dri/common/dri_test.c
src/mesa/main/context.c
src/mesa/main/context.h
src/mesa/main/debug.c
src/mesa/main/dlist.c
src/mesa/main/mtypes.h

index a0bb0781063bc7ac02756ac7a5640169091e44c8..2fa580283e82af8bf85e439af232cc560690ef09 100644 (file)
@@ -94,7 +94,7 @@ _GLAPI_EXPORT extern __thread void * _glapi_tls_Context
 _GLAPI_EXPORT extern const struct _glapi_table *_glapi_Dispatch;
 _GLAPI_EXPORT extern const void *_glapi_Context;
 
-# define GET_DISPATCH() _glapi_tls_Dispatch
+# define GET_DISPATCH(t) _glapi_tls_Dispatch
 # define GET_CURRENT_CONTEXT(C)  GLcontext *C = (GLcontext *) _glapi_tls_Context
 
 #else
@@ -167,6 +167,12 @@ _glapi_get_proc_name(unsigned int offset);
 _GLAPI_EXPORT unsigned long
 _glthread_GetID(void);
 
+_GLAPI_EXPORT int
+_glapi_logging_available(void);
+
+_GLAPI_EXPORT void
+_glapi_enable_logging(void (*func)(void *data, const char *fmt, ...),
+                     void *data);
 
 /*
  * These stubs are kept so that the old DRI drivers still load.
index 7421a36d35a560c4b672f87b2af9536ffee31104..0d41c9499b5e059024570c0026325b3ff10afa66 100644 (file)
@@ -41,7 +41,6 @@
 #include "glapi/glapitable.h"
 #include "glapi/glapidispatch.h"
 
-
 #if !(defined(USE_X86_ASM) || defined(USE_X86_64_ASM) || defined(USE_SPARC_ASM))
 
 #if defined(WIN32)
 #define NAME(func)  gl##func
 #endif
 
-#if 0  /* Use this to log GL calls to stdout (for DEBUG only!) */
-
-#define F stdout
-#define DISPATCH(FUNC, ARGS, MESSAGE)          \
-   fprintf MESSAGE;                            \
-   CALL_ ## FUNC(GET_DISPATCH(), ARGS);
-
-#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE)   \
-   fprintf MESSAGE;                            \
-   return CALL_ ## FUNC(GET_DISPATCH(), ARGS);
-
-#else
-
 #define DISPATCH(FUNC, ARGS, MESSAGE)          \
    CALL_ ## FUNC(GET_DISPATCH(), ARGS);
 
 #define RETURN_DISPATCH(FUNC, ARGS, MESSAGE)   \
    return CALL_ ## FUNC(GET_DISPATCH(), ARGS);
 
-#endif /* logging */
-
 
 #ifndef GLAPIENTRY
 #define GLAPIENTRY
 #include "glapi/glapitemp.h"
 
 #endif /* USE_X86_ASM */
+
+
+#ifdef DEBUG
+
+static void *logger_data;
+static void (*logger_func)(void *data, const char *fmt, ...);
+static struct _glapi_table *real_dispatch; /* FIXME: This need to be TLS etc */
+
+#define KEYWORD1 static
+#define KEYWORD1_ALT static
+#define KEYWORD2
+#define NAME(func)  log_##func
+#define F logger_data
+
+static void
+log_Unused(void)
+{
+}
+
+#define DISPATCH(FUNC, ARGS, MESSAGE)          \
+   logger_func MESSAGE;                                \
+   CALL_ ## FUNC(real_dispatch, ARGS);
+
+#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE)   \
+   logger_func MESSAGE;                        \
+   return CALL_ ## FUNC(real_dispatch, ARGS);
+
+#define DISPATCH_TABLE_NAME __glapi_logging_table
+
+#define TABLE_ENTRY(func) (_glapi_proc) log_##func
+
+#include "glapi/glapitemp.h"
+
+int
+_glapi_logging_available(void)
+{
+   return 1;
+}
+
+void
+_glapi_enable_logging(void (*func)(void *data, const char *fmt, ...),
+                     void *data)
+{
+   real_dispatch = GET_DISPATCH();
+   logger_func = func;
+   logger_data = data;
+   _glapi_set_dispatch(&__glapi_logging_table);
+}
+
+#else
+
+int
+_glapi_logging_available(void)
+{
+   return 0
+}
+
+void
+_glapi_enable_logging(void (*func)(void *data, const char *fmt, ...),
+                     void *data)
+{
+}
+
+#endif
index 793f0c37d79247f5df664f10f298694ba4981b42..8a47316bea6f04c052aa16a052fcd5cdc6bf7c96 100644 (file)
@@ -82,6 +82,18 @@ _glthread_GetID(void)
    return 0;
 }
 
+PUBLIC int
+_glapi_logging_available(void)
+{
+   return 0;
+}
+
+PUBLIC void
+_glapi_enable_logging(void (*func)(void *data, const char *fmt, ...),
+                     void *data)
+{
+}
+
 int main(int argc, char** argv)
 {
    void* p = __driDriverExtensions;
index 8e34ec4124f9bb4f8363286a715f51aa01ba6fb0..73d96e8d2127b265c65e8d7bb1370af0e5950f0d 100644 (file)
@@ -1367,6 +1367,26 @@ _mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height)
    }
 }
 
+static void
+dispatch_logger(void *data, const char *fmt, ...)
+{
+   va_list ap;
+
+   va_start(ap, fmt);
+   vfprintf(stderr, fmt, ap);
+   va_end(ap);
+}
+
+void
+_mesa_set_dispatch(void *table)
+{
+   if (table && (MESA_VERBOSE & VERBOSE_DISPATCH)) {
+      _glapi_set_dispatch(table);
+      _glapi_enable_logging(dispatch_logger, stderr);
+   } else {
+      _glapi_set_dispatch(table);
+   }
+}
 
 /**
  * Bind the given context to the given drawBuffer and readBuffer and
@@ -1411,10 +1431,10 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
    ASSERT(_mesa_get_current_context() == newCtx);
 
    if (!newCtx) {
-      _glapi_set_dispatch(NULL);  /* none current */
+      _mesa_set_dispatch(NULL);  /* none current */
    }
    else {
-      _glapi_set_dispatch(newCtx->CurrentDispatch);
+      _mesa_set_dispatch(newCtx->CurrentDispatch);
 
       if (drawBuffer && readBuffer) {
         /* TODO: check if newCtx and buffer's visual match??? */
index c61da62826fb3dd2f750550d139a789deb9284f7..142243f5ee306e08644e790d08ba826837e0726b 100644 (file)
@@ -145,6 +145,9 @@ extern GLboolean
 _mesa_make_current( GLcontext *ctx, GLframebuffer *drawBuffer,
                     GLframebuffer *readBuffer );
 
+extern void
+_mesa_set_dispatch(void *table);
+
 extern GLboolean
 _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare);
 
index 526145aeccfe90f82fe04cb8b155d28f3b97f867..e5c313304d125dc589b618f248d835ee42de8110 100644 (file)
@@ -201,7 +201,8 @@ static void add_debug_flags( const char *debug )
       { "lighting",  VERBOSE_LIGHTING },
       { "disassem",  VERBOSE_DISASSEM },
       { "draw",      VERBOSE_DRAW },
-      { "swap",      VERBOSE_SWAPBUFFERS }
+      { "swap",      VERBOSE_SWAPBUFFERS },
+      { "dispatch",  VERBOSE_DISPATCH }
    };
    GLuint i;
 
@@ -211,6 +212,9 @@ static void add_debug_flags( const char *debug )
          MESA_VERBOSE |= debug_opt[i].flag;
    }
 
+   if ((MESA_VERBOSE & VERBOSE_DISPATCH) && !_glapi_logging_available())
+      _mesa_debug(NULL, "dispatch logging not available in this buidl\n");
+
    /* Debug flag:
     */
    if (strstr(debug, "flush"))
index 6928d21a21ef366620e122ed3fb67870e7ab8833..0c4e3d51a9d535e4ec560c93c30f0b5d2c7fe24c 100644 (file)
@@ -8062,7 +8062,7 @@ _mesa_NewList(GLuint name, GLenum mode)
    ctx->Driver.NewList(ctx, name, mode);
 
    ctx->CurrentDispatch = ctx->Save;
-   _glapi_set_dispatch(ctx->CurrentDispatch);
+   _mesa_set_dispatch(ctx->CurrentDispatch);
 }
 
 
@@ -8109,7 +8109,7 @@ _mesa_EndList(void)
    ctx->CompileFlag = GL_FALSE;
 
    ctx->CurrentDispatch = ctx->Exec;
-   _glapi_set_dispatch(ctx->CurrentDispatch);
+   _mesa_set_dispatch(ctx->CurrentDispatch);
 }
 
 
@@ -8143,7 +8143,7 @@ _mesa_CallList(GLuint list)
    /* also restore API function pointers to point to "save" versions */
    if (save_compile_flag) {
       ctx->CurrentDispatch = ctx->Save;
-      _glapi_set_dispatch(ctx->CurrentDispatch);
+      _mesa_set_dispatch(ctx->CurrentDispatch);
    }
 }
 
@@ -8195,7 +8195,7 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
    /* also restore API function pointers to point to "save" versions */
    if (save_compile_flag) {
       ctx->CurrentDispatch = ctx->Save;
-      _glapi_set_dispatch(ctx->CurrentDispatch);
+      _mesa_set_dispatch(ctx->CurrentDispatch);
    }
 }
 
index 3e54656981d4be6d13a831442616f180d7c6a37e..96fd9141902f3f39972c183b377bc8c41485c8dc 100644 (file)
@@ -3345,7 +3345,8 @@ enum _verbose
    VERBOSE_VERTS               = 0x0800,
    VERBOSE_DISASSEM            = 0x1000,
    VERBOSE_DRAW                 = 0x2000,
-   VERBOSE_SWAPBUFFERS          = 0x4000
+   VERBOSE_SWAPBUFFERS          = 0x4000,
+   VERBOSE_DISPATCH             = 0x8000
 };