2010-05-27 17:24:56 -04:00
|
|
|
/*
|
|
|
|
* Cogl
|
|
|
|
*
|
|
|
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
|
|
|
*
|
|
|
|
* Copyright (C) 2008,2009,2010 Intel Corporation.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2010-06-01 14:27:07 -04:00
|
|
|
* License along with this library. If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
2010-05-27 17:24:56 -04:00
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Robert Bragg <robert@linux.intel.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __COGL_OBJECT_PRIVATE_H
|
|
|
|
#define __COGL_OBJECT_PRIVATE_H
|
|
|
|
|
2010-07-03 16:10:05 -04:00
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#include "cogl-types.h"
|
2010-05-27 17:24:56 -04:00
|
|
|
#include "cogl-object.h"
|
2010-09-17 12:18:09 -04:00
|
|
|
#include "cogl-debug.h"
|
2010-05-27 17:24:56 -04:00
|
|
|
|
|
|
|
/* For compatability until all components have been converted */
|
|
|
|
typedef struct _CoglObjectClass CoglHandleClass;
|
|
|
|
typedef struct _CoglObject CoglHandleObject;
|
|
|
|
|
2011-01-12 15:37:53 -05:00
|
|
|
/* XXX: sadly we didn't fully consider when we copied the cairo API
|
|
|
|
* for _set_user_data that the callback doesn't get a pointer to the
|
|
|
|
* instance which is desired in most cases. This means you tend to end
|
|
|
|
* up creating micro allocations for the private data just so you can
|
|
|
|
* pair up the data of interest with the original instance for
|
|
|
|
* identification when it is later destroyed.
|
|
|
|
*
|
|
|
|
* Internally we use a small hack to avoid needing these micro
|
|
|
|
* allocations by actually passing the instance as a second argument
|
|
|
|
* to the callback */
|
|
|
|
typedef void (*CoglUserDataDestroyInternalCallback) (void *user_data,
|
|
|
|
void *instance);
|
|
|
|
|
2010-05-27 17:24:56 -04:00
|
|
|
typedef struct _CoglObjectClass
|
|
|
|
{
|
2012-01-24 11:24:26 -05:00
|
|
|
const char *name;
|
|
|
|
void *virt_free;
|
2012-01-24 11:36:16 -05:00
|
|
|
void *virt_unref;
|
2010-05-27 17:24:56 -04:00
|
|
|
} CoglObjectClass;
|
|
|
|
|
|
|
|
#define COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES 2
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
CoglUserDataKey *key;
|
|
|
|
void *user_data;
|
2011-01-12 15:37:53 -05:00
|
|
|
CoglUserDataDestroyInternalCallback destroy;
|
2010-05-27 17:24:56 -04:00
|
|
|
} CoglUserDataEntry;
|
|
|
|
|
|
|
|
/* All Cogl objects inherit from this base object by adding a member:
|
|
|
|
*
|
|
|
|
* CoglObject _parent;
|
|
|
|
*
|
|
|
|
* at the top of its main structure. This structure is initialized
|
|
|
|
* when you call _cogl_#type_name#_object_new (new_object);
|
|
|
|
*/
|
|
|
|
struct _CoglObject
|
|
|
|
{
|
2012-01-24 10:55:27 -05:00
|
|
|
CoglObjectClass *klass;
|
2010-05-27 17:24:56 -04:00
|
|
|
|
|
|
|
CoglUserDataEntry user_data_entry[
|
|
|
|
COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES];
|
|
|
|
GArray *user_data_array;
|
|
|
|
int n_user_data_entries;
|
|
|
|
|
2012-01-24 10:55:27 -05:00
|
|
|
unsigned int ref_count;
|
2010-05-27 17:24:56 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Helper macro to encapsulate the common code for COGL reference
|
|
|
|
counted objects */
|
|
|
|
|
|
|
|
#ifdef COGL_OBJECT_DEBUG
|
|
|
|
|
2010-06-01 14:27:07 -04:00
|
|
|
#define _COGL_OBJECT_DEBUG_NEW(type_name, obj) \
|
2010-05-27 17:24:56 -04:00
|
|
|
COGL_NOTE (HANDLE, "COGL " G_STRINGIFY (type_name) " NEW %p %i", \
|
2010-06-01 14:27:07 -04:00
|
|
|
(obj), (obj)->ref_count)
|
2010-05-27 17:24:56 -04:00
|
|
|
|
|
|
|
#define _COGL_OBJECT_DEBUG_REF(type_name, object) G_STMT_START { \
|
|
|
|
CoglObject *__obj = (CoglObject *)object; \
|
2010-06-01 14:27:07 -04:00
|
|
|
COGL_NOTE (HANDLE, "COGL %s REF %p %i", \
|
2012-01-24 11:24:26 -05:00
|
|
|
(__obj)->klass->name, \
|
2010-05-27 17:24:56 -04:00
|
|
|
(__obj), (__obj)->ref_count); } G_STMT_END
|
|
|
|
|
|
|
|
#define _COGL_OBJECT_DEBUG_UNREF(type_name, object) G_STMT_START { \
|
2010-06-01 14:27:07 -04:00
|
|
|
CoglObject *__obj = (CoglObject *)object; \
|
|
|
|
COGL_NOTE (HANDLE, "COGL %s UNREF %p %i", \
|
2012-01-24 11:24:26 -05:00
|
|
|
(__obj)->klass->name, \
|
2010-05-27 17:24:56 -04:00
|
|
|
(__obj), (__obj)->ref_count - 1); } G_STMT_END
|
|
|
|
|
|
|
|
#define COGL_OBJECT_DEBUG_FREE(obj) \
|
|
|
|
COGL_NOTE (HANDLE, "COGL %s FREE %p", \
|
2012-01-24 11:24:26 -05:00
|
|
|
(obj)->klass->name, (obj))
|
2010-05-27 17:24:56 -04:00
|
|
|
|
|
|
|
#else /* !COGL_OBJECT_DEBUG */
|
|
|
|
|
|
|
|
#define _COGL_OBJECT_DEBUG_NEW(type_name, obj)
|
|
|
|
#define _COGL_OBJECT_DEBUG_REF(type_name, obj)
|
|
|
|
#define _COGL_OBJECT_DEBUG_UNREF(type_name, obj)
|
|
|
|
#define COGL_OBJECT_DEBUG_FREE(obj)
|
|
|
|
|
|
|
|
#endif /* COGL_OBJECT_DEBUG */
|
|
|
|
|
|
|
|
/* For temporary compatability */
|
|
|
|
#define _COGL_HANDLE_DEBUG_NEW _COGL_OBJECT_DEBUG_NEW
|
|
|
|
#define _COGL_HANDLE_DEBUG_REF _COGL_OBJECT_DEBUG_REF
|
|
|
|
#define _COGL_HANDLE_DEBUG_UNREF _COGL_OBJECT_DEBUG_UNREF
|
|
|
|
#define COGL_HANDLE_DEBUG_FREE COGL_OBJECT_DEBUG_FREE
|
|
|
|
|
2011-06-10 13:44:09 -04:00
|
|
|
#define COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \
|
|
|
|
\
|
2012-01-24 11:24:26 -05:00
|
|
|
CoglObjectClass _cogl_##type_name##_class; \
|
2011-06-10 13:44:09 -04:00
|
|
|
static unsigned long _cogl_object_##type_name##_count; \
|
|
|
|
\
|
|
|
|
static inline void \
|
|
|
|
_cogl_object_##type_name##_inc (void) \
|
|
|
|
{ \
|
|
|
|
_cogl_object_##type_name##_count++; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static inline void \
|
|
|
|
_cogl_object_##type_name##_dec (void) \
|
|
|
|
{ \
|
|
|
|
_cogl_object_##type_name##_count--; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static void \
|
|
|
|
_cogl_object_##type_name##_indirect_free (CoglObject *obj) \
|
|
|
|
{ \
|
|
|
|
_cogl_##type_name##_free ((Cogl##TypeName *) obj); \
|
|
|
|
_cogl_object_##type_name##_dec (); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static Cogl##TypeName * \
|
|
|
|
_cogl_##type_name##_object_new (Cogl##TypeName *new_obj) \
|
|
|
|
{ \
|
|
|
|
CoglObject *obj = (CoglObject *)&new_obj->_parent; \
|
|
|
|
obj->ref_count = 0; \
|
|
|
|
cogl_object_ref (obj); \
|
|
|
|
obj->n_user_data_entries = 0; \
|
|
|
|
obj->user_data_array = NULL; \
|
|
|
|
\
|
|
|
|
obj->klass = &_cogl_##type_name##_class; \
|
2012-01-24 11:24:26 -05:00
|
|
|
if (!obj->klass->virt_free) \
|
2011-06-10 13:44:09 -04:00
|
|
|
{ \
|
2012-01-24 11:24:26 -05:00
|
|
|
_cogl_object_##type_name##_count = 0; \
|
|
|
|
\
|
|
|
|
if (_cogl_debug_instances == NULL) \
|
|
|
|
_cogl_debug_instances = \
|
|
|
|
g_hash_table_new (g_str_hash, g_str_equal); \
|
|
|
|
\
|
2011-06-10 13:44:09 -04:00
|
|
|
obj->klass->virt_free = \
|
|
|
|
_cogl_object_##type_name##_indirect_free; \
|
2012-01-24 11:36:16 -05:00
|
|
|
obj->klass->virt_unref = \
|
|
|
|
_cogl_object_default_unref; \
|
2012-01-24 11:24:26 -05:00
|
|
|
obj->klass->name = "Cogl"#TypeName, \
|
|
|
|
\
|
|
|
|
g_hash_table_insert (_cogl_debug_instances, \
|
|
|
|
(void *) obj->klass->name, \
|
|
|
|
&_cogl_object_##type_name##_count); \
|
|
|
|
\
|
|
|
|
{ code; } \
|
2011-06-10 13:44:09 -04:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
_cogl_object_##type_name##_inc (); \
|
|
|
|
_COGL_OBJECT_DEBUG_NEW (TypeName, obj); \
|
|
|
|
return new_obj; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
Cogl##TypeName * \
|
|
|
|
_cogl_##type_name##_pointer_from_handle (CoglHandle handle) \
|
|
|
|
{ \
|
|
|
|
return handle; \
|
2010-07-09 13:46:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#define COGL_OBJECT_DEFINE_WITH_CODE(TypeName, type_name, code) \
|
|
|
|
\
|
|
|
|
COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \
|
|
|
|
\
|
|
|
|
gboolean \
|
|
|
|
cogl_is_##type_name (void *object) \
|
|
|
|
{ \
|
|
|
|
CoglObject *obj = object; \
|
|
|
|
\
|
|
|
|
if (object == NULL) \
|
|
|
|
return FALSE; \
|
|
|
|
\
|
2012-01-24 11:24:26 -05:00
|
|
|
return obj->klass == &_cogl_##type_name##_class; \
|
2010-07-09 13:46:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#define COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \
|
|
|
|
\
|
|
|
|
COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \
|
|
|
|
\
|
|
|
|
gboolean \
|
|
|
|
_cogl_is_##type_name (void *object) \
|
|
|
|
{ \
|
|
|
|
CoglObject *obj = object; \
|
|
|
|
\
|
|
|
|
if (object == NULL) \
|
|
|
|
return FALSE; \
|
|
|
|
\
|
2012-01-24 11:24:26 -05:00
|
|
|
return obj->klass == &_cogl_##type_name##_class; \
|
2010-07-09 12:59:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#define COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING(type_name) \
|
2010-06-01 14:27:07 -04:00
|
|
|
\
|
|
|
|
void * G_GNUC_DEPRECATED \
|
|
|
|
cogl_##type_name##_ref (void *object) \
|
|
|
|
{ \
|
|
|
|
if (!cogl_is_##type_name (object)) \
|
|
|
|
return NULL; \
|
|
|
|
\
|
|
|
|
_COGL_OBJECT_DEBUG_REF (TypeName, object); \
|
|
|
|
\
|
2010-05-27 17:24:56 -04:00
|
|
|
cogl_handle_ref (object); \
|
2010-06-01 14:27:07 -04:00
|
|
|
\
|
|
|
|
return object; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void G_GNUC_DEPRECATED \
|
|
|
|
cogl_##type_name##_unref (void *object) \
|
|
|
|
{ \
|
|
|
|
if (!cogl_is_##type_name (object)) \
|
2010-05-27 17:24:56 -04:00
|
|
|
{ \
|
|
|
|
g_warning (G_STRINGIFY (cogl_##type_name##_unref) \
|
|
|
|
": Ignoring unref of Cogl handle " \
|
|
|
|
"due to type mismatch"); \
|
2010-06-01 14:27:07 -04:00
|
|
|
return; \
|
2010-05-27 17:24:56 -04:00
|
|
|
} \
|
2010-06-01 14:27:07 -04:00
|
|
|
\
|
|
|
|
_COGL_OBJECT_DEBUG_UNREF (TypeName, object); \
|
2010-05-27 17:24:56 -04:00
|
|
|
\
|
|
|
|
cogl_handle_unref (object); \
|
|
|
|
}
|
|
|
|
|
2010-06-11 08:44:27 -04:00
|
|
|
#define COGL_OBJECT_DEFINE(TypeName, type_name) \
|
|
|
|
COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
|
|
|
|
|
2010-07-09 13:46:31 -04:00
|
|
|
#define COGL_OBJECT_INTERNAL_DEFINE(TypeName, type_name) \
|
|
|
|
COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
|
|
|
|
|
2010-05-27 17:24:56 -04:00
|
|
|
/* For temporary compatability */
|
2010-07-09 13:46:31 -04:00
|
|
|
#define COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \
|
|
|
|
\
|
|
|
|
COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, code) \
|
|
|
|
\
|
|
|
|
static Cogl##TypeName * \
|
|
|
|
_cogl_##type_name##_handle_new (CoglHandle handle) \
|
|
|
|
{ \
|
|
|
|
return _cogl_##type_name##_object_new (handle); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define COGL_HANDLE_DEFINE_WITH_CODE(TypeName, type_name, code) \
|
|
|
|
\
|
|
|
|
COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, code) \
|
|
|
|
\
|
|
|
|
static Cogl##TypeName * \
|
|
|
|
_cogl_##type_name##_handle_new (CoglHandle handle) \
|
|
|
|
{ \
|
|
|
|
return _cogl_##type_name##_object_new (handle); \
|
2010-05-27 17:24:56 -04:00
|
|
|
}
|
|
|
|
|
2010-07-09 13:46:31 -04:00
|
|
|
#define COGL_HANDLE_INTERNAL_DEFINE(TypeName, type_name) \
|
|
|
|
COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
|
|
|
|
|
2010-06-11 08:44:27 -04:00
|
|
|
#define COGL_HANDLE_DEFINE(TypeName, type_name) \
|
|
|
|
COGL_HANDLE_DEFINE_WITH_CODE (TypeName, type_name, (void) 0)
|
|
|
|
|
2011-01-12 15:37:53 -05:00
|
|
|
void
|
|
|
|
_cogl_object_set_user_data (CoglObject *object,
|
|
|
|
CoglUserDataKey *key,
|
|
|
|
void *user_data,
|
|
|
|
CoglUserDataDestroyInternalCallback destroy);
|
|
|
|
|
2012-01-24 11:36:16 -05:00
|
|
|
void
|
|
|
|
_cogl_object_default_unref (void *obj);
|
|
|
|
|
2010-05-27 17:24:56 -04:00
|
|
|
#endif /* __COGL_OBJECT_PRIVATE_H */
|
|
|
|
|