32
32
#include <string.h>
34
34
#include "cogl-bitmask.h"
35
#include "cogl-util.h"
36
#include "cogl-flags.h"
38
/* This code assumes that we can cast an unsigned long to a pointer
39
and back without losing any data */
40
G_STATIC_ASSERT (sizeof (unsigned long) <= sizeof (void *));
42
#define ARRAY_INDEX(bit_num) \
43
((bit_num) / (sizeof (unsigned long) * 8))
44
#define BIT_INDEX(bit_num) \
45
((bit_num) & (sizeof (unsigned long) * 8 - 1))
46
#define BIT_MASK(bit_num) \
47
(1UL << BIT_INDEX (bit_num))
37
50
_cogl_bitmask_get_from_array (const CoglBitmask *bitmask,
42
55
/* If the index is off the end of the array then assume the bit is
44
if (bit_num >= sizeof (unsigned int) * 8 * array->len)
57
if (bit_num >= sizeof (unsigned long) * 8 * array->len)
47
return !!(g_array_index (array, unsigned int,
48
bit_num / (sizeof (unsigned int) * 8)) &
49
(1 << (bit_num % (sizeof (unsigned int) * 8))));
60
return !!(g_array_index (array, unsigned long, ARRAY_INDEX (bit_num)) &
53
65
_cogl_bitmask_convert_to_array (CoglBitmask *bitmask)
56
/* Fetch the old values, ignoring the least significant bit */
57
unsigned int old_values = GPOINTER_TO_UINT (*bitmask) >> 1;
68
/* Fetch the old values */
69
unsigned long old_values = _cogl_bitmask_to_bits (bitmask);
59
array = g_array_new (FALSE, TRUE, sizeof (unsigned int));
71
array = g_array_new (FALSE, /* not zero-terminated */
72
TRUE, /* do clear new entries */
73
sizeof (unsigned long));
60
74
/* Copy the old values back in */
61
75
g_array_append_val (array, old_values);
78
93
array = (GArray *) *bitmask;
80
array_index = bit_num / (sizeof (unsigned int) * 8);
95
array_index = ARRAY_INDEX (bit_num);
81
96
/* Grow the array if necessary. This will clear the new data */
82
97
if (array_index >= array->len)
83
98
g_array_set_size (array, array_index + 1);
85
new_value_mask = 1 << (bit_num % (sizeof (unsigned int) * 8));
100
new_value_mask = BIT_MASK (bit_num);
88
g_array_index (array, unsigned int, array_index) |= new_value_mask;
103
g_array_index (array, unsigned long, array_index) |= new_value_mask;
90
g_array_index (array, unsigned int, array_index) &= ~new_value_mask;
105
g_array_index (array, unsigned long, array_index) &= ~new_value_mask;
109
124
g_array_set_size (dst_array, src_array->len);
111
126
for (i = 0; i < src_array->len; i++)
112
g_array_index (dst_array, unsigned int, i) |=
113
g_array_index (src_array, unsigned int, i);
127
g_array_index (dst_array, unsigned long, i) |=
128
g_array_index (src_array, unsigned long, i);
115
130
else if (_cogl_bitmask_has_array (dst))
119
134
dst_array = (GArray *) *dst;
121
g_array_index (dst_array, unsigned int, 0) |=
122
(GPOINTER_TO_UINT (*src) >> 1);
136
g_array_index (dst_array, unsigned long, 0) |=
137
_cogl_bitmask_to_bits (src);
125
*dst = GUINT_TO_POINTER (GPOINTER_TO_UINT (*dst) |
126
GPOINTER_TO_UINT (*src));
140
*dst = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (dst) |
141
_cogl_bitmask_to_bits (src));
144
159
array = (GArray *) *bitmask;
146
161
/* Get the array index of the top most value that will be touched */
147
array_index = (n_bits - 1) / (sizeof (unsigned int) * 8);
162
array_index = ARRAY_INDEX (n_bits - 1);
148
163
/* Get the bit index of the top most value */
149
bit_index = (n_bits - 1) % (sizeof (unsigned int) * 8);
164
bit_index = BIT_INDEX (n_bits - 1);
150
165
/* Grow the array if necessary. This will clear the new data */
151
166
if (array_index >= array->len)
152
167
g_array_set_size (array, array_index + 1);
156
171
/* Set the bits that are touching this index */
157
g_array_index (array, unsigned int, array_index) |=
158
~(unsigned int) 0 >> (sizeof (unsigned int) * 8 - 1 - bit_index);
172
g_array_index (array, unsigned long, array_index) |=
173
~0UL >> (sizeof (unsigned long) * 8 - 1 - bit_index);
160
175
/* Set all of the bits in any lesser indices */
161
memset (array->data, 0xff, sizeof (unsigned int) * array_index);
176
memset (array->data, 0xff, sizeof (unsigned long) * array_index);
165
180
/* Clear the bits that are touching this index */
166
g_array_index (array, unsigned int, array_index) &=
167
~(unsigned int) 1 << bit_index;
181
g_array_index (array, unsigned long, array_index) &= ~1UL << bit_index;
169
183
/* Clear all of the bits in any lesser indices */
170
memset (array->data, 0x00, sizeof (unsigned int) * array_index);
184
memset (array->data, 0x00, sizeof (unsigned long) * array_index);
190
204
g_array_set_size (dst_array, src_array->len);
192
206
for (i = 0; i < src_array->len; i++)
193
g_array_index (dst_array, unsigned int, i) ^=
194
g_array_index (src_array, unsigned int, i);
207
g_array_index (dst_array, unsigned long, i) ^=
208
g_array_index (src_array, unsigned long, i);
196
210
else if (_cogl_bitmask_has_array (dst))
200
214
dst_array = (GArray *) *dst;
202
g_array_index (dst_array, unsigned int, 0) ^=
203
(GPOINTER_TO_UINT (*src) >> 1);
216
g_array_index (dst_array, unsigned long, 0) ^=
217
_cogl_bitmask_to_bits (src);
206
*dst = GUINT_TO_POINTER ((GPOINTER_TO_UINT (*dst) ^
207
GPOINTER_TO_UINT (*src)) | 1);
220
*dst = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (dst) ^
221
_cogl_bitmask_to_bits (src));
213
227
GArray *array = (GArray *) *bitmask;
215
memset (array->data, 0, sizeof (unsigned int) * array->len);
229
memset (array->data, 0, sizeof (unsigned long) * array->len);
219
233
_cogl_bitmask_foreach (const CoglBitmask *bitmask,
220
234
CoglBitmaskForeachFunc func,
223
237
if (_cogl_bitmask_has_array (bitmask))
225
239
GArray *array = (GArray *) *bitmask;
228
for (array_index = 0; array_index < array->len; array_index++)
230
unsigned int mask = g_array_index (array, unsigned int, array_index);
236
func (array_index * sizeof (unsigned int) * 8 + bit, user_data);
245
unsigned int mask = GPOINTER_TO_UINT (*bitmask) >> 1;
251
func (bit, user_data);
240
const unsigned long *values = &g_array_index (array, unsigned long, 0);
243
COGL_FLAGS_FOREACH_START (values, array->len, bit_num)
245
if (!func (bit_num, user_data))
248
COGL_FLAGS_FOREACH_END;
252
unsigned long mask = _cogl_bitmask_to_bits (bitmask);
255
COGL_FLAGS_FOREACH_START (&mask, 1, bit_num)
257
if (!func (bit_num, user_data))
260
COGL_FLAGS_FOREACH_END;
265
_cogl_bitmask_set_flags_array (const CoglBitmask *bitmask,
266
unsigned long *flags)
268
const GArray *array = (const GArray *) *bitmask;
271
for (i = 0; i < array->len; i++)
272
flags[i] |= g_array_index (array, unsigned long, i);
276
_cogl_bitmask_popcount_in_array (const CoglBitmask *bitmask)
278
const GArray *array = (const GArray *) *bitmask;
282
for (i = 0; i < array->len; i++)
283
pop += _cogl_util_popcountl (g_array_index (array, unsigned long, i));
289
_cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask,
292
const GArray *array = (const GArray *) *bitmask;
294
if (upto >= array->len * sizeof (unsigned long) * 8)
295
return _cogl_bitmask_popcount_in_array (bitmask);
298
unsigned long top_mask;
299
int array_index = ARRAY_INDEX (upto);
300
int bit_index = BIT_INDEX (upto);
304
for (i = 0; i < array_index; i++)
305
pop += _cogl_util_popcountl (g_array_index (array, unsigned long, i));
307
top_mask = g_array_index (array, unsigned long, array_index);
309
return pop + _cogl_util_popcountl (top_mask & ((1UL << bit_index) - 1));