~elementary-os/ubuntu-package-imports/mutter-bionic

« back to all changes in this revision

Viewing changes to cogl/cogl/cogl-object.c

  • Committer: RabbitBot
  • Date: 2018-04-11 14:49:36 UTC
  • Revision ID: rabbitbot@elementary.io-20180411144936-hgymqa9d8d1xfpbh
Initial import, version 3.28.0-2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Cogl
 
3
 *
 
4
 * A Low Level GPU Graphics and Utilities API
 
5
 *
 
6
 * Copyright (C) 2007,2008,2009,2010 Intel Corporation.
 
7
 *
 
8
 * Permission is hereby granted, free of charge, to any person
 
9
 * obtaining a copy of this software and associated documentation
 
10
 * files (the "Software"), to deal in the Software without
 
11
 * restriction, including without limitation the rights to use, copy,
 
12
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 
13
 * of the Software, and to permit persons to whom the Software is
 
14
 * furnished to do so, subject to the following conditions:
 
15
 *
 
16
 * The above copyright notice and this permission notice shall be
 
17
 * included in all copies or substantial portions of the Software.
 
18
 *
 
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
20
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
21
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
22
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 
23
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 
24
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
25
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
26
 * SOFTWARE.
 
27
 *
 
28
 * Authors:
 
29
 *   Robert Bragg <robert@linux.intel.com>
 
30
 */
 
31
 
 
32
#ifdef HAVE_CONFIG_H
 
33
#include "cogl-config.h"
 
34
#endif
 
35
 
 
36
#include <glib.h>
 
37
#include <string.h>
 
38
 
 
39
#include "cogl-util.h"
 
40
#include "cogl-types.h"
 
41
#include "cogl-object-private.h"
 
42
#include "cogl-gtype-private.h"
 
43
 
 
44
COGL_GTYPE_DEFINE_BASE_CLASS (Object, object);
 
45
 
 
46
void *
 
47
cogl_object_ref (void *object)
 
48
{
 
49
  CoglObject *obj = object;
 
50
 
 
51
  _COGL_RETURN_VAL_IF_FAIL (object != NULL, NULL);
 
52
 
 
53
  obj->ref_count++;
 
54
  return object;
 
55
}
 
56
 
 
57
CoglHandle
 
58
cogl_handle_ref (CoglHandle handle)
 
59
{
 
60
  return cogl_object_ref (handle);
 
61
}
 
62
 
 
63
void
 
64
_cogl_object_default_unref (void *object)
 
65
{
 
66
  CoglObject *obj = object;
 
67
 
 
68
  _COGL_RETURN_IF_FAIL (object != NULL);
 
69
  _COGL_RETURN_IF_FAIL (obj->ref_count > 0);
 
70
 
 
71
  if (--obj->ref_count < 1)
 
72
    {
 
73
      void (*free_func)(void *obj);
 
74
 
 
75
      if (obj->n_user_data_entries)
 
76
        {
 
77
          int i;
 
78
          int count = MIN (obj->n_user_data_entries,
 
79
                           COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES);
 
80
 
 
81
          for (i = 0; i < count; i++)
 
82
            {
 
83
              CoglUserDataEntry *entry = &obj->user_data_entry[i];
 
84
              if (entry->destroy)
 
85
                entry->destroy (entry->user_data, obj);
 
86
            }
 
87
 
 
88
          if (obj->user_data_array != NULL)
 
89
            {
 
90
              for (i = 0; i < obj->user_data_array->len; i++)
 
91
                {
 
92
                  CoglUserDataEntry *entry =
 
93
                    &g_array_index (obj->user_data_array,
 
94
                                    CoglUserDataEntry, i);
 
95
 
 
96
                  if (entry->destroy)
 
97
                    entry->destroy (entry->user_data, obj);
 
98
                }
 
99
              g_array_free (obj->user_data_array, TRUE);
 
100
            }
 
101
        }
 
102
 
 
103
      COGL_OBJECT_DEBUG_FREE (obj);
 
104
      free_func = obj->klass->virt_free;
 
105
      free_func (obj);
 
106
    }
 
107
}
 
108
 
 
109
void
 
110
cogl_object_unref (void *obj)
 
111
{
 
112
  void (* unref_func) (void *) = ((CoglObject *) obj)->klass->virt_unref;
 
113
  unref_func (obj);
 
114
}
 
115
 
 
116
void
 
117
cogl_handle_unref (CoglHandle handle)
 
118
{
 
119
  cogl_object_unref (handle);
 
120
}
 
121
 
 
122
GType
 
123
cogl_handle_get_type (void)
 
124
{
 
125
  static GType our_type = 0;
 
126
 
 
127
  /* XXX: We are keeping the "CoglHandle" name for now incase it would
 
128
   * break bindings to change to "CoglObject" */
 
129
  if (G_UNLIKELY (our_type == 0))
 
130
    our_type = g_boxed_type_register_static (g_intern_static_string ("CoglHandle"),
 
131
                                             (GBoxedCopyFunc) cogl_object_ref,
 
132
                                             (GBoxedFreeFunc) cogl_object_unref);
 
133
 
 
134
  return our_type;
 
135
}
 
136
 
 
137
/* XXX: Unlike for cogl_object_get_user_data this code will return
 
138
 * an empty entry if available and no entry for the given key can be
 
139
 * found. */
 
140
static CoglUserDataEntry *
 
141
_cogl_object_find_entry (CoglObject *object, CoglUserDataKey *key)
 
142
{
 
143
  CoglUserDataEntry *entry = NULL;
 
144
  int count;
 
145
  int i;
 
146
 
 
147
  count = MIN (object->n_user_data_entries,
 
148
               COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES);
 
149
 
 
150
  for (i = 0; i < count; i++)
 
151
    {
 
152
      CoglUserDataEntry *current = &object->user_data_entry[i];
 
153
      if (current->key == key)
 
154
        return current;
 
155
      if (current->user_data == NULL)
 
156
        entry = current;
 
157
    }
 
158
 
 
159
  if (G_UNLIKELY (object->user_data_array != NULL))
 
160
    {
 
161
      for (i = 0; i < object->user_data_array->len; i++)
 
162
        {
 
163
          CoglUserDataEntry *current =
 
164
            &g_array_index (object->user_data_array, CoglUserDataEntry, i);
 
165
 
 
166
          if (current->key == key)
 
167
            return current;
 
168
          if (current->user_data == NULL)
 
169
            entry = current;
 
170
        }
 
171
    }
 
172
 
 
173
  return entry;
 
174
}
 
175
 
 
176
void
 
177
_cogl_object_set_user_data (CoglObject *object,
 
178
                            CoglUserDataKey *key,
 
179
                            void *user_data,
 
180
                            CoglUserDataDestroyInternalCallback destroy)
 
181
{
 
182
  CoglUserDataEntry new_entry;
 
183
  CoglUserDataEntry *entry;
 
184
 
 
185
  if (user_data)
 
186
    {
 
187
      new_entry.key = key;
 
188
      new_entry.user_data = user_data;
 
189
      new_entry.destroy = destroy;
 
190
    }
 
191
  else
 
192
    memset (&new_entry, 0, sizeof (new_entry));
 
193
 
 
194
  entry = _cogl_object_find_entry (object, key);
 
195
  if (entry)
 
196
    {
 
197
      if (G_LIKELY (entry->destroy))
 
198
        entry->destroy (entry->user_data, object);
 
199
    }
 
200
  else
 
201
    {
 
202
      /* NB: Setting a value of NULL is documented to delete the
 
203
       * corresponding entry so we can return immediately in this
 
204
       * case. */
 
205
      if (user_data == NULL)
 
206
        return;
 
207
 
 
208
      if (G_LIKELY (object->n_user_data_entries <
 
209
                    COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES))
 
210
        entry = &object->user_data_entry[object->n_user_data_entries++];
 
211
      else
 
212
        {
 
213
          if (G_UNLIKELY (object->user_data_array == NULL))
 
214
            {
 
215
              object->user_data_array =
 
216
                g_array_new (FALSE, FALSE, sizeof (CoglUserDataEntry));
 
217
            }
 
218
 
 
219
          g_array_set_size (object->user_data_array,
 
220
                            object->user_data_array->len + 1);
 
221
          entry =
 
222
            &g_array_index (object->user_data_array, CoglUserDataEntry,
 
223
                            object->user_data_array->len - 1);
 
224
 
 
225
          object->n_user_data_entries++;
 
226
        }
 
227
    }
 
228
 
 
229
  *entry = new_entry;
 
230
}
 
231
 
 
232
void
 
233
cogl_object_set_user_data (CoglObject *object,
 
234
                           CoglUserDataKey *key,
 
235
                           void *user_data,
 
236
                           CoglUserDataDestroyCallback destroy)
 
237
{
 
238
  _cogl_object_set_user_data (object, key, user_data,
 
239
                              (CoglUserDataDestroyInternalCallback)destroy);
 
240
}
 
241
 
 
242
void *
 
243
cogl_object_get_user_data (CoglObject *object, CoglUserDataKey *key)
 
244
{
 
245
  int count;
 
246
  int i;
 
247
 
 
248
  count = MIN (object->n_user_data_entries,
 
249
               COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES);
 
250
 
 
251
  for (i = 0; i < count; i++)
 
252
    {
 
253
      CoglUserDataEntry *entry = &object->user_data_entry[i];
 
254
      if (entry->key == key)
 
255
        return entry->user_data;
 
256
    }
 
257
 
 
258
  if (object->user_data_array != NULL)
 
259
    {
 
260
      for (i = 0; i < object->user_data_array->len; i++)
 
261
        {
 
262
          CoglUserDataEntry *entry =
 
263
            &g_array_index (object->user_data_array, CoglUserDataEntry, i);
 
264
 
 
265
          if (entry->key == key)
 
266
            return entry->user_data;
 
267
        }
 
268
    }
 
269
 
 
270
  return NULL;
 
271
}
 
272
 
 
273
void
 
274
cogl_debug_object_foreach_type (CoglDebugObjectForeachTypeCallback func,
 
275
                                void *user_data)
 
276
{
 
277
  GHashTableIter iter;
 
278
  unsigned long *instance_count;
 
279
  CoglDebugObjectTypeInfo info;
 
280
 
 
281
  g_hash_table_iter_init (&iter, _cogl_debug_instances);
 
282
  while (g_hash_table_iter_next (&iter,
 
283
                                 (void *) &info.name,
 
284
                                 (void *) &instance_count))
 
285
    {
 
286
      info.instance_count = *instance_count;
 
287
      func (&info, user_data);
 
288
    }
 
289
}
 
290
 
 
291
static void
 
292
print_instances_cb (const CoglDebugObjectTypeInfo *info,
 
293
                    void *user_data)
 
294
{
 
295
  g_print ("\t%s: %lu\n", info->name, info->instance_count);
 
296
}
 
297
 
 
298
void
 
299
cogl_debug_object_print_instances (void)
 
300
{
 
301
  g_print ("Cogl instances:\n");
 
302
 
 
303
  cogl_debug_object_foreach_type (print_instances_cb, NULL);
 
304
}