cleanup specfile for packaging
[profile/ivi/cogl.git] / cogl / cogl-object-private.h
1 /*
2  * Cogl
3  *
4  * An object oriented GL/GLES Abstraction/Utility Layer
5  *
6  * Copyright (C) 2008,2009,2010 Intel Corporation.
7  *
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.
12  *
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.
17  *
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/>.
21  *
22  * Authors:
23  *   Robert Bragg <robert@linux.intel.com>
24  */
25
26 #ifndef __COGL_OBJECT_PRIVATE_H
27 #define __COGL_OBJECT_PRIVATE_H
28
29 #include <glib.h>
30
31 #include "cogl-types.h"
32 #include "cogl-object.h"
33 #include "cogl-debug.h"
34
35 /* For compatability until all components have been converted */
36 typedef struct _CoglObjectClass CoglHandleClass;
37 typedef struct _CoglObject      CoglHandleObject;
38
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.
45  *
46  * Internally we use a small hack to avoid needing these micro
47  * allocations by actually passing the instance as a second argument
48  * to the callback */
49 typedef void (*CoglUserDataDestroyInternalCallback) (void *user_data,
50                                                      void *instance);
51
52 typedef struct _CoglObjectClass
53 {
54   const char *name;
55   void *virt_free;
56   void *virt_unref;
57 } CoglObjectClass;
58
59 #define COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES 2
60
61 typedef struct
62 {
63   CoglUserDataKey *key;
64   void *user_data;
65   CoglUserDataDestroyInternalCallback destroy;
66 } CoglUserDataEntry;
67
68 /* All Cogl objects inherit from this base object by adding a member:
69  *
70  *   CoglObject _parent;
71  *
72  * at the top of its main structure. This structure is initialized
73  * when you call _cogl_#type_name#_object_new (new_object);
74  */
75 struct _CoglObject
76 {
77   CoglObjectClass  *klass;
78
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;
83
84   unsigned int      ref_count;
85 };
86
87 /* Helper macro to encapsulate the common code for COGL reference
88    counted objects */
89
90 #ifdef COGL_OBJECT_DEBUG
91
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)
95
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
101
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
107
108 #define COGL_OBJECT_DEBUG_FREE(obj)                                     \
109   COGL_NOTE (HANDLE, "COGL %s FREE %p",                                 \
110              (obj)->klass->name, (obj))
111
112 #else /* !COGL_OBJECT_DEBUG */
113
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)
118
119 #endif /* COGL_OBJECT_DEBUG */
120
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
126
127 #define COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code)  \
128                                                                         \
129 CoglObjectClass _cogl_##type_name##_class;                              \
130 static unsigned long _cogl_object_##type_name##_count;                  \
131                                                                         \
132 static inline void                                                      \
133 _cogl_object_##type_name##_inc (void)                                   \
134 {                                                                       \
135   _cogl_object_##type_name##_count++;                                   \
136 }                                                                       \
137                                                                         \
138 static inline void                                                      \
139 _cogl_object_##type_name##_dec (void)                                   \
140 {                                                                       \
141   _cogl_object_##type_name##_count--;                                   \
142 }                                                                       \
143                                                                         \
144 static void                                                             \
145 _cogl_object_##type_name##_indirect_free (CoglObject *obj)              \
146 {                                                                       \
147   _cogl_##type_name##_free ((Cogl##TypeName *) obj);                    \
148   _cogl_object_##type_name##_dec ();                                    \
149 }                                                                       \
150                                                                         \
151 static Cogl##TypeName *                                                 \
152 _cogl_##type_name##_object_new (Cogl##TypeName *new_obj)                \
153 {                                                                       \
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;                                          \
159                                                                         \
160   obj->klass = &_cogl_##type_name##_class;                              \
161   if (!obj->klass->virt_free)                                           \
162     {                                                                   \
163       _cogl_object_##type_name##_count = 0;                             \
164                                                                         \
165       if (_cogl_debug_instances == NULL)                                \
166         _cogl_debug_instances =                                         \
167           g_hash_table_new (g_str_hash, g_str_equal);                   \
168                                                                         \
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,                               \
174                                                                         \
175       g_hash_table_insert (_cogl_debug_instances,                       \
176                            (void *) obj->klass->name,                   \
177                            &_cogl_object_##type_name##_count);          \
178                                                                         \
179       { code; }                                                         \
180     }                                                                   \
181                                                                         \
182   _cogl_object_##type_name##_inc ();                                    \
183   _COGL_OBJECT_DEBUG_NEW (TypeName, obj);                               \
184   return new_obj;                                                       \
185 }
186
187 #define COGL_OBJECT_DEFINE_WITH_CODE(TypeName, type_name, code)         \
188                                                                         \
189 COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code)          \
190                                                                         \
191 gboolean                                                                \
192 cogl_is_##type_name (void *object)                                      \
193 {                                                                       \
194   CoglObject *obj = object;                                             \
195                                                                         \
196   if (object == NULL)                                                   \
197     return FALSE;                                                       \
198                                                                         \
199   return obj->klass == &_cogl_##type_name##_class;                      \
200 }
201
202 #define COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \
203                                                                         \
204 COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code)          \
205                                                                         \
206 gboolean                                                                \
207 _cogl_is_##type_name (void *object)                                     \
208 {                                                                       \
209   CoglObject *obj = object;                                             \
210                                                                         \
211   if (object == NULL)                                                   \
212     return FALSE;                                                       \
213                                                                         \
214   return obj->klass == &_cogl_##type_name##_class;                      \
215 }
216
217 #define COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING(type_name)   \
218                                                                 \
219 void * G_GNUC_DEPRECATED                                        \
220 cogl_##type_name##_ref (void *object)                           \
221 {                                                               \
222   if (!cogl_is_##type_name (object))                            \
223     return NULL;                                                \
224                                                                 \
225   _COGL_OBJECT_DEBUG_REF (TypeName, object);                    \
226                                                                 \
227   cogl_handle_ref (object);                                     \
228                                                                 \
229   return object;                                                \
230 }                                                               \
231                                                                 \
232 void G_GNUC_DEPRECATED                                          \
233 cogl_##type_name##_unref (void *object)                         \
234 {                                                               \
235   if (!cogl_is_##type_name (object))                            \
236     {                                                           \
237       g_warning (G_STRINGIFY (cogl_##type_name##_unref)         \
238                  ": Ignoring unref of Cogl handle "             \
239                  "due to type mismatch");                       \
240       return;                                                   \
241     }                                                           \
242                                                                 \
243   _COGL_OBJECT_DEBUG_UNREF (TypeName, object);                  \
244                                                                 \
245   cogl_handle_unref (object);                                   \
246 }
247
248 #define COGL_OBJECT_DEFINE(TypeName, type_name)                 \
249   COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
250
251 #define COGL_OBJECT_INTERNAL_DEFINE(TypeName, type_name)         \
252   COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
253
254 /* For temporary compatability */
255 #define COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \
256                                                                          \
257 COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, code)        \
258                                                                          \
259 static Cogl##TypeName *                                                  \
260 _cogl_##type_name##_handle_new (CoglHandle handle)                       \
261 {                                                                        \
262   return _cogl_##type_name##_object_new (handle);                        \
263 }
264
265 #define COGL_HANDLE_DEFINE_WITH_CODE(TypeName, type_name, code)          \
266                                                                          \
267 COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, code)                 \
268                                                                          \
269 static Cogl##TypeName *                                                  \
270 _cogl_##type_name##_handle_new (CoglHandle handle)                       \
271 {                                                                        \
272   return _cogl_##type_name##_object_new (handle);                        \
273 }
274
275 #define COGL_HANDLE_INTERNAL_DEFINE(TypeName, type_name)        \
276   COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
277
278 #define COGL_HANDLE_DEFINE(TypeName, type_name)                 \
279   COGL_HANDLE_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
280
281 void
282 _cogl_object_set_user_data (CoglObject *object,
283                             CoglUserDataKey *key,
284                             void *user_data,
285                             CoglUserDataDestroyInternalCallback destroy);
286
287 void
288 _cogl_object_default_unref (void *obj);
289
290 #endif /* __COGL_OBJECT_PRIVATE_H */
291