From f4c1ba9ed9f1555f7a6dbd5bbd84f7b936019ead Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Mon, 31 Oct 2011 14:19:10 +0000 Subject: [PATCH] cogl-flags: Use longs instead of ints Previously cogl-flags was using an array of ints to store the flags. There was a comment saying that it would be nice to use longs but this is awkward because g_parse_debug_flags can only work in ints. This is a silly reason not to use longs because we can just parse multiple sets of flags per long. This patch therefore changes cogl-flags to use longs and tweaks the debug key parsing code. Reviewed-by: Robert Bragg --- cogl/cogl-context-private.h | 6 ++-- cogl/cogl-debug.c | 68 +++++++++++++++++++++++-------------- cogl/cogl-debug.h | 4 +-- cogl/cogl-flags.h | 29 +++++++--------- 4 files changed, 60 insertions(+), 47 deletions(-) diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h index 3b40b36e1..df0aa4a7c 100644 --- a/cogl/cogl-context-private.h +++ b/cogl/cogl-context-private.h @@ -63,7 +63,7 @@ struct _CoglContext const CoglTextureDriver *texture_driver; /* Features cache */ - unsigned int features[COGL_FLAGS_N_INTS_FOR_SIZE (_COGL_N_FEATURE_IDS)]; + unsigned long features[COGL_FLAGS_N_LONGS_FOR_SIZE (_COGL_N_FEATURE_IDS)]; CoglFeatureFlags feature_flags; /* legacy/deprecated feature flags */ CoglPrivateFeatureFlags private_feature_flags; @@ -254,8 +254,8 @@ struct _CoglContext CoglXlibTrapState *trap_state; #endif - unsigned int winsys_features - [COGL_FLAGS_N_INTS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; + unsigned long winsys_features + [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; void *winsys; /* This defines a list of function pointers that Cogl uses from diff --git a/cogl/cogl-debug.c b/cogl/cogl-debug.c index 2e1fb2e95..3651dffdb 100644 --- a/cogl/cogl-debug.c +++ b/cogl/cogl-debug.c @@ -83,7 +83,7 @@ static const GDebugKey cogl_behavioural_debug_keys[] = { static const int n_cogl_behavioural_debug_keys = G_N_ELEMENTS (cogl_behavioural_debug_keys); -unsigned int _cogl_debug_flags[COGL_DEBUG_N_INTS]; +unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; GHashTable *_cogl_debug_instances; static void @@ -92,36 +92,54 @@ _cogl_parse_debug_string_for_keys (const char *value, const GDebugKey *keys, unsigned int nkeys) { - int int_num, key_num; + int long_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 */ + mask in a guint but the flags is stored in an array of multiple + longs so we need to build a separate array for each possible + guint */ - for (int_num = 0; int_num < COGL_DEBUG_N_INTS; int_num++) + for (long_num = 0; long_num < COGL_DEBUG_N_LONGS; long_num++) { - GDebugKey keys_for_int[sizeof (unsigned int) * 8]; - unsigned int mask_for_int; - int nkeys_for_int = 0; + int int_num; - 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) + for (int_num = 0; + int_num < sizeof (unsigned long) / sizeof (unsigned int); + int_num++) { - 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; + GDebugKey keys_for_int[sizeof (unsigned int) * 8]; + int nkeys_for_int = 0; + + for (key_num = 0; key_num < nkeys; key_num++) + { + int long_index = COGL_FLAGS_GET_INDEX (keys[key_num].value); + int int_index = (keys[key_num].value % + (sizeof (unsigned long) * 8) / + (sizeof (unsigned int) * 8)); + + if (long_index == long_num && int_index == 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) >> + (int_num * sizeof (unsigned int) * 8); + nkeys_for_int++; + } + } + + if (nkeys_for_int > 0) + { + unsigned long mask = + ((unsigned long) g_parse_debug_string (value, + keys_for_int, + nkeys_for_int)) << + (int_num * sizeof (unsigned int) * 8); + + if (enable) + _cogl_debug_flags[long_num] |= mask; + else + _cogl_debug_flags[long_num] &= ~mask; + } } } } diff --git a/cogl/cogl-debug.h b/cogl/cogl-debug.h index 3c8c73ae0..901850f7b 100644 --- a/cogl/cogl-debug.h +++ b/cogl/cogl-debug.h @@ -72,9 +72,9 @@ typedef enum { #ifdef COGL_ENABLE_DEBUG -#define COGL_DEBUG_N_INTS COGL_FLAGS_N_INTS_FOR_SIZE (COGL_DEBUG_N_FLAGS) +#define COGL_DEBUG_N_LONGS COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_DEBUG_N_FLAGS) -extern unsigned int _cogl_debug_flags[COGL_DEBUG_N_INTS]; +extern unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; extern GHashTable *_cogl_debug_instances; #define COGL_DEBUG_ENABLED(flag) \ diff --git a/cogl/cogl-flags.h b/cogl/cogl-flags.h index af07532f3..14fb8f198 100644 --- a/cogl/cogl-flags.h +++ b/cogl/cogl-flags.h @@ -36,36 +36,31 @@ G_BEGIN_DECLS that will be set is known at compile time, for example when setting for recording a set of known available features */ -/* The bits are stored in an array of unsigned ints. It would probably - make sense to use unsigned long instead because then on 64-bit - systems where it can handle 64-bits just as easily and it can test - more bits. However GDebugKey uses a guint for the mask and we need - to fit the masks into this */ - -/* To use these macros, you would typically have an enum defining the - available bits with an extra last enum to define the maximum - value. Then to store the flags you would declare an array of - unsigned ints sized using COGL_FLAGS_N_INTS_FOR_SIZE, eg: +/* The bits are stored in an array of unsigned longs. To use these + macros, you would typically have an enum defining the available + bits with an extra last enum to define the maximum value. Then to + store the flags you would declare an array of unsigned longs sized + using COGL_FLAGS_N_LONGS_FOR_SIZE, eg: typedef enum { FEATURE_A, FEATURE_B, FEATURE_C, N_FEATURES } Features; - unsigned int feature_flags[COGL_FLAGS_N_INTS_FOR_SIZE (N_FEATURES)]; + unsigned long feature_flags[COGL_FLAGS_N_LONGS_FOR_SIZE (N_FEATURES)]; */ -#define COGL_FLAGS_N_INTS_FOR_SIZE(size) \ +#define COGL_FLAGS_N_LONGS_FOR_SIZE(size) \ (((size) + \ - (sizeof (unsigned int) * 8 - 1)) \ - / (sizeof (unsigned int) * 8)) + (sizeof (unsigned long) * 8 - 1)) \ + / (sizeof (unsigned long) * 8)) /* @flag is expected to be constant so these should result in a constant expression. This means that setting a flag is equivalent to just setting in a bit in a global variable at a known location */ #define COGL_FLAGS_GET_INDEX(flag) \ - ((flag) / (sizeof (unsigned int) * 8)) + ((flag) / (sizeof (unsigned long) * 8)) #define COGL_FLAGS_GET_MASK(flag) \ - (1U << ((unsigned int) (flag) & \ - (sizeof (unsigned int) * 8 - 1))) + (1UL << ((unsigned long) (flag) & \ + (sizeof (unsigned long) * 8 - 1))) #define COGL_FLAGS_GET(array, flag) \ (!!((array)[COGL_FLAGS_GET_INDEX (flag)] & \