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.
This commit is contained in:
Emmanuele Bassi 2009-02-23 12:47:02 +00:00
parent a4c8e78477
commit 605dfb8fd0
8 changed files with 177 additions and 9 deletions

View File

@ -1500,9 +1500,12 @@ clutter_init_with_args (int *argc,
if (argc && *argc > 0 && *argv) if (argc && *argc > 0 && *argv)
g_set_prgname ((*argv)[0]); g_set_prgname ((*argv)[0]);
group = clutter_get_option_group ();
context = g_option_context_new (parameter_string); context = g_option_context_new (parameter_string);
group = clutter_get_option_group ();
g_option_context_add_group (context, group);
group = cogl_get_option_group ();
g_option_context_add_group (context, group); g_option_context_add_group (context, group);
if (entries) if (entries)
@ -1536,7 +1539,7 @@ clutter_parse_args (int *argc,
char ***argv) char ***argv)
{ {
GOptionContext *option_context; GOptionContext *option_context;
GOptionGroup *clutter_group; GOptionGroup *clutter_group, *cogl_group;
GError *error = NULL; GError *error = NULL;
gboolean ret = TRUE; gboolean ret = TRUE;
@ -1552,6 +1555,9 @@ clutter_parse_args (int *argc,
clutter_group = clutter_get_option_group (); clutter_group = clutter_get_option_group ();
g_option_context_set_main_group (option_context, clutter_group); g_option_context_set_main_group (option_context, clutter_group);
cogl_group = cogl_get_option_group ();
g_option_context_add_group (option_context, cogl_group);
if (!g_option_context_parse (option_context, argc, argv, &error)) if (!g_option_context_parse (option_context, argc, argv, &error))
{ {
if (error) if (error)

45
clutter/cogl/cogl-debug.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef __COGL_DEBUG_H__
#define __COGL_DEBUG_H__
#include <glib.h>
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__ */

View File

@ -26,10 +26,10 @@
#ifndef __COGL_H__ #ifndef __COGL_H__
#define __COGL_H__ #define __COGL_H__
#define __COGL_H_INSIDE__
#include <glib.h> #include <glib.h>
#define __COGL_H_INSIDE__
#include <cogl/cogl-defines-@CLUTTER_COGL@.h> #include <cogl/cogl-defines-@CLUTTER_COGL@.h>
#include <cogl/cogl-vertex-buffer.h> #include <cogl/cogl-vertex-buffer.h>
@ -43,6 +43,7 @@
#include <cogl/cogl-shader.h> #include <cogl/cogl-shader.h>
#include <cogl/cogl-texture.h> #include <cogl/cogl-texture.h>
#include <cogl/cogl-types.h> #include <cogl/cogl-types.h>
#include <cogl/cogl-debug.h>
#include <cogl/cogl-deprecated.h> #include <cogl/cogl-deprecated.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -70,6 +71,19 @@ gboolean cogl_create_context (void);
*/ */
void cogl_destroy_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 */ /* Misc */
/** /**
* cogl_get_features: * cogl_get_features:

View File

@ -35,4 +35,5 @@ libclutter_cogl_common_la_SOURCES = \
cogl-vertex-buffer.c \ cogl-vertex-buffer.c \
cogl-matrix.c \ cogl-matrix.c \
cogl-material.c \ cogl-material.c \
cogl-material-private.h cogl-material-private.h \
cogl-debug.c

View File

@ -0,0 +1,98 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <glib/gi18n-lib.h>
#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;
}

View File

@ -12,7 +12,8 @@ libclutterinclude_HEADERS = \
$(top_builddir)/clutter/cogl/cogl-types.h \ $(top_builddir)/clutter/cogl/cogl-types.h \
$(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \ $(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \
$(top_builddir)/clutter/cogl/cogl-material.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 = \ INCLUDES = \
-I$(top_srcdir) \ -I$(top_srcdir) \
@ -44,6 +45,7 @@ libclutter_cogl_la_SOURCES = \
$(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-shader.h \
$(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \
$(top_builddir)/clutter/cogl/cogl-types.h \ $(top_builddir)/clutter/cogl/cogl-types.h \
$(top_builddir)/clutter/cogl/cogl-debug.h \
cogl-internal.h \ cogl-internal.h \
cogl-texture-private.h \ cogl-texture-private.h \
cogl-fbo.h \ cogl-fbo.h \

View File

@ -12,7 +12,8 @@ libclutterinclude_HEADERS = \
$(top_builddir)/clutter/cogl/cogl-types.h \ $(top_builddir)/clutter/cogl/cogl-types.h \
$(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \ $(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \
$(top_builddir)/clutter/cogl/cogl-material.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 = \ INCLUDES = \
-I$(top_srcdir) \ -I$(top_srcdir) \
@ -44,6 +45,7 @@ libclutter_cogl_la_SOURCES = \
$(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-shader.h \
$(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \
$(top_builddir)/clutter/cogl/cogl-types.h \ $(top_builddir)/clutter/cogl/cogl-types.h \
$(top_builddir)/clutter/cogl/cogl-debug.h \
cogl-internal.h \ cogl-internal.h \
cogl-texture-private.h \ cogl-texture-private.h \
cogl-fbo.h \ cogl-fbo.h \

View File

@ -569,12 +569,12 @@ AC_ARG_ENABLE(debug,
if test "x$enable_debug" = "xyes"; then if test "x$enable_debug" = "xyes"; then
test "$cflags_set" = set || CFLAGS="$CFLAGS -g" test "$cflags_set" = set || CFLAGS="$CFLAGS -g"
CLUTTER_DEBUG_CFLAGS="-DCLUTTER_ENABLE_DEBUG" CLUTTER_DEBUG_CFLAGS="-DCLUTTER_ENABLE_DEBUG -DCOGL_ENABLE_DEBUG"
else else
if test "x$enable_debug" = "xno"; then if test "x$enable_debug" = "xno"; then
CLUTTER_DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS" CLUTTER_DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS"
else # minimum else # minimum
CLUTTER_DEBUG_CFLAGS="-DCLUTTER_ENABLE_DEBUG -DG_DISABLE_CAST_CHECKS" CLUTTER_DEBUG_CFLAGS="-DCLUTTER_ENABLE_DEBUG -DCOGL_ENABLE_DEBUG -DG_DISABLE_CAST_CHECKS"
fi fi
fi fi