[cogl vertex buffers] Give indices a CoglHandle so they are shareable
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.
This commit is contained in:
parent
f0849fc3e2
commit
be826ed4e7
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -201,8 +201,10 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user