From ed272213f002bde9ae947f0dea9aea343bd4d795 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Wed, 1 Apr 2009 17:16:44 +0100 Subject: [PATCH] [cogl-handle] Optimize how we define cogl handles The cogl_is_* functions were showing up quite high on profiles due to iterating through arrays of cogl handles. This does away with all the handle arrays and implements a simple struct inheritance scheme. All cogl objects now add a CoglHandleObject _parent; member to their main structures. The base object includes 2 members a.t.m; a ref_count, and a klass pointer. The klass in turn gives you a type and virtual function for freeing objects of that type. Each handle type has a _cogl_##handle_type##_get_type () function automatically defined which returns a GQuark of the handle type, so now implementing the cogl_is_* funcs is just a case of comparing with obj->klass->type. Another outcome of the re-work is that cogl_handle_{ref,unref} are also much more efficient, and no longer need extending for each handle type added to cogl. The cogl_##handle_type##_{ref,unref} functions are now deprecated and are no longer used internally to Clutter or Cogl. Potentially we can remove them completely before 1.0. --- common/cogl-handle.h | 165 ++++++++++++++-------------- common/cogl-material-private.h | 5 +- common/cogl-material.c | 31 +++--- common/cogl-util.c | 45 +++----- common/cogl-vertex-buffer-private.h | 7 +- common/cogl-vertex-buffer.c | 7 +- gl/cogl-context.c | 25 +---- gl/cogl-context.h | 13 --- gl/cogl-fbo.c | 5 +- gl/cogl-fbo.h | 6 +- gl/cogl-program.c | 5 +- gl/cogl-program.h | 4 +- gl/cogl-shader-private.h | 4 +- gl/cogl-shader.c | 5 +- gl/cogl-texture-private.h | 3 +- gl/cogl-texture.c | 16 +-- gles/cogl-context.c | 25 +---- gles/cogl-context.h | 13 --- gles/cogl-fbo.c | 5 +- gles/cogl-fbo.h | 6 +- gles/cogl-program.c | 9 +- gles/cogl-program.h | 3 +- gles/cogl-shader-private.h | 4 +- gles/cogl-shader.c | 5 +- gles/cogl-texture-private.h | 3 +- gles/cogl-texture.c | 16 +-- 26 files changed, 162 insertions(+), 273 deletions(-) diff --git a/common/cogl-handle.h b/common/cogl-handle.h index 79deb7f8c..55e8ecd26 100644 --- a/common/cogl-handle.h +++ b/common/cogl-handle.h @@ -26,82 +26,92 @@ #ifndef __COGL_HANDLE_H #define __COGL_HANDLE_H +typedef struct _CoglHandleClass +{ + GQuark type; + void *virt_free; +} CoglHandleClass; + +/* All Cogl objects inherit from this base object by adding a member: + * + * CoglHandleObject _parent; + * + * at the top of its main structure. This structure is initialized + * when you call _cogl_#type_name#_handle_new (new_object); + */ +typedef struct _CoglHandleObject +{ + guint ref_count; + CoglHandleClass *klass; +} CoglHandleObject; + /* Helper macro to encapsulate the common code for COGL reference counted handles */ #if COGL_DEBUG -#define COGL_HANDLE_DEBUG_NEW(type_name, obj) \ +#define _COGL_HANDLE_DEBUG_NEW(type_name, obj) \ printf ("COGL " G_STRINGIFY (type_name) " NEW %p %i\n", \ (obj), (obj)->ref_count) -#define COGL_HANDLE_DEBUG_REF(type_name, obj) \ - printf ("COGL " G_STRINGIFY (type_name) " REF %p %i\n", \ - (obj), (obj)->ref_count) +#define _COGL_HANDLE_DEBUG_REF(type_name, handle) \ + do { \ + CoglHandleObject *obj = (CoglHandleObject *)handle; \ + printf ("COGL %s REF %p %i\n", \ + g_quark_to_string ((obj)->klass->type), \ + (obj), (obj)->ref_count) \ + } while (0) -#define COGL_HANDLE_DEBUG_UNREF(type_name, obj) \ - printf ("COGL " G_STRINGIFY (type_name) " UNREF %p %i\n", \ - (obj), (obj)->ref_count - 1) +#define _COGL_HANDLE_DEBUG_UNREF(type_name, handle) \ + do { \ + CoglHandleObject *obj = (CoglHandleObject *)handle; \ + printf ("COGL %s UNREF %p %i\n", \ + g_quark_to_string ((obj)->klass->type), \ + (obj), (obj)->ref_count - 1) + } while (0) -#define COGL_HANDLE_DEBUG_FREE(type_name, obj) \ - printf ("COGL " G_STRINGIFY (type_name) " FREE %p\n", (obj)) +#define COGL_HANDLE_DEBUG_FREE(obj) \ + printf ("COGL %s FREE %p\n", \ + g_quark_to_string ((obj)->klass->type), (obj)) \ #else /* COGL_DEBUG */ -#define COGL_HANDLE_DEBUG_NEW(type_name, obj) (void) 0 -#define COGL_HANDLE_DEBUG_REF(type_name, obj) (void) 0 -#define COGL_HANDLE_DEBUG_UNREF(type_name, obj) (void) 0 -#define COGL_HANDLE_DEBUG_FREE(type_name, obj) (void) 0 +#define _COGL_HANDLE_DEBUG_NEW(type_name, obj) +#define _COGL_HANDLE_DEBUG_REF(type_name, obj) +#define _COGL_HANDLE_DEBUG_UNREF(type_name, obj) +#define COGL_HANDLE_DEBUG_FREE(obj) #endif /* COGL_DEBUG */ -#define COGL_HANDLE_DEFINE(TypeName, type_name, handle_array) \ +#define COGL_HANDLE_DEFINE(TypeName, type_name) \ \ - static gint \ - _cogl_##type_name##_handle_find (CoglHandle handle) \ - { \ - gint i; \ + static CoglHandleClass _cogl_##type_name##_class; \ \ - _COGL_GET_CONTEXT (ctx, -1); \ - \ - if (ctx->handle_array == NULL) \ - return -1; \ - \ - for (i=0; i < ctx->handle_array->len; ++i) \ - if (g_array_index (ctx->handle_array, \ - CoglHandle, i) == handle) \ - return i; \ - \ - return -1; \ - } \ + static GQuark \ + _cogl_##type_name##_get_type (void) \ + { \ + static GQuark type = 0; \ + if (!type) \ + type = g_quark_from_static_string ("Cogl"#TypeName); \ + return type; \ + } \ \ static CoglHandle \ - _cogl_##type_name##_handle_new (Cogl##TypeName *obj) \ - { \ - CoglHandle handle = (CoglHandle) obj; \ + _cogl_##type_name##_handle_new (Cogl##TypeName *new_obj) \ + { \ + CoglHandleObject *obj = &new_obj->_parent; \ + obj->ref_count = 1; \ \ - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); \ + obj->klass = &_cogl_##type_name##_class; \ + if (!obj->klass->type) \ + { \ + obj->klass->type = \ + _cogl_##type_name##_get_type (); \ + obj->klass->virt_free = _cogl_##type_name##_free; \ + } \ \ - if (ctx->handle_array == NULL) \ - ctx->handle_array \ - = g_array_new (FALSE, FALSE, sizeof (CoglHandle)); \ - \ - g_array_append_val (ctx->handle_array, handle); \ - \ - return handle; \ - } \ - \ - static void \ - _cogl_##type_name##_handle_release (CoglHandle handle) \ - { \ - gint i; \ - \ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); \ - \ - if ( (i = _cogl_##type_name##_handle_find (handle)) == -1) \ - return; \ - \ - g_array_remove_index_fast (ctx->handle_array, i); \ + _COGL_HANDLE_DEBUG_NEW (TypeName, obj); \ + return (CoglHandle) new_obj; \ } \ \ Cogl##TypeName * \ @@ -112,49 +122,40 @@ \ gboolean \ cogl_is_##type_name (CoglHandle handle) \ - { \ - if (handle == COGL_INVALID_HANDLE) \ - return FALSE; \ - \ - return _cogl_##type_name##_handle_find (handle) >= 0; \ + { \ + CoglHandleObject *obj = (CoglHandleObject *)handle; \ + \ + return (obj->klass->type == \ + _cogl_##type_name##_get_type ()); \ } \ \ - CoglHandle \ + CoglHandle G_GNUC_DEPRECATED \ cogl_##type_name##_ref (CoglHandle handle) \ { \ - Cogl##TypeName *obj; \ - \ if (!cogl_is_##type_name (handle)) \ return COGL_INVALID_HANDLE; \ + \ + _COGL_HANDLE_DEBUG_REF (TypeName, handle); \ \ - obj = _cogl_##type_name##_pointer_from_handle (handle); \ - \ - obj->ref_count++; \ - \ - COGL_HANDLE_DEBUG_REF (type_name, obj); \ + cogl_handle_ref (handle); \ \ return handle; \ } \ \ - void \ + void G_GNUC_DEPRECATED \ cogl_##type_name##_unref (CoglHandle handle) \ { \ - Cogl##TypeName *obj; \ - \ if (!cogl_is_##type_name (handle)) \ - return; \ + { \ + g_warning (G_STRINGIFY (cogl_##type_name##_unref) \ + ": Ignoring unref of Cogl handle " \ + "due to type missmatch"); \ + return; \ + } \ \ - obj = _cogl_##type_name##_pointer_from_handle (handle); \ - \ - COGL_HANDLE_DEBUG_UNREF (type_name, obj); \ - \ - if (--obj->ref_count < 1) \ - { \ - COGL_HANDLE_DEBUG_FREE (type_name, obj); \ - \ - _cogl_##type_name##_handle_release (obj); \ - _cogl_##type_name##_free (obj); \ - } \ + _COGL_HANDLE_DEBUG_UNREF (TypeName, handle); \ + \ + cogl_handle_unref (handle); \ } #endif /* __COGL_HANDLE_H */ diff --git a/common/cogl-material-private.h b/common/cogl-material-private.h index f5948e318..4044894dd 100644 --- a/common/cogl-material-private.h +++ b/common/cogl-material-private.h @@ -3,6 +3,7 @@ #include "cogl-material.h" #include "cogl-matrix.h" +#include "cogl-handle.h" #include @@ -34,7 +35,7 @@ typedef struct _CoglLayerInfo struct _CoglMaterialLayer { - guint ref_count; + CoglHandleObject _parent; guint index; /*!< lowest index is blended first then others on top */ gulong flags; @@ -68,7 +69,7 @@ typedef enum _CoglMaterialFlags struct _CoglMaterial { - guint ref_count; + CoglHandleObject _parent; gulong flags; diff --git a/common/cogl-material.c b/common/cogl-material.c index bd8eb0c38..498c85979 100644 --- a/common/cogl-material.c +++ b/common/cogl-material.c @@ -30,10 +30,8 @@ static void _cogl_material_free (CoglMaterial *tex); static void _cogl_material_layer_free (CoglMaterialLayer *layer); -COGL_HANDLE_DEFINE (Material, material, material_handles); -COGL_HANDLE_DEFINE (MaterialLayer, - material_layer, - material_layer_handles); +COGL_HANDLE_DEFINE (Material, material); +COGL_HANDLE_DEFINE (MaterialLayer, material_layer); /* #define DISABLE_MATERIAL_CACHE 1 */ @@ -48,9 +46,6 @@ cogl_material_new (void) GLfloat *specular = material->specular; GLfloat *emission = material->emission; - material->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (material, material); - /* Use the same defaults as the GL spec... */ unlit[0] = 1.0; unlit[1] = 1.0; unlit[2] = 1.0; unlit[3] = 1.0; material->flags |= COGL_MATERIAL_FLAG_DEFAULT_COLOR; @@ -84,7 +79,7 @@ _cogl_material_free (CoglMaterial *material) released! Do that separately before this! */ g_list_foreach (material->layers, - (GFunc)cogl_material_layer_unref, NULL); + (GFunc)cogl_handle_unref, NULL); g_free (material); } @@ -424,7 +419,7 @@ _cogl_material_get_layer (CoglMaterial *material, layer = g_new0 (CoglMaterialLayer, 1); - layer->ref_count = 1; + layer_handle = _cogl_material_layer_handle_new (layer); layer->index = index_; layer->flags = COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE; layer->texture = COGL_INVALID_HANDLE; @@ -449,7 +444,6 @@ _cogl_material_get_layer (CoglMaterial *material, cogl_matrix_init_identity (&layer->matrix); - layer_handle = _cogl_material_layer_handle_new (layer); /* Note: see comment after for() loop above */ material->layers = g_list_insert_before (material->layers, tmp, layer_handle); @@ -488,10 +482,10 @@ cogl_material_set_layer (CoglHandle material_handle, * MAX_COMBINED_TEXTURE_IMAGE_UNITS layers. */ } - cogl_texture_ref (texture_handle); + cogl_handle_ref (texture_handle); if (layer->texture) - cogl_texture_unref (layer->texture); + cogl_handle_unref (layer->texture); layer->texture = texture_handle; @@ -625,7 +619,7 @@ cogl_material_set_layer_matrix (CoglHandle material_handle, static void _cogl_material_layer_free (CoglMaterialLayer *layer) { - cogl_texture_unref (layer->texture); + cogl_handle_unref (layer->texture); g_free (layer); } @@ -646,7 +640,7 @@ cogl_material_remove_layer (CoglHandle material_handle, if (layer->index == layer_index) { CoglHandle handle = (CoglHandle) layer; - cogl_material_layer_unref (handle); + cogl_handle_unref (handle); material->layers = g_list_remove (material->layers, layer); break; } @@ -1131,8 +1125,9 @@ cogl_material_flush_gl_state (CoglHandle handle, ...) * cogl_material_flush_gl_state is called, we can compare the incomming * material pointer with ctx->current_material */ - cogl_material_ref (handle); - cogl_material_unref (ctx->current_material); + cogl_handle_ref (handle); + if (ctx->current_material) + cogl_handle_unref (ctx->current_material); ctx->current_material = handle; ctx->current_material_flags = material->flags; @@ -1150,10 +1145,10 @@ cogl_set_source (CoglHandle material_handle) if (ctx->source_material == material_handle) return; - cogl_material_ref (material_handle); + cogl_handle_ref (material_handle); if (ctx->source_material) - cogl_material_unref (ctx->source_material); + cogl_handle_unref (ctx->source_material); ctx->source_material = material_handle; } diff --git a/common/cogl-util.c b/common/cogl-util.c index b64047430..61b08e228 100644 --- a/common/cogl-util.c +++ b/common/cogl-util.c @@ -40,6 +40,7 @@ #include "cogl-shader.h" #include "cogl-texture.h" #include "cogl-types.h" +#include "cogl-handle.h" #include "cogl-util.h" /** @@ -55,7 +56,7 @@ cogl_util_next_p2 (int a) { int rval=1; - while(rval < a) + while(rval < a) rval <<= 1; return rval; @@ -66,45 +67,29 @@ cogl_util_next_p2 (int a) CoglHandle cogl_handle_ref (CoglHandle handle) { + CoglHandleObject *obj = (CoglHandleObject *)handle; + g_return_val_if_fail (handle != COGL_INVALID_HANDLE, COGL_INVALID_HANDLE); - if (cogl_is_texture (handle)) - return cogl_texture_ref (handle); - - if (cogl_is_offscreen (handle)) - return cogl_offscreen_ref (handle); - - if (cogl_is_material (handle)) - return cogl_material_ref (handle); - - if (cogl_is_program (handle)) - return cogl_program_ref (handle); - - if (cogl_is_shader (handle)) - return cogl_shader_ref (handle); - - return COGL_INVALID_HANDLE; + obj->ref_count++; + return handle; } void cogl_handle_unref (CoglHandle handle) { + CoglHandleObject *obj = (CoglHandleObject *)handle; + g_return_if_fail (handle != COGL_INVALID_HANDLE); - if (cogl_is_texture (handle)) - cogl_texture_unref (handle); + if (--obj->ref_count < 1) + { + void (*free_func)(void *obj); - if (cogl_is_offscreen (handle)) - cogl_offscreen_unref (handle); - - if (cogl_is_material (handle)) - cogl_material_unref (handle); - - if (cogl_is_program (handle)) - cogl_program_unref (handle); - - if (cogl_is_shader (handle)) - cogl_shader_unref (handle); + COGL_HANDLE_DEBUG_FREE (obj); + free_func = obj->klass->virt_free; + free_func (obj); + } } GType diff --git a/common/cogl-vertex-buffer-private.h b/common/cogl-vertex-buffer-private.h index fc285a6a9..9ef0d281f 100644 --- a/common/cogl-vertex-buffer-private.h +++ b/common/cogl-vertex-buffer-private.h @@ -24,6 +24,10 @@ #ifndef __COGL_VERTEX_BUFFER_H #define __COGL_VERTEX_BUFFER_H +#include "cogl-handle.h" + +#include + /* Note we put quite a bit into the flags here to help keep * the down size of the CoglVertexBufferAttrib struct below. */ typedef enum _CoglVertexBufferAttribFlags @@ -129,7 +133,8 @@ typedef struct _CoglVertexBufferVBO typedef struct _CoglVertexBuffer { - guint ref_count; + CoglHandleObject _parent; + guint n_vertices; /*!< The number of vertices in the buffer */ GList *submitted_vbos; /* The VBOs currently submitted to the GPU */ diff --git a/common/cogl-vertex-buffer.c b/common/cogl-vertex-buffer.c index 7e6a2b1a0..b9020d375 100644 --- a/common/cogl-vertex-buffer.c +++ b/common/cogl-vertex-buffer.c @@ -200,18 +200,13 @@ static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer); -COGL_HANDLE_DEFINE (VertexBuffer, - vertex_buffer, - vertex_buffer_handles); +COGL_HANDLE_DEFINE (VertexBuffer, vertex_buffer); CoglHandle cogl_vertex_buffer_new (guint n_vertices) { CoglVertexBuffer *buffer = g_slice_alloc (sizeof (CoglVertexBuffer)); - buffer->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (CoglVertexBuffer, buffer); - buffer->n_vertices = n_vertices; buffer->submitted_vbos = NULL; diff --git a/gl/cogl-context.c b/gl/cogl-context.c index 777484d12..5663e81ad 100644 --- a/gl/cogl-context.c +++ b/gl/cogl-context.c @@ -62,12 +62,9 @@ cogl_create_context () _context->indirect = gl_is_indirect; - _context->material_handles = NULL; - _context->material_layer_handles = NULL; _context->default_material = cogl_material_new (); _context->source_material = NULL; - _context->texture_handles = NULL; _context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE; _context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE; @@ -83,15 +80,8 @@ cogl_create_context () sizeof (CoglLayerInfo)); _context->n_texcoord_arrays_enabled = 0; - _context->fbo_handles = NULL; _context->draw_buffer = COGL_WINDOW_BUFFER; - _context->shader_handles = NULL; - - _context->program_handles = NULL; - - _context->vertex_buffer_handles = NULL; - _context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode)); _context->last_path = 0; _context->stencil_material = cogl_material_new (); @@ -193,22 +183,13 @@ cogl_destroy_context () if (_context->path_nodes) g_array_free (_context->path_nodes, TRUE); - if (_context->texture_handles) - g_array_free (_context->texture_handles, TRUE); - if (_context->fbo_handles) - g_array_free (_context->fbo_handles, TRUE); - if (_context->shader_handles) - g_array_free (_context->shader_handles, TRUE); - if (_context->program_handles) - g_array_free (_context->program_handles, TRUE); - if (_context->default_gl_texture_2d_tex) - cogl_texture_unref (_context->default_gl_texture_2d_tex); + cogl_handle_unref (_context->default_gl_texture_2d_tex); if (_context->default_gl_texture_rect_tex) - cogl_texture_unref (_context->default_gl_texture_rect_tex); + cogl_handle_unref (_context->default_gl_texture_rect_tex); if (_context->default_material) - cogl_material_unref (_context->default_material); + cogl_handle_unref (_context->default_material); if (_context->journal) g_array_free (_context->journal, TRUE); diff --git a/gl/cogl-context.h b/gl/cogl-context.h index 14de41c3c..7d025fc9f 100644 --- a/gl/cogl-context.h +++ b/gl/cogl-context.h @@ -60,13 +60,10 @@ typedef struct float inverse_projection[16]; /* Materials */ - GArray *material_handles; - GArray *material_layer_handles; CoglHandle default_material; CoglHandle source_material; /* Textures */ - GArray *texture_handles; CoglHandle default_gl_texture_2d_tex; CoglHandle default_gl_texture_rect_tex; @@ -87,21 +84,11 @@ typedef struct guint n_texcoord_arrays_enabled; /* Framebuffer objects */ - GArray *fbo_handles; CoglBufferTarget draw_buffer; - /* Shaders */ - GArray *shader_handles; - - /* Programs */ - GArray *program_handles; - /* Clip stack */ CoglClipStackState clip; - /* Vertex buffers */ - GArray *vertex_buffer_handles; - /* Primitives */ floatVec2 path_start; floatVec2 path_pen; diff --git a/gl/cogl-fbo.c b/gl/cogl-fbo.c index 42a28a44c..13463d345 100644 --- a/gl/cogl-fbo.c +++ b/gl/cogl-fbo.c @@ -58,7 +58,7 @@ static void _cogl_offscreen_free (CoglFbo *fbo); -COGL_HANDLE_DEFINE (Fbo, offscreen, fbo_handles); +COGL_HANDLE_DEFINE (Fbo, offscreen); CoglHandle cogl_offscreen_new_to_texture (CoglHandle texhandle) @@ -142,14 +142,11 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle) /* Allocate and init a CoglFbo object (store non-wasted size for subsequent blits and viewport setup) */ fbo = (CoglFbo*) g_malloc (sizeof (CoglFbo)); - fbo->ref_count = 1; fbo->width = x_span->size - x_span->waste; fbo->height = y_span->size - y_span->waste; fbo->gl_handle = fbo_gl_handle; fbo->gl_stencil_handle = gl_stencil_handle; - COGL_HANDLE_DEBUG_NEW (offscreen, fbo); - return _cogl_offscreen_handle_new (fbo); } diff --git a/gl/cogl-fbo.h b/gl/cogl-fbo.h index f0efef79f..308c1d955 100644 --- a/gl/cogl-fbo.h +++ b/gl/cogl-fbo.h @@ -26,14 +26,16 @@ #ifndef __COGL_FBO_H #define __COGL_FBO_H +#include "cogl-handle.h" + typedef struct { - guint ref_count; + CoglHandleObject _parent; int width; int height; GLuint gl_handle; GLuint gl_stencil_handle; - + } CoglFbo; #endif /* __COGL_FBO_H */ diff --git a/gl/cogl-program.c b/gl/cogl-program.c index 15f70f8fd..6ee3775ec 100644 --- a/gl/cogl-program.c +++ b/gl/cogl-program.c @@ -65,7 +65,7 @@ static void _cogl_program_free (CoglProgram *program); -COGL_HANDLE_DEFINE (Program, program, program_handles); +COGL_HANDLE_DEFINE (Program, program); static void _cogl_program_free (CoglProgram *program) @@ -83,11 +83,8 @@ cogl_create_program (void) _COGL_GET_CONTEXT (ctx, 0); program = g_slice_new (CoglProgram); - program->ref_count = 1; program->gl_handle = glCreateProgramObjectARB (); - COGL_HANDLE_DEBUG_NEW (program, program); - return _cogl_program_handle_new (program); } diff --git a/gl/cogl-program.h b/gl/cogl-program.h index 6793631d7..fa75f63b6 100644 --- a/gl/cogl-program.h +++ b/gl/cogl-program.h @@ -26,11 +26,13 @@ #ifndef __COGL_PROGRAM_H #define __COGL_PROGRAM_H +#include "cogl-handle.h" + typedef struct _CoglProgram CoglProgram; struct _CoglProgram { - guint ref_count; + CoglHandleObject _parent; GLhandleARB gl_handle; }; diff --git a/gl/cogl-shader-private.h b/gl/cogl-shader-private.h index 4b064e420..4c8fbbb44 100644 --- a/gl/cogl-shader-private.h +++ b/gl/cogl-shader-private.h @@ -26,11 +26,13 @@ #ifndef __COGL_SHADER_H #define __COGL_SHADER_H +#include "cogl-handle.h" + typedef struct _CoglShader CoglShader; struct _CoglShader { - guint ref_count; + CoglHandleObject _parent; GLhandleARB gl_handle; }; diff --git a/gl/cogl-shader.c b/gl/cogl-shader.c index 7cff49ed5..309db01cd 100644 --- a/gl/cogl-shader.c +++ b/gl/cogl-shader.c @@ -45,7 +45,7 @@ static void _cogl_shader_free (CoglShader *shader); -COGL_HANDLE_DEFINE (Shader, shader, shader_handles); +COGL_HANDLE_DEFINE (Shader, shader); static void _cogl_shader_free (CoglShader *shader) @@ -64,11 +64,8 @@ cogl_create_shader (COGLenum shaderType) _COGL_GET_CONTEXT (ctx, 0); shader = g_slice_new (CoglShader); - shader->ref_count = 1; shader->gl_handle = glCreateShaderObjectARB (shaderType); - COGL_HANDLE_DEBUG_NEW (shader, shader); - return _cogl_shader_handle_new (shader); } diff --git a/gl/cogl-texture-private.h b/gl/cogl-texture-private.h index d4e4f2437..2a3a4a5a1 100644 --- a/gl/cogl-texture-private.h +++ b/gl/cogl-texture-private.h @@ -27,6 +27,7 @@ #define __COGL_TEXTURE_H #include "cogl-bitmap.h" +#include "cogl-handle.h" typedef struct _CoglTexture CoglTexture; typedef struct _CoglTexSliceSpan CoglTexSliceSpan; @@ -58,7 +59,7 @@ struct _CoglSpanIter struct _CoglTexture { - guint ref_count; + CoglHandleObject _parent; CoglBitmap bitmap; gboolean bitmap_owner; GLenum gl_target; diff --git a/gl/cogl-texture.c b/gl/cogl-texture.c index 9758e9491..1c7b747bd 100644 --- a/gl/cogl-texture.c +++ b/gl/cogl-texture.c @@ -70,7 +70,7 @@ extern void _cogl_journal_flush (void); static void _cogl_texture_free (CoglTexture *tex); -COGL_HANDLE_DEFINE (Texture, texture, texture_handles); +COGL_HANDLE_DEFINE (Texture, texture); static void _cogl_texture_bitmap_free (CoglTexture *tex) @@ -1228,9 +1228,6 @@ cogl_texture_new_with_size (guint width, /* Init texture with empty bitmap */ tex = (CoglTexture*) g_malloc (sizeof (CoglTexture)); - tex->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (texture, tex); - tex->is_foreign = FALSE; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); @@ -1292,9 +1289,6 @@ cogl_texture_new_from_data (guint width, /* Create new texture and fill with given data */ tex = (CoglTexture*) g_malloc (sizeof (CoglTexture)); - tex->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (texture, tex); - tex->is_foreign = FALSE; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); @@ -1352,9 +1346,6 @@ cogl_texture_new_from_bitmap (CoglBitmap *bmp, /* Create new texture and fill with loaded data */ tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); - tex->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (texture, tex); - tex->is_foreign = FALSE; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); @@ -1376,7 +1367,7 @@ cogl_texture_new_from_bitmap (CoglBitmap *bmp, * this one instead (reloading from file is not needed * in that case). As a rule then, everytime a valid * CoglHandle is returned, it should also be destroyed - * with cogl_texture_unref at some point! */ + * with cogl_handle_unref at some point! */ if (!_cogl_texture_bitmap_prepare (tex, internal_format)) { @@ -1531,9 +1522,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle, /* Create new texture */ tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); - tex->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (texture, tex); - /* Setup bitmap info */ tex->is_foreign = TRUE; tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE; diff --git a/gles/cogl-context.c b/gles/cogl-context.c index 03bd2aaea..5630506e1 100644 --- a/gles/cogl-context.c +++ b/gles/cogl-context.c @@ -64,12 +64,9 @@ cogl_create_context () _context->indirect = gl_is_indirect; - _context->material_handles = NULL; - _context->material_layer_handles = NULL; _context->default_material = cogl_material_new (); _context->source_material = NULL; - _context->texture_handles = NULL; _context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE; _context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE; _context->texture_download_material = COGL_INVALID_HANDLE; @@ -86,15 +83,8 @@ cogl_create_context () sizeof (CoglLayerInfo)); _context->n_texcoord_arrays_enabled = 0; - _context->fbo_handles = NULL; _context->draw_buffer = COGL_WINDOW_BUFFER; - _context->shader_handles = NULL; - - _context->program_handles = NULL; - - _context->vertex_buffer_handles = NULL; - _context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode)); _context->last_path = 0; _context->stencil_material = cogl_material_new (); @@ -154,22 +144,13 @@ cogl_destroy_context () if (_context->path_nodes) g_array_free (_context->path_nodes, TRUE); - if (_context->texture_handles) - g_array_free (_context->texture_handles, TRUE); - if (_context->fbo_handles) - g_array_free (_context->fbo_handles, TRUE); - if (_context->shader_handles) - g_array_free (_context->shader_handles, TRUE); - if (_context->program_handles) - g_array_free (_context->program_handles, TRUE); - if (_context->default_gl_texture_2d_tex) - cogl_texture_unref (_context->default_gl_texture_2d_tex); + cogl_handle_unref (_context->default_gl_texture_2d_tex); if (_context->default_gl_texture_rect_tex) - cogl_texture_unref (_context->default_gl_texture_rect_tex); + cogl_handle_unref (_context->default_gl_texture_rect_tex); if (_context->default_material) - cogl_material_unref (_context->default_material); + cogl_handle_unref (_context->default_material); if (_context->journal) g_array_free (_context->journal, TRUE); diff --git a/gles/cogl-context.h b/gles/cogl-context.h index 68c694549..2a358de97 100644 --- a/gles/cogl-context.h +++ b/gles/cogl-context.h @@ -62,13 +62,10 @@ typedef struct float inverse_projection[16]; /* Materials */ - GArray *material_handles; - GArray *material_layer_handles; CoglHandle default_material; CoglHandle source_material; /* Textures */ - GArray *texture_handles; CoglHandle default_gl_texture_2d_tex; CoglHandle default_gl_texture_rect_tex; CoglHandle texture_download_material; @@ -89,21 +86,11 @@ typedef struct guint n_texcoord_arrays_enabled; /* Framebuffer objects */ - GArray *fbo_handles; CoglBufferTarget draw_buffer; - /* Shaders */ - GArray *shader_handles; - - /* Programs */ - GArray *program_handles; - /* Clip stack */ CoglClipStackState clip; - /* Vertex buffers */ - GArray *vertex_buffer_handles; - /* Primitives */ floatVec2 path_start; floatVec2 path_pen; diff --git a/gles/cogl-fbo.c b/gles/cogl-fbo.c index b52e1055a..c3a2cfd96 100644 --- a/gles/cogl-fbo.c +++ b/gles/cogl-fbo.c @@ -40,7 +40,7 @@ static void _cogl_offscreen_free (CoglFbo *fbo); -COGL_HANDLE_DEFINE (Fbo, offscreen, fbo_handles); +COGL_HANDLE_DEFINE (Fbo, offscreen); CoglHandle cogl_offscreen_new_to_texture (CoglHandle texhandle) @@ -124,14 +124,11 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle) /* Allocate and init a CoglFbo object (store non-wasted size for subsequent blits and viewport setup) */ fbo = (CoglFbo*) g_malloc (sizeof (CoglFbo)); - fbo->ref_count = 1; fbo->width = x_span->size - x_span->waste; fbo->height = y_span->size - y_span->waste; fbo->gl_handle = fbo_gl_handle; fbo->gl_stencil_handle = gl_stencil_handle; - COGL_HANDLE_DEBUG_NEW (offscreen, fbo); - return _cogl_offscreen_handle_new (fbo); } diff --git a/gles/cogl-fbo.h b/gles/cogl-fbo.h index f0efef79f..308c1d955 100644 --- a/gles/cogl-fbo.h +++ b/gles/cogl-fbo.h @@ -26,14 +26,16 @@ #ifndef __COGL_FBO_H #define __COGL_FBO_H +#include "cogl-handle.h" + typedef struct { - guint ref_count; + CoglHandleObject _parent; int width; int height; GLuint gl_handle; GLuint gl_stencil_handle; - + } CoglFbo; #endif /* __COGL_FBO_H */ diff --git a/gles/cogl-program.c b/gles/cogl-program.c index 63f2c0d45..3c7096012 100644 --- a/gles/cogl-program.c +++ b/gles/cogl-program.c @@ -42,7 +42,7 @@ static void _cogl_program_free (CoglProgram *program); -COGL_HANDLE_DEFINE (Program, program, program_handles); +COGL_HANDLE_DEFINE (Program, program); static void _cogl_program_free (CoglProgram *program) @@ -52,7 +52,7 @@ _cogl_program_free (CoglProgram *program) _COGL_GET_CONTEXT (ctx, NO_RETVAL); /* Unref all of the attached shaders */ - g_slist_foreach (program->attached_shaders, (GFunc) cogl_shader_unref, NULL); + g_slist_foreach (program->attached_shaders, (GFunc) cogl_handle_unref, NULL); /* Destroy the list */ g_slist_free (program->attached_shaders); @@ -75,13 +75,10 @@ cogl_create_program (void) CoglProgram *program; program = g_slice_new (CoglProgram); - program->ref_count = 1; program->attached_shaders = NULL; memset (program->custom_uniform_names, 0, COGL_GLES2_NUM_CUSTOM_UNIFORMS * sizeof (char *)); - COGL_HANDLE_DEBUG_NEW (program, program); - return _cogl_program_handle_new (program); } @@ -99,7 +96,7 @@ cogl_program_attach_shader (CoglHandle program_handle, program = _cogl_program_pointer_from_handle (program_handle); program->attached_shaders = g_slist_prepend (program->attached_shaders, - cogl_shader_ref (shader_handle)); + cogl_handle_ref (shader_handle)); /* Whenever the shader changes we will need to relink the program with the fixed functionality shaders so we should forget the diff --git a/gles/cogl-program.h b/gles/cogl-program.h index 65a274c79..fdf52cd67 100644 --- a/gles/cogl-program.h +++ b/gles/cogl-program.h @@ -27,12 +27,13 @@ #define __COGL_PROGRAM_H #include "cogl-gles2-wrapper.h" +#include "cogl-handle.h" typedef struct _CoglProgram CoglProgram; struct _CoglProgram { - guint ref_count; + CoglHandleObject _parent; GSList *attached_shaders; diff --git a/gles/cogl-shader-private.h b/gles/cogl-shader-private.h index 04dff11f4..e95fcd7d9 100644 --- a/gles/cogl-shader-private.h +++ b/gles/cogl-shader-private.h @@ -26,11 +26,13 @@ #ifndef __COGL_SHADER_H #define __COGL_SHADER_H +#include "cogl-handle.h" + typedef struct _CoglShader CoglShader; struct _CoglShader { - guint ref_count; + CoglHandleObject _parent; GLuint gl_handle; GLenum type; }; diff --git a/gles/cogl-shader.c b/gles/cogl-shader.c index 56c5ad07f..5ea438406 100644 --- a/gles/cogl-shader.c +++ b/gles/cogl-shader.c @@ -38,7 +38,7 @@ static void _cogl_shader_free (CoglShader *shader); -COGL_HANDLE_DEFINE (Shader, shader, shader_handles); +COGL_HANDLE_DEFINE (Shader, shader); static void _cogl_shader_free (CoglShader *shader) @@ -57,12 +57,9 @@ cogl_create_shader (COGLenum shaderType) _COGL_GET_CONTEXT (ctx, 0); shader = g_slice_new (CoglShader); - shader->ref_count = 1; shader->gl_handle = glCreateShader (shaderType); shader->type = shaderType; - COGL_HANDLE_DEBUG_NEW (shader, shader); - return _cogl_shader_handle_new (shader); } diff --git a/gles/cogl-texture-private.h b/gles/cogl-texture-private.h index d4e4f2437..2a3a4a5a1 100644 --- a/gles/cogl-texture-private.h +++ b/gles/cogl-texture-private.h @@ -27,6 +27,7 @@ #define __COGL_TEXTURE_H #include "cogl-bitmap.h" +#include "cogl-handle.h" typedef struct _CoglTexture CoglTexture; typedef struct _CoglTexSliceSpan CoglTexSliceSpan; @@ -58,7 +59,7 @@ struct _CoglSpanIter struct _CoglTexture { - guint ref_count; + CoglHandleObject _parent; CoglBitmap bitmap; gboolean bitmap_owner; GLenum gl_target; diff --git a/gles/cogl-texture.c b/gles/cogl-texture.c index 204948ce5..e2a5ec90b 100644 --- a/gles/cogl-texture.c +++ b/gles/cogl-texture.c @@ -57,7 +57,7 @@ extern void _cogl_journal_flush (void); static void _cogl_texture_free (CoglTexture *tex); -COGL_HANDLE_DEFINE (Texture, texture, texture_handles); +COGL_HANDLE_DEFINE (Texture, texture); static void _cogl_texture_bitmap_free (CoglTexture *tex) @@ -1327,9 +1327,6 @@ cogl_texture_new_with_size (guint width, /* Init texture with empty bitmap */ tex = (CoglTexture*) g_malloc (sizeof (CoglTexture)); - tex->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (texture, tex); - tex->is_foreign = FALSE; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); @@ -1391,9 +1388,6 @@ cogl_texture_new_from_data (guint width, /* Create new texture and fill with given data */ tex = (CoglTexture*) g_malloc (sizeof (CoglTexture)); - tex->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (texture, tex); - tex->is_foreign = FALSE; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); @@ -1451,9 +1445,6 @@ cogl_texture_new_from_bitmap (CoglBitmap *bmp, /* Create new texture and fill with loaded data */ tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); - tex->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (texture, tex); - tex->is_foreign = FALSE; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); @@ -1475,7 +1466,7 @@ cogl_texture_new_from_bitmap (CoglBitmap *bmp, * this one instead (reloading from file is not needed * in that case). As a rule then, everytime a valid * CoglHandle is returned, it should also be destroyed - * with cogl_texture_unref at some point! */ + * with cogl_handle_unref at some point! */ if (!_cogl_texture_bitmap_prepare (tex, internal_format)) { @@ -1629,9 +1620,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle, /* Create new texture */ tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); - tex->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (texture, tex); - /* Setup bitmap info */ tex->is_foreign = TRUE; tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE;