4 * An object oriented GL/GLES Abstraction/Utility Layer
6 * Copyright (C) 2008,2009,2010 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see
20 * <http://www.gnu.org/licenses/>.
23 * Robert Bragg <robert@linux.intel.com>
26 #ifndef __COGL_OBJECT_PRIVATE_H
27 #define __COGL_OBJECT_PRIVATE_H
31 #include "cogl-types.h"
32 #include "cogl-object.h"
33 #include "cogl-debug.h"
35 /* For compatability until all components have been converted */
36 typedef struct _CoglObjectClass CoglHandleClass;
37 typedef struct _CoglObject CoglHandleObject;
39 /* XXX: sadly we didn't fully consider when we copied the cairo API
40 * for _set_user_data that the callback doesn't get a pointer to the
41 * instance which is desired in most cases. This means you tend to end
42 * up creating micro allocations for the private data just so you can
43 * pair up the data of interest with the original instance for
44 * identification when it is later destroyed.
46 * Internally we use a small hack to avoid needing these micro
47 * allocations by actually passing the instance as a second argument
49 typedef void (*CoglUserDataDestroyInternalCallback) (void *user_data,
52 typedef struct _CoglObjectClass
59 #define COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES 2
65 CoglUserDataDestroyInternalCallback destroy;
68 /* All Cogl objects inherit from this base object by adding a member:
72 * at the top of its main structure. This structure is initialized
73 * when you call _cogl_#type_name#_object_new (new_object);
77 CoglObjectClass *klass;
79 CoglUserDataEntry user_data_entry[
80 COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES];
81 GArray *user_data_array;
82 int n_user_data_entries;
84 unsigned int ref_count;
87 /* Helper macro to encapsulate the common code for COGL reference
90 #ifdef COGL_OBJECT_DEBUG
92 #define _COGL_OBJECT_DEBUG_NEW(type_name, obj) \
93 COGL_NOTE (HANDLE, "COGL " G_STRINGIFY (type_name) " NEW %p %i", \
94 (obj), (obj)->ref_count)
96 #define _COGL_OBJECT_DEBUG_REF(type_name, object) G_STMT_START { \
97 CoglObject *__obj = (CoglObject *)object; \
98 COGL_NOTE (HANDLE, "COGL %s REF %p %i", \
99 (__obj)->klass->name, \
100 (__obj), (__obj)->ref_count); } G_STMT_END
102 #define _COGL_OBJECT_DEBUG_UNREF(type_name, object) G_STMT_START { \
103 CoglObject *__obj = (CoglObject *)object; \
104 COGL_NOTE (HANDLE, "COGL %s UNREF %p %i", \
105 (__obj)->klass->name, \
106 (__obj), (__obj)->ref_count - 1); } G_STMT_END
108 #define COGL_OBJECT_DEBUG_FREE(obj) \
109 COGL_NOTE (HANDLE, "COGL %s FREE %p", \
110 (obj)->klass->name, (obj))
112 #else /* !COGL_OBJECT_DEBUG */
114 #define _COGL_OBJECT_DEBUG_NEW(type_name, obj)
115 #define _COGL_OBJECT_DEBUG_REF(type_name, obj)
116 #define _COGL_OBJECT_DEBUG_UNREF(type_name, obj)
117 #define COGL_OBJECT_DEBUG_FREE(obj)
119 #endif /* COGL_OBJECT_DEBUG */
121 /* For temporary compatability */
122 #define _COGL_HANDLE_DEBUG_NEW _COGL_OBJECT_DEBUG_NEW
123 #define _COGL_HANDLE_DEBUG_REF _COGL_OBJECT_DEBUG_REF
124 #define _COGL_HANDLE_DEBUG_UNREF _COGL_OBJECT_DEBUG_UNREF
125 #define COGL_HANDLE_DEBUG_FREE COGL_OBJECT_DEBUG_FREE
127 #define COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \
129 CoglObjectClass _cogl_##type_name##_class; \
130 static unsigned long _cogl_object_##type_name##_count; \
133 _cogl_object_##type_name##_inc (void) \
135 _cogl_object_##type_name##_count++; \
139 _cogl_object_##type_name##_dec (void) \
141 _cogl_object_##type_name##_count--; \
145 _cogl_object_##type_name##_indirect_free (CoglObject *obj) \
147 _cogl_##type_name##_free ((Cogl##TypeName *) obj); \
148 _cogl_object_##type_name##_dec (); \
151 static Cogl##TypeName * \
152 _cogl_##type_name##_object_new (Cogl##TypeName *new_obj) \
154 CoglObject *obj = (CoglObject *)&new_obj->_parent; \
155 obj->ref_count = 0; \
156 cogl_object_ref (obj); \
157 obj->n_user_data_entries = 0; \
158 obj->user_data_array = NULL; \
160 obj->klass = &_cogl_##type_name##_class; \
161 if (!obj->klass->virt_free) \
163 _cogl_object_##type_name##_count = 0; \
165 if (_cogl_debug_instances == NULL) \
166 _cogl_debug_instances = \
167 g_hash_table_new (g_str_hash, g_str_equal); \
169 obj->klass->virt_free = \
170 _cogl_object_##type_name##_indirect_free; \
171 obj->klass->virt_unref = \
172 _cogl_object_default_unref; \
173 obj->klass->name = "Cogl"#TypeName, \
175 g_hash_table_insert (_cogl_debug_instances, \
176 (void *) obj->klass->name, \
177 &_cogl_object_##type_name##_count); \
182 _cogl_object_##type_name##_inc (); \
183 _COGL_OBJECT_DEBUG_NEW (TypeName, obj); \
187 #define COGL_OBJECT_DEFINE_WITH_CODE(TypeName, type_name, code) \
189 COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \
192 cogl_is_##type_name (void *object) \
194 CoglObject *obj = object; \
196 if (object == NULL) \
199 return obj->klass == &_cogl_##type_name##_class; \
202 #define COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \
204 COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \
207 _cogl_is_##type_name (void *object) \
209 CoglObject *obj = object; \
211 if (object == NULL) \
214 return obj->klass == &_cogl_##type_name##_class; \
217 #define COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING(type_name) \
219 void * G_GNUC_DEPRECATED \
220 cogl_##type_name##_ref (void *object) \
222 if (!cogl_is_##type_name (object)) \
225 _COGL_OBJECT_DEBUG_REF (TypeName, object); \
227 cogl_handle_ref (object); \
232 void G_GNUC_DEPRECATED \
233 cogl_##type_name##_unref (void *object) \
235 if (!cogl_is_##type_name (object)) \
237 g_warning (G_STRINGIFY (cogl_##type_name##_unref) \
238 ": Ignoring unref of Cogl handle " \
239 "due to type mismatch"); \
243 _COGL_OBJECT_DEBUG_UNREF (TypeName, object); \
245 cogl_handle_unref (object); \
248 #define COGL_OBJECT_DEFINE(TypeName, type_name) \
249 COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
251 #define COGL_OBJECT_INTERNAL_DEFINE(TypeName, type_name) \
252 COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
254 /* For temporary compatability */
255 #define COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \
257 COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, code) \
259 static Cogl##TypeName * \
260 _cogl_##type_name##_handle_new (CoglHandle handle) \
262 return _cogl_##type_name##_object_new (handle); \
265 #define COGL_HANDLE_DEFINE_WITH_CODE(TypeName, type_name, code) \
267 COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, code) \
269 static Cogl##TypeName * \
270 _cogl_##type_name##_handle_new (CoglHandle handle) \
272 return _cogl_##type_name##_object_new (handle); \
275 #define COGL_HANDLE_INTERNAL_DEFINE(TypeName, type_name) \
276 COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
278 #define COGL_HANDLE_DEFINE(TypeName, type_name) \
279 COGL_HANDLE_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
282 _cogl_object_set_user_data (CoglObject *object,
283 CoglUserDataKey *key,
285 CoglUserDataDestroyInternalCallback destroy);
288 _cogl_object_default_unref (void *obj);
290 #endif /* __COGL_OBJECT_PRIVATE_H */