[cogl vertex buffers] Give indices a CoglHandle so they are shareable
authorRobert Bragg <robert@linux.intel.com>
Thu, 28 May 2009 11:49:29 +0000 (12:49 +0100)
committerRobert Bragg <robert@linux.intel.com>
Thu, 28 May 2009 12:27:54 +0000 (13:27 +0100)
Previously indices were tightly bound to a particular Cogl vertex buffer
but we would like to be able to share indices so now we have
cogl_vertex_buffer_indices_new () which returns a CoglHandle.

In particular we could like to have a shared set of indices for drawing
lists of quads that can be shared between the pango renderer and the
Cogl journal.

clutter/cogl/cogl-vertex-buffer.h
clutter/cogl/common/cogl-vertex-buffer-private.h
clutter/cogl/common/cogl-vertex-buffer.c
tests/interactive/test-cogl-vertex-buffer.c

index 1887db5..ba2cef8 100644 (file)
@@ -303,10 +303,7 @@ typedef enum _CoglIndicesType
 } CoglIndicesType;
 
 /**
- * cogl_vertex_buffer_add_indices:
- * @handle: A vertex buffer handle
- * @min_index: Specifies the minimum vertex index contained in indices
- * @max_index: Specifies the maximum vertex index contained in indices
+ * cogl_vertex_buffer_indices_new:
  * @indices_type: a #CoglIndicesType specifying the data type used for
  *                the indices.
  * @indices_array: Specifies the address of your array of indices
@@ -317,19 +314,11 @@ typedef enum _CoglIndicesType
  * array allows you to reference vertices multiple times, for example
  * during triangle strips.
  *
- * You should aim to use the smallest data type possible and correctly reflect
- * the range of index values in the {min,max}_index arguments. This allows Cogl
- * to optimize the internal storage used for the indices and reduce the demand
- * for memory bandwidth.
- *
- * Returns: An identifier (greater than 0) for the indices which you can
- *          pass to cogl_vertex_buffer_draw_elements().
+ * Returns: A CoglHandle for the indices which you can pass to
+ *          cogl_vertex_buffer_draw_elements().
  */
-int
-cogl_vertex_buffer_add_indices (CoglHandle       handle,
-                               int              min_index,
-                                int              max_index,
-                                CoglIndicesType  indices_type,
+CoglHandle
+cogl_vertex_buffer_indices_new (CoglIndicesType  indices_type,
                                 const void      *indices_array,
                                 int              indices_len);
 
@@ -352,16 +341,17 @@ cogl_vertex_buffer_delete_indices (CoglHandle handle,
  * @handle: A vertex buffer handle
  * @mode: A #CoglVerticesMode specifying how the vertices should be
  *        interpreted.
- * @indices_id: The identifier for a an array of indices previously added to
- *              the given Cogl vertex buffer using
- *              cogl_vertex_buffer_add_indices().
+ * @indices: A CoglHandle for a set of indices allocated via
+ *           cogl_vertex_buffer_indices_new ()
+ * @min_index: Specifies the minimum vertex index contained in indices
+ * @max_index: Specifies the maximum vertex index contained in indices
  * @indices_offset: An offset into named indices. The offset marks the first
  *                  index to use for drawing.
  * @count: Specifies the number of vertices you want to draw.
  *
  * This function lets you use an array of indices to specify the vertices
  * within your vertex buffer that you want to draw. The indices themselves
- * are given by calling cogl_vertex_buffer_add_indices ()
+ * are created by calling cogl_vertex_buffer_indices_new ()
  *
  * Any un-submitted attribute changes are automatically submitted before
  * drawing.
@@ -369,7 +359,9 @@ cogl_vertex_buffer_delete_indices (CoglHandle handle,
 void
 cogl_vertex_buffer_draw_elements (CoglHandle       handle,
                                  CoglVerticesMode mode,
-                                  int              indices_id,
+                                  CoglHandle       indices,
+                                  int              min_index,
+                                  int              max_index,
                                   int              indices_offset,
                                   int              count);
 
index cc87b18..17f8725 100644 (file)
@@ -139,14 +139,13 @@ typedef struct _CoglVertexBufferVBO
 
 typedef struct _CoglVertexBufferIndices
 {
-  int     id;
+  CoglHandleObject _parent;
+
   /* Note: this is a pointer to handle fallbacks. It normally holds
    * a GLuint VBO name, but when the driver doesn't support VBOs then
    * this simply points to an malloc'd buffer. */
   void   *vbo_name;
   GLenum  type;
-  GLuint  min_index;
-  GLuint  max_index;
 } CoglVertexBufferIndices;
 
 typedef struct _CoglVertexBuffer
@@ -160,8 +159,6 @@ typedef struct _CoglVertexBuffer
    * modifying a buffer. */
   GList  *new_attributes; /*!< attributes pending submission */
 
-  GList *indices; /*!< A list of associated index arrays */
-
 } CoglVertexBuffer;
 
 #endif /* __COGL_VERTEX_BUFFER_H */
index 096a4a4..b3c36f0 100644 (file)
 #endif /* HAVE_COGL_GL */
 
 static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer);
+static void _cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices);
 
 COGL_HANDLE_DEFINE (VertexBuffer, vertex_buffer);
+COGL_HANDLE_DEFINE (VertexBufferIndices, vertex_buffer_indices);
 
 CoglHandle
 cogl_vertex_buffer_new (guint n_vertices)
@@ -214,8 +216,6 @@ cogl_vertex_buffer_new (guint n_vertices)
   buffer->submitted_vbos = NULL;
   buffer->new_attributes = NULL;
 
-  buffer->indices = NULL;
-
   /* return COGL_INVALID_HANDLE; */
   return _cogl_vertex_buffer_handle_new (buffer);
 }
@@ -1741,22 +1741,6 @@ cogl_vertex_buffer_draw (CoglHandle       handle,
   disable_state_for_drawing_buffer (buffer);
 }
 
-static void
-free_vertex_buffer_indices (CoglVertexBufferIndices *indices)
-{
-  gboolean fallback =
-    (cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
-
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  if (fallback)
-    g_free (indices->vbo_name);
-  else
-    GE (glDeleteBuffers (1, (GLuint *)&indices->vbo_name));
-
-  g_slice_free (CoglVertexBufferIndices, indices);
-}
-
 static int
 get_indices_type_size (GLuint indices_type)
 {
@@ -1771,34 +1755,19 @@ get_indices_type_size (GLuint indices_type)
     }
 }
 
-int
-cogl_vertex_buffer_add_indices (CoglHandle       handle,
-                               int              min_index,
-                                int              max_index,
-                                CoglIndicesType  indices_type,
+CoglHandle
+cogl_vertex_buffer_indices_new (CoglIndicesType  indices_type,
                                 const void      *indices_array,
                                 int              indices_len)
 {
-  CoglVertexBuffer *buffer;
   gboolean fallback =
     (cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
   size_t indices_bytes;
   CoglVertexBufferIndices *indices;
 
-  static int next_indices_id = 1;
-
-
   _COGL_GET_CONTEXT (ctx, 0);
 
-  if (!cogl_is_vertex_buffer (handle))
-    return 0;
-
-  buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
-
   indices = g_slice_alloc (sizeof (CoglVertexBufferIndices));
-  indices->id = next_indices_id;
-  indices->min_index = min_index;
-  indices->max_index = max_index;
 
   if (indices_type == COGL_INDICES_TYPE_UNSIGNED_BYTE)
     indices->type = GL_UNSIGNED_BYTE;
@@ -1829,39 +1798,31 @@ cogl_vertex_buffer_add_indices (CoglHandle       handle,
       GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0));
     }
 
-  buffer->indices = g_list_prepend (buffer->indices, indices);
-
-  return next_indices_id++;
+  return _cogl_vertex_buffer_indices_handle_new (indices);
 }
 
 void
-cogl_vertex_buffer_delete_indices (CoglHandle handle,
-                                   int indices_id)
+_cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *indices)
 {
-  CoglVertexBuffer *buffer;
-  GList *l;
+  gboolean fallback =
+    (cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
 
-  if (!cogl_is_vertex_buffer (handle))
-    return;
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
 
-  buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
+  if (fallback)
+    g_free (indices->vbo_name);
+  else
+    GE (glDeleteBuffers (1, (GLuint *)&indices->vbo_name));
 
-  for (l = buffer->indices; l; l = l->next)
-    {
-      CoglVertexBufferIndices *current_indices = l->data;
-      if (current_indices->id == indices_id)
-        {
-          free_vertex_buffer_indices (l->data);
-          buffer->indices = g_list_delete_link (buffer->indices, l);
-          return;
-        }
-    }
+  g_slice_free (CoglVertexBufferIndices, indices);
 }
 
 void
 cogl_vertex_buffer_draw_elements (CoglHandle       handle,
                                  CoglVerticesMode mode,
-                                  int              indices_id,
+                                  CoglHandle       indices_handle,
+                                  int              min_index,
+                                  int              max_index,
                                   int              indices_offset,
                                   int              count)
 {
@@ -1869,7 +1830,6 @@ cogl_vertex_buffer_draw_elements (CoglHandle       handle,
   gboolean fallback =
     (cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
   size_t byte_offset;
-  GList *l;
   CoglVertexBufferIndices *indices = NULL;
 
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@@ -1879,22 +1839,15 @@ cogl_vertex_buffer_draw_elements (CoglHandle       handle,
 
   buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
 
+  if (!cogl_is_vertex_buffer_indices (indices_handle))
+    return;
+
+  indices = _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle);
+
   cogl_clip_ensure ();
   _cogl_current_matrix_state_flush ();
   enable_state_for_drawing_buffer (buffer);
 
-  for (l = buffer->indices; l; l = l->next)
-    {
-      CoglVertexBufferIndices *current_indices = l->data;
-      if (current_indices->id == indices_id)
-        {
-          indices = current_indices;
-          break;
-        }
-    }
-  if (!indices)
-    return;
-
   byte_offset = indices_offset * get_indices_type_size (indices->type);
   if (fallback)
     byte_offset = (size_t)(((char *)indices->vbo_name) + byte_offset);
@@ -1903,7 +1856,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle       handle,
                       GPOINTER_TO_UINT (indices->vbo_name)));
 
   /* FIXME: flush cogl cache */
-  GE (glDrawRangeElements (mode, indices->min_index, indices->max_index,
+  GE (glDrawRangeElements (mode, min_index, max_index,
                            count, indices->type, (void *)byte_offset));
 
   disable_state_for_drawing_buffer (buffer);
@@ -1924,10 +1877,6 @@ _cogl_vertex_buffer_free (CoglVertexBuffer *buffer)
     cogl_vertex_buffer_attribute_free (tmp->data);
   g_list_free (buffer->new_attributes);
 
-  for (tmp = buffer->indices; tmp != NULL; tmp = tmp->next)
-    free_vertex_buffer_indices (tmp->data);
-  g_list_free (buffer->indices);
-
   g_slice_free (CoglVertexBuffer, buffer);
 }
 
index 4cc3b48..093e32a 100644 (file)
@@ -49,7 +49,7 @@ typedef struct _TestState
   GLubyte         *quad_mesh_colors;
   GLushort        *static_indices;
   guint            n_static_indices;
-  int              indices_id;
+  CoglHandle       indices;
   ClutterTimeline *timeline;
 } TestState;
 
@@ -141,7 +141,10 @@ on_paint (ClutterActor *actor, TestState *state)
   cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
   cogl_vertex_buffer_draw_elements (state->buffer,
                                     COGL_VERTICES_MODE_TRIANGLE_STRIP,
-                                    state->indices_id,
+                                    state->indices,
+                                    0, /* min index */
+                                    (MESH_WIDTH + 1) *
+                                    (MESH_HEIGHT + 1), /* max index */
                                     0, /* indices offset */
                                     state->n_static_indices);
 }
@@ -220,12 +223,8 @@ init_static_index_arrays (TestState *state)
 
 #undef MESH_INDEX
 
-  state->indices_id =
-    cogl_vertex_buffer_add_indices (state->buffer,
-                                    0, /* min index */
-                                    (MESH_WIDTH + 1) *
-                                    (MESH_HEIGHT + 1), /* max index */
-                                    COGL_INDICES_TYPE_UNSIGNED_SHORT,
+  state->indices =
+    cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
                                     state->static_indices,
                                     state->n_static_indices);
 }
@@ -376,6 +375,7 @@ test_cogl_vertex_buffer_main (int argc, char *argv[])
   clutter_main ();
 
   cogl_handle_unref (state.buffer);
+  cogl_handle_unref (state.indices);
 
   g_source_remove (idle_source);