From 9e9c615e49eda68a67685ee8d6bcdce8978316e9 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 23 Feb 2009 12:47:02 +0000 Subject: [PATCH] Add runtime debug messages for COGL Clutter is able to show debug messages written using the CLUTTER_NOTE() macro at runtime, either by using an environment variable: CLUTTER_DEBUG=... or by using a command line switch: --clutter-debug=... --clutter-no-debug=... Both are parsed during the initialization process by using the GOption API. COGL would benefit from having the same support. In order to do this, we need a cogl_get_option_group() function in COGL that sets up a GOptionGroup for COGL and adds a pre-parse hook that will check the COGL_DEBUG environment variable. The OptionGroup will also install two command line switches: --cogl-debug --cogl-no-debug With the same semantics of the Clutter ones. During Clutter initialization, the COGL option group will be attached to the GOptionContext used to parse the command line options passed to a Clutter application. Every debug message written using: COGL_NOTE (SECTION, "message format", arguments); Will then be printed only if SECTION was enabled at runtime. This whole machinery, like the equivalent one in Clutter, depends on a compile time switch, COGL_ENABLE_DEBUG, which is enabled at the same time as CLUTTER_ENABLE_DEBUG. Having two different symbols allows greater granularity. --- cogl-debug.h | 45 +++++++++++++++++++++ cogl.h.in | 18 ++++++++- common/Makefile.am | 3 +- common/cogl-debug.c | 98 +++++++++++++++++++++++++++++++++++++++++++++ gl/Makefile.am | 4 +- gles/Makefile.am | 4 +- 6 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 cogl-debug.h create mode 100644 common/cogl-debug.c diff --git a/cogl-debug.h b/cogl-debug.h new file mode 100644 index 000000000..815dcbc4f --- /dev/null +++ b/cogl-debug.h @@ -0,0 +1,45 @@ +#ifndef __COGL_DEBUG_H__ +#define __COGL_DEBUG_H__ + +#include + +G_BEGIN_DECLS + +typedef enum { + COGL_DEBUG_MISC = 1 << 0, + COGL_DEBUG_TEXTURE = 1 << 1, + COGL_DEBUG_MATERIAL = 1 << 2, + COGL_DEBUG_SHADER = 1 << 3, + COGL_DEBUG_OFFSCREEN = 1 << 4, + COGL_DEBUG_DRAW = 1 << 5 +} CoglDebugFlags; + +#ifdef COGL_ENABLE_DEBUG + +#ifdef __GNUC__ +#define COGL_NOTE(type,x,a...) G_STMT_START { \ + if (cogl_debug_flags & COGL_DEBUG_##type) { \ + g_message ("[" #type "] " G_STRLOC ": " x, ##a); \ + } } G_STMT_END + +#else +#define COGL_NOTE(type,...) G_STMT_START { \ + if (cogl_debug_flags & COGL_DEBUG_##type) { \ + gchar *_fmt = g_strdup_printf (__VA_ARGS__); \ + g_message ("[" #type "] " G_STRLOC ": %s", _fmt); \ + g_free (_fmt); \ + } } G_STMT_END + +#endif /* __GNUC__ */ + +#else /* !COGL_ENABLE_DEBUG */ + +#define COGL_NOTE(type,...) + +#endif /* COGL_ENABLE_DEBUG */ + +extern guint cogl_debug_flags; + +G_END_DECLS + +#endif /* __COGL_DEBUG_H__ */ diff --git a/cogl.h.in b/cogl.h.in index 06c32a546..f1388537a 100644 --- a/cogl.h.in +++ b/cogl.h.in @@ -26,10 +26,10 @@ #ifndef __COGL_H__ #define __COGL_H__ -#define __COGL_H_INSIDE__ - #include +#define __COGL_H_INSIDE__ + #include #include @@ -43,6 +43,7 @@ #include #include #include +#include #include G_BEGIN_DECLS @@ -70,6 +71,19 @@ gboolean cogl_create_context (void); */ void cogl_destroy_context (void); +/** + * cogl_get_option_group: + * + * Retrieves the #GOptionGroup used by COGL to parse the command + * line options. Clutter uses this to handle the COGL command line + * options during its initialization process. + * + * Return value: a #GOptionGroup + * + * Since: 1.0 + */ +GOptionGroup * cogl_get_option_group (void); + /* Misc */ /** * cogl_get_features: diff --git a/common/Makefile.am b/common/Makefile.am index 8777defc6..7a322326a 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -35,4 +35,5 @@ libclutter_cogl_common_la_SOURCES = \ cogl-vertex-buffer.c \ cogl-matrix.c \ cogl-material.c \ - cogl-material-private.h + cogl-material-private.h \ + cogl-debug.c diff --git a/common/cogl-debug.c b/common/cogl-debug.c new file mode 100644 index 000000000..863da3b4a --- /dev/null +++ b/common/cogl-debug.c @@ -0,0 +1,98 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "cogl-debug.h" + +#ifdef COGL_ENABLE_DEBUG +static const GDebugKey cogl_debug_keys[] = { + { "misc", COGL_DEBUG_MISC }, + { "texture", COGL_DEBUG_TEXTURE }, + { "material", COGL_DEBUG_MATERIAL }, + { "shader", COGL_DEBUG_SHADER }, + { "offscreen", COGL_DEBUG_OFFSCREEN }, + { "draw", COGL_DEBUG_DRAW } +}; + +static const gint n_cogl_debug_keys = G_N_ELEMENTS (cogl_debug_keys); +#endif /* COGL_ENABLE_DEBUG */ + +guint cogl_debug_flags = 0; + +#ifdef COGL_ENABLE_DEBUG +static gboolean +cogl_arg_debug_cb (const char *key, + const char *value, + gpointer user_data) +{ + cogl_debug_flags |= + g_parse_debug_string (value, + cogl_debug_keys, + n_cogl_debug_keys); + return TRUE; +} + +static gboolean +cogl_arg_no_debug_cb (const char *key, + const char *value, + gpointer user_data) +{ + cogl_debug_flags &= + ~g_parse_debug_string (value, + cogl_debug_keys, + n_cogl_debug_keys); + return TRUE; +} +#endif /* CLUTTER_ENABLE_DEBUG */ + +static GOptionEntry cogl_args[] = { +#ifdef COGL_ENABLE_DEBUG + { "cogl-debug", 0, 0, G_OPTION_ARG_CALLBACK, cogl_arg_debug_cb, + N_("COGL debugging flags to set"), "FLAGS" }, + { "cogl-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, cogl_arg_no_debug_cb, + N_("COGL debugging flags to unset"), "FLAGS" }, +#endif /* COGL_ENABLE_DEBUG */ + { NULL, }, +}; + +static gboolean +pre_parse_hook (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + const char *env_string; + +#ifdef COGL_ENABLE_DEBUG + env_string = g_getenv ("COGL_DEBUG"); + if (env_string != NULL) + { + cogl_debug_flags = + g_parse_debug_string (env_string, + cogl_debug_keys, + n_cogl_debug_keys); + env_string = NULL; + } +#endif /* COGL_ENABLE_DEBUG */ + + return TRUE; +} + +GOptionGroup * +cogl_get_option_group (void) +{ + GOptionGroup *group; + + group = g_option_group_new ("cogl", + _("COGL Options"), + _("Show COGL options"), + NULL, NULL); + + g_option_group_set_parse_hooks (group, pre_parse_hook, NULL); + g_option_group_add_entries (group, cogl_args); + g_option_group_set_translation_domain (group, GETTEXT_PACKAGE); + + return group; +} diff --git a/gl/Makefile.am b/gl/Makefile.am index 394629ce9..12e2ee92a 100644 --- a/gl/Makefile.am +++ b/gl/Makefile.am @@ -12,7 +12,8 @@ libclutterinclude_HEADERS = \ $(top_builddir)/clutter/cogl/cogl-types.h \ $(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \ $(top_builddir)/clutter/cogl/cogl-material.h \ - $(top_builddir)/clutter/cogl/cogl-matrix.h + $(top_builddir)/clutter/cogl/cogl-matrix.h \ + $(top_builddir)/clutter/cogl/cogl-debug.h INCLUDES = \ -I$(top_srcdir) \ @@ -44,6 +45,7 @@ libclutter_cogl_la_SOURCES = \ $(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-types.h \ + $(top_builddir)/clutter/cogl/cogl-debug.h \ cogl-internal.h \ cogl-texture-private.h \ cogl-fbo.h \ diff --git a/gles/Makefile.am b/gles/Makefile.am index a33fbbe5d..1ec4ae789 100644 --- a/gles/Makefile.am +++ b/gles/Makefile.am @@ -12,7 +12,8 @@ libclutterinclude_HEADERS = \ $(top_builddir)/clutter/cogl/cogl-types.h \ $(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \ $(top_builddir)/clutter/cogl/cogl-material.h \ - $(top_builddir)/clutter/cogl/cogl-matrix.h + $(top_builddir)/clutter/cogl/cogl-matrix.h \ + $(top_builddir)/clutter/cogl/cogl-debug.h INCLUDES = \ -I$(top_srcdir) \ @@ -44,6 +45,7 @@ libclutter_cogl_la_SOURCES = \ $(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-types.h \ + $(top_builddir)/clutter/cogl/cogl-debug.h \ cogl-internal.h \ cogl-texture-private.h \ cogl-fbo.h \