mutter/cogl/cogl-debug.c
Neil Roberts 4a7762d6d7 cogl-context: Store winsys features in an array of unsigned ints
Previously the mask of available winsys features was stored in a
CoglBitmask. That isn't the ideal type to use for this because it is
intended for a growable array of bits so it can allocate extra memory
if there are more than 31 flags set. For the winsys feature flags the
highest used bit is known at compile time so it makes sense to
allocate a fixed array instead. This is conceptually similar to the
CoglDebugFlags which are stored in an array of integers with macros to
test a bit in the array. This moves the macros used for CoglDebugFlags
to cogl-flags.h and makes them more generic so they can be shared with
CoglContext.
2011-04-20 18:20:10 +01:00

248 lines
8.1 KiB
C

/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <glib/gi18n-lib.h>
#include "cogl-debug.h"
#ifdef COGL_ENABLE_DEBUG
/* XXX: If you add a debug option, please also add an option
* definition to cogl-debug-options.h. This will enable us - for
* example - to emit a "help" description for the option.
*/
/* NB: Only these options get enabled if COGL_DEBUG=all is
* used since they don't affect the behaviour of Cogl they
* simply print out verbose information */
static const GDebugKey cogl_log_debug_keys[] = {
{ "handle", COGL_DEBUG_HANDLE },
{ "slicing", COGL_DEBUG_SLICING },
{ "atlas", COGL_DEBUG_ATLAS },
{ "blend-strings", COGL_DEBUG_BLEND_STRINGS },
{ "journal", COGL_DEBUG_JOURNAL },
{ "batching", COGL_DEBUG_BATCHING },
{ "matrices", COGL_DEBUG_MATRICES },
{ "draw", COGL_DEBUG_DRAW },
{ "opengl", COGL_DEBUG_OPENGL },
{ "pango", COGL_DEBUG_PANGO },
{ "show-source", COGL_DEBUG_SHOW_SOURCE},
{ "offscreen", COGL_DEBUG_OFFSCREEN },
{ "texture-pixmap", COGL_DEBUG_TEXTURE_PIXMAP },
{ "bitmap", COGL_DEBUG_BITMAP },
{ "clipping", COGL_DEBUG_CLIPPING }
};
static const int n_cogl_log_debug_keys =
G_N_ELEMENTS (cogl_log_debug_keys);
static const GDebugKey cogl_behavioural_debug_keys[] = {
{ "rectangles", COGL_DEBUG_RECTANGLES },
{ "disable-batching", COGL_DEBUG_DISABLE_BATCHING },
{ "disable-vbos", COGL_DEBUG_DISABLE_VBOS },
{ "disable-pbos", COGL_DEBUG_DISABLE_PBOS },
{ "disable-software-transform", COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM },
{ "dump-atlas-image", COGL_DEBUG_DUMP_ATLAS_IMAGE },
{ "disable-atlas", COGL_DEBUG_DISABLE_ATLAS },
{ "disable-texturing", COGL_DEBUG_DISABLE_TEXTURING},
{ "disable-arbfp", COGL_DEBUG_DISABLE_ARBFP},
{ "disable-fixed", COGL_DEBUG_DISABLE_FIXED},
{ "disable-glsl", COGL_DEBUG_DISABLE_GLSL},
{ "disable-blending", COGL_DEBUG_DISABLE_BLENDING},
{ "disable-npot-textures", COGL_DEBUG_DISABLE_NPOT_TEXTURES},
{ "wireframe", COGL_DEBUG_WIREFRAME},
{ "disable-software-clip", COGL_DEBUG_DISABLE_SOFTWARE_CLIP},
{ "disable-program-caches", COGL_DEBUG_DISABLE_PROGRAM_CACHES},
{ "disable-fast-read-pixel", COGL_DEBUG_DISABLE_FAST_READ_PIXEL}
};
static const int n_cogl_behavioural_debug_keys =
G_N_ELEMENTS (cogl_behavioural_debug_keys);
unsigned int _cogl_debug_flags[COGL_DEBUG_N_INTS];
static void
_cogl_parse_debug_string_for_keys (const char *value,
gboolean enable,
const GDebugKey *keys,
unsigned int nkeys)
{
int int_num, key_num;
/* g_parse_debug_string expects the value field in GDebugKey to be a
mask in a guint but we may have multiple guints so we need to
build a separate array for each possible guint */
for (int_num = 0; int_num < COGL_DEBUG_N_INTS; int_num++)
{
GDebugKey keys_for_int[sizeof (unsigned int) * 8];
unsigned int mask_for_int;
int nkeys_for_int = 0;
for (key_num = 0; key_num < nkeys; key_num++)
if (COGL_FLAGS_GET_INDEX (keys[key_num].value) == int_num)
{
keys_for_int[nkeys_for_int] = keys[key_num];
keys_for_int[nkeys_for_int].value =
COGL_FLAGS_GET_MASK (keys[key_num].value);
nkeys_for_int++;
}
if (nkeys_for_int > 0)
{
mask_for_int = g_parse_debug_string (value,
keys_for_int,
nkeys_for_int);
if (enable)
_cogl_debug_flags[int_num] |= mask_for_int;
else
_cogl_debug_flags[int_num] &= ~mask_for_int;
}
}
}
static void
_cogl_parse_debug_string (const char *value,
gboolean enable,
gboolean ignore_help)
{
if (ignore_help && strcmp (value, "help") == 0)
return;
/* We don't want to let g_parse_debug_string handle "all" because
* literally enabling all the debug options wouldn't be useful to
* anyone; instead the all option enables all non behavioural
* options.
*/
if (strcmp (value, "all") == 0 ||
strcmp (value, "verbose") == 0)
{
int i;
for (i = 0; i < n_cogl_log_debug_keys; i++)
if (enable)
COGL_DEBUG_SET_FLAG (cogl_log_debug_keys[i].value);
else
COGL_DEBUG_CLEAR_FLAG (cogl_log_debug_keys[i].value);
}
else if (strcmp (value, "help") == 0)
{
g_printerr ("\n\n%28s\n", "Supported debug values:");
#define OPT(MASK_NAME, GROUP, NAME, NAME_FORMATTED, DESCRIPTION) \
g_printerr ("%28s %s\n", NAME ":", DESCRIPTION);
#include "cogl-debug-options.h"
g_printerr ("\n%28s\n", "Special debug values:");
OPT (IGNORED, "ignored", "all", "ignored", \
"Enables all non-behavioural debug options");
OPT (IGNORED, "ignored", "verbose", "ignored", \
"Enables all non-behavioural debug options");
#undef OPT
exit (1);
}
else
{
_cogl_parse_debug_string_for_keys (value,
enable,
cogl_log_debug_keys,
n_cogl_log_debug_keys);
_cogl_parse_debug_string_for_keys (value,
enable,
cogl_behavioural_debug_keys,
n_cogl_behavioural_debug_keys);
}
}
static gboolean
cogl_arg_debug_cb (const char *key,
const char *value,
gpointer user_data)
{
_cogl_parse_debug_string (value,
TRUE /* enable the flags */,
FALSE /* don't ignore help */);
return TRUE;
}
static gboolean
cogl_arg_no_debug_cb (const char *key,
const char *value,
gpointer user_data)
{
_cogl_parse_debug_string (value,
FALSE, /* disable the flags */
TRUE /* ignore help */);
return TRUE;
}
#endif /* COGL_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)
{
#ifdef COGL_ENABLE_DEBUG
const char *env_string;
env_string = g_getenv ("COGL_DEBUG");
if (env_string != NULL)
{
_cogl_parse_debug_string (env_string,
TRUE /* enable the flags */,
FALSE /* don't ignore help */);
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;
}