~darkxst/ubuntu/raring/cogl/lp1163025

« back to all changes in this revision

Viewing changes to cogl/cogl-bitmask.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2012-03-13 19:11:11 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20120313191111-3hgk529qkh9m6uk2
Tags: 1.9.8-0ubuntu1
* New upstream release (LP: #941617)
* Updated symbols & library name for soname update
* debian/control.in: Bump minimum glib to 2.28
* debian/patches/02_disable_armv5t_specific_optimization.patch: Disabled

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include <string.h>
33
33
 
34
34
#include "cogl-bitmask.h"
 
35
#include "cogl-util.h"
 
36
#include "cogl-flags.h"
 
37
 
 
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 *));
 
41
 
 
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))
35
48
 
36
49
gboolean
37
50
_cogl_bitmask_get_from_array (const CoglBitmask *bitmask,
41
54
 
42
55
  /* If the index is off the end of the array then assume the bit is
43
56
     not set */
44
 
  if (bit_num >= sizeof (unsigned int) * 8 * array->len)
 
57
  if (bit_num >= sizeof (unsigned long) * 8 * array->len)
45
58
    return FALSE;
46
59
  else
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)) &
 
61
              BIT_MASK (bit_num));
50
62
}
51
63
 
52
64
static void
53
65
_cogl_bitmask_convert_to_array (CoglBitmask *bitmask)
54
66
{
55
67
  GArray *array;
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);
58
70
 
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);
62
76
 
69
83
                            gboolean value)
70
84
{
71
85
  GArray *array;
72
 
  unsigned int array_index, new_value_mask;
 
86
  unsigned int array_index;
 
87
  unsigned long new_value_mask;
73
88
 
74
89
  /* If the bitmask is not already an array then we need to allocate one */
75
90
  if (!_cogl_bitmask_has_array (bitmask))
77
92
 
78
93
  array = (GArray *) *bitmask;
79
94
 
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);
84
99
 
85
 
  new_value_mask = 1 << (bit_num % (sizeof (unsigned int) * 8));
 
100
  new_value_mask = BIT_MASK (bit_num);
86
101
 
87
102
  if (value)
88
 
    g_array_index (array, unsigned int, array_index) |= new_value_mask;
 
103
    g_array_index (array, unsigned long, array_index) |= new_value_mask;
89
104
  else
90
 
    g_array_index (array, unsigned int, array_index) &= ~new_value_mask;
 
105
    g_array_index (array, unsigned long, array_index) &= ~new_value_mask;
91
106
}
92
107
 
93
108
void
109
124
        g_array_set_size (dst_array, src_array->len);
110
125
 
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);
114
129
    }
115
130
  else if (_cogl_bitmask_has_array (dst))
116
131
    {
118
133
 
119
134
      dst_array = (GArray *) *dst;
120
135
 
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);
123
138
    }
124
139
  else
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));
127
142
}
128
143
 
129
144
void
144
159
  array = (GArray *) *bitmask;
145
160
 
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);
154
169
  if (value)
155
170
    {
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);
159
174
 
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);
162
177
    }
163
178
  else
164
179
    {
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;
168
182
 
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);
171
185
    }
172
186
}
173
187
 
190
204
        g_array_set_size (dst_array, src_array->len);
191
205
 
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);
195
209
    }
196
210
  else if (_cogl_bitmask_has_array (dst))
197
211
    {
199
213
 
200
214
      dst_array = (GArray *) *dst;
201
215
 
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);
204
218
    }
205
219
  else
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));
208
222
}
209
223
 
210
224
void
212
226
{
213
227
  GArray *array = (GArray *) *bitmask;
214
228
 
215
 
  memset (array->data, 0, sizeof (unsigned int) * array->len);
 
229
  memset (array->data, 0, sizeof (unsigned long) * array->len);
216
230
}
217
231
 
218
232
void
219
233
_cogl_bitmask_foreach (const CoglBitmask *bitmask,
220
234
                       CoglBitmaskForeachFunc func,
221
 
                       gpointer user_data)
 
235
                       void *user_data)
222
236
{
223
237
  if (_cogl_bitmask_has_array (bitmask))
224
238
    {
225
239
      GArray *array = (GArray *) *bitmask;
226
 
      int array_index;
227
 
 
228
 
      for (array_index = 0; array_index < array->len; array_index++)
229
 
        {
230
 
          unsigned int mask = g_array_index (array, unsigned int, array_index);
231
 
          int bit = 0;
232
 
 
233
 
          while (mask)
234
 
            {
235
 
              if (mask & 1)
236
 
                func (array_index * sizeof (unsigned int) * 8 + bit, user_data);
237
 
 
238
 
              bit++;
239
 
              mask >>= 1;
240
 
            }
241
 
        }
242
 
    }
243
 
  else
244
 
    {
245
 
      unsigned int mask = GPOINTER_TO_UINT (*bitmask) >> 1;
246
 
      int bit = 0;
247
 
 
248
 
      while (mask)
249
 
        {
250
 
          if (mask & 1)
251
 
            func (bit, user_data);
252
 
 
253
 
          bit++;
254
 
          mask >>= 1;
255
 
        }
 
240
      const unsigned long *values = &g_array_index (array, unsigned long, 0);
 
241
      int bit_num;
 
242
 
 
243
      COGL_FLAGS_FOREACH_START (values, array->len, bit_num)
 
244
        {
 
245
          if (!func (bit_num, user_data))
 
246
            return;
 
247
        }
 
248
      COGL_FLAGS_FOREACH_END;
 
249
    }
 
250
  else
 
251
    {
 
252
      unsigned long mask = _cogl_bitmask_to_bits (bitmask);
 
253
      int bit_num;
 
254
 
 
255
      COGL_FLAGS_FOREACH_START (&mask, 1, bit_num)
 
256
        {
 
257
          if (!func (bit_num, user_data))
 
258
            return;
 
259
        }
 
260
      COGL_FLAGS_FOREACH_END;
 
261
    }
 
262
}
 
263
 
 
264
void
 
265
_cogl_bitmask_set_flags_array (const CoglBitmask *bitmask,
 
266
                               unsigned long *flags)
 
267
{
 
268
  const GArray *array = (const GArray *) *bitmask;
 
269
  int i;
 
270
 
 
271
  for (i = 0; i < array->len; i++)
 
272
    flags[i] |= g_array_index (array, unsigned long, i);
 
273
}
 
274
 
 
275
int
 
276
_cogl_bitmask_popcount_in_array (const CoglBitmask *bitmask)
 
277
{
 
278
  const GArray *array = (const GArray *) *bitmask;
 
279
  int pop = 0;
 
280
  int i;
 
281
 
 
282
  for (i = 0; i < array->len; i++)
 
283
    pop += _cogl_util_popcountl (g_array_index (array, unsigned long, i));
 
284
 
 
285
  return pop;
 
286
}
 
287
 
 
288
int
 
289
_cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask,
 
290
                                      int upto)
 
291
{
 
292
  const GArray *array = (const GArray *) *bitmask;
 
293
 
 
294
  if (upto >= array->len * sizeof (unsigned long) * 8)
 
295
    return _cogl_bitmask_popcount_in_array (bitmask);
 
296
  else
 
297
    {
 
298
      unsigned long top_mask;
 
299
      int array_index = ARRAY_INDEX (upto);
 
300
      int bit_index = BIT_INDEX (upto);
 
301
      int pop = 0;
 
302
      int i;
 
303
 
 
304
      for (i = 0; i < array_index; i++)
 
305
        pop += _cogl_util_popcountl (g_array_index (array, unsigned long, i));
 
306
 
 
307
      top_mask = g_array_index (array, unsigned long, array_index);
 
308
 
 
309
      return pop + _cogl_util_popcountl (top_mask & ((1UL << bit_index) - 1));
256
310
    }
257
311
}