cogl-bitmask: Use ffsl to speedup bitmask iteration
Instead of testing each bit when iterating a bitmask, we can use ffsl to skip over unset bits in single instruction. That way it will scale by the number of bits set, not the total number of bits. ffsl is a non-standard function which glibc only provides by defining GNUC_SOURCE. However if we are compiling with GCC we can avoid that mess and just use the equivalent builtin. When not compiling for GCC it will fall back to _cogl_util_ffs if the size of ints and longs are the same (which is the case on i686). Otherwise it fallbacks to a slow function implementation. Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
@ -108,6 +108,21 @@ int
|
||||
_cogl_util_ffs (int num);
|
||||
#endif
|
||||
|
||||
/* The 'ffsl' function is non-standard but GCC has a builtin for it
|
||||
since 3.4 which we can use */
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
#define _cogl_util_ffsl __builtin_ffsl
|
||||
#define COGL_UTIL_HAVE_BUILTIN_FFSL
|
||||
#else
|
||||
/* If ints and longs are the same size we can just use ffs. Hopefully
|
||||
the compiler will optimise away this conditional */
|
||||
#define _cogl_util_ffsl(x) \
|
||||
(sizeof (long int) == sizeof (int) ? _cogl_util_ffs ((int) x) : \
|
||||
_cogl_util_ffsl_wrapper (x))
|
||||
int
|
||||
_cogl_util_ffsl_wrapper (long int num);
|
||||
#endif
|
||||
|
||||
#ifdef COGL_HAS_GLIB_SUPPORT
|
||||
#define _COGL_RETURN_IF_FAIL(EXPR) g_return_if_fail(EXPR)
|
||||
#define _COGL_RETURN_VAL_IF_FAIL(EXPR, VAL) g_return_val_if_fail(EXPR, VAL)
|
||||
|
Reference in New Issue
Block a user