cogl: Fallback to set_data when mapping a buffer to fill it

In the journal code and when generating the stroke path the vertices
are generated on the fly and stored in a CoglBuffer using
cogl_buffer_map. However cogl_buffer_map is allowed to fail but it
wasn't checking for a NULL return value. In particular on GLES it will
always fail because glMapBuffer is only provided by an extension. This
adds a new pair of internal functions called
_cogl_buffer_{un,}map_for_fill_or_fallback which wrap
cogl_buffer_map. If the map fails then it will instead return a
pointer into a GByteArray attached to the context. When the buffer is
unmapped the array is copied into the buffer using
cogl_buffer_set_data.
This commit is contained in:
Neil Roberts
2011-01-13 15:35:30 +00:00
parent ac81f3b936
commit a8216aff2f
6 changed files with 83 additions and 10 deletions

View File

@ -474,6 +474,57 @@ cogl_buffer_unmap (CoglBuffer *buffer)
buffer->vtable.unmap (buffer);
}
void *
_cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer)
{
void *ret;
_COGL_GET_CONTEXT (ctx, NULL);
g_return_val_if_fail (!ctx->buffer_map_fallback_in_use, NULL);
ctx->buffer_map_fallback_in_use = TRUE;
ret = cogl_buffer_map (buffer,
COGL_BUFFER_ACCESS_WRITE,
COGL_BUFFER_MAP_HINT_DISCARD);
if (ret)
return ret;
else
{
/* If the map fails then we'll use a temporary buffer to fill
the data and then upload it using cogl_buffer_set_data when
the buffer is unmapped. The temporary buffer is shared to
avoid reallocating it every time */
g_byte_array_set_size (ctx->buffer_map_fallback_array, buffer->size);
buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK;
return ctx->buffer_map_fallback_array->data;
}
}
void
_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
g_return_if_fail (ctx->buffer_map_fallback_in_use);
ctx->buffer_map_fallback_in_use = FALSE;
if ((buffer->flags & COGL_BUFFER_FLAG_MAPPED_FALLBACK))
{
cogl_buffer_set_data (buffer, 0,
ctx->buffer_map_fallback_array->data,
buffer->size);
buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED_FALLBACK;
}
else
cogl_buffer_unmap (buffer);
}
gboolean
cogl_buffer_set_data (CoglBuffer *buffer,
gsize offset,