cogl-buffer: Create the buffer store when bound
Whenever the buffer is bound with _cogl_buffer_bind Cogl now ensures the buffer's data store has been created. Previously it would only ensure it was created when it was first mapped or when the first data was set on it. This is necessary if we are going to use CoglBuffers for retrieving data from GL. In that case the buffer won't be mapped or have data set on it before it is used. Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
parent
1b47ff0dfe
commit
2501899044
@ -118,6 +118,34 @@ convert_bind_target_to_gl_target (CoglBufferBindTarget target)
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
_cogl_buffer_bind_no_create (CoglBuffer *buffer,
|
||||
CoglBufferBindTarget target)
|
||||
{
|
||||
CoglContext *ctx = buffer->context;
|
||||
|
||||
_COGL_RETURN_VAL_IF_FAIL (buffer != NULL, NULL);
|
||||
|
||||
/* Don't allow binding the buffer to multiple targets at the same time */
|
||||
_COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[buffer->last_target] != buffer,
|
||||
NULL);
|
||||
|
||||
/* Don't allow nesting binds to the same target */
|
||||
_COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[target] == NULL, NULL);
|
||||
|
||||
buffer->last_target = target;
|
||||
ctx->current_buffer[target] = buffer;
|
||||
|
||||
if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT)
|
||||
{
|
||||
GLenum gl_target = convert_bind_target_to_gl_target (buffer->last_target);
|
||||
GE( ctx, glBindBuffer (gl_target, buffer->gl_handle) );
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return buffer->data;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
_cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint,
|
||||
CoglBufferUpdateHint update_hint)
|
||||
@ -136,6 +164,25 @@ _cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint,
|
||||
return GL_STATIC_DRAW;
|
||||
}
|
||||
|
||||
static void
|
||||
bo_recreate_store (CoglBuffer *buffer)
|
||||
{
|
||||
GLenum gl_target;
|
||||
GLenum gl_enum;
|
||||
|
||||
/* This assumes the buffer is already bound */
|
||||
|
||||
gl_target = convert_bind_target_to_gl_target (buffer->last_target);
|
||||
gl_enum = _cogl_buffer_hints_to_gl_enum (buffer->usage_hint,
|
||||
buffer->update_hint);
|
||||
|
||||
GE( buffer->context, glBufferData (gl_target,
|
||||
buffer->size,
|
||||
NULL,
|
||||
gl_enum) );
|
||||
buffer->store_created = TRUE;
|
||||
}
|
||||
|
||||
static void *
|
||||
bo_map (CoglBuffer *buffer,
|
||||
CoglBufferAccess access,
|
||||
@ -154,7 +201,7 @@ bo_map (CoglBuffer *buffer,
|
||||
return NULL;
|
||||
|
||||
target = buffer->last_target;
|
||||
_cogl_buffer_bind (buffer, target);
|
||||
_cogl_buffer_bind_no_create (buffer, target);
|
||||
|
||||
gl_target = convert_bind_target_to_gl_target (target);
|
||||
|
||||
@ -162,19 +209,7 @@ bo_map (CoglBuffer *buffer,
|
||||
* lazily allows the user of the CoglBuffer to set a hint before the
|
||||
* store is created. */
|
||||
if (!buffer->store_created || (hints & COGL_BUFFER_MAP_HINT_DISCARD))
|
||||
{
|
||||
GLenum gl_enum;
|
||||
|
||||
gl_enum = _cogl_buffer_hints_to_gl_enum (buffer->usage_hint,
|
||||
buffer->update_hint);
|
||||
|
||||
|
||||
GE( ctx, glBufferData (gl_target,
|
||||
buffer->size,
|
||||
NULL,
|
||||
gl_enum) );
|
||||
buffer->store_created = TRUE;
|
||||
}
|
||||
bo_recreate_store (buffer);
|
||||
|
||||
GE_RET( data, ctx, glMapBuffer (gl_target,
|
||||
_cogl_buffer_access_to_gl_enum (access)) );
|
||||
@ -191,7 +226,7 @@ bo_unmap (CoglBuffer *buffer)
|
||||
{
|
||||
CoglContext *ctx = buffer->context;
|
||||
|
||||
_cogl_buffer_bind (buffer, buffer->last_target);
|
||||
_cogl_buffer_bind_no_create (buffer, buffer->last_target);
|
||||
|
||||
GE( ctx, glUnmapBuffer (convert_bind_target_to_gl_target
|
||||
(buffer->last_target)) );
|
||||
@ -215,20 +250,6 @@ bo_set_data (CoglBuffer *buffer,
|
||||
|
||||
gl_target = convert_bind_target_to_gl_target (target);
|
||||
|
||||
/* create an empty store if we don't have one yet. creating the store
|
||||
* lazily allows the user of the CoglBuffer to set a hint before the
|
||||
* store is created. */
|
||||
if (!buffer->store_created)
|
||||
{
|
||||
GLenum gl_enum = _cogl_buffer_hints_to_gl_enum (buffer->usage_hint,
|
||||
buffer->update_hint);
|
||||
GE( ctx, glBufferData (gl_target,
|
||||
buffer->size,
|
||||
NULL,
|
||||
gl_enum) );
|
||||
buffer->store_created = TRUE;
|
||||
}
|
||||
|
||||
GE( ctx, glBufferSubData (gl_target, offset, size, data) );
|
||||
|
||||
_cogl_buffer_unbind (buffer);
|
||||
@ -331,28 +352,18 @@ _cogl_buffer_access_to_gl_enum (CoglBufferAccess access)
|
||||
void *
|
||||
_cogl_buffer_bind (CoglBuffer *buffer, CoglBufferBindTarget target)
|
||||
{
|
||||
CoglContext *ctx = buffer->context;
|
||||
void *ret;
|
||||
|
||||
_COGL_RETURN_VAL_IF_FAIL (buffer != NULL, NULL);
|
||||
ret = _cogl_buffer_bind_no_create (buffer, target);
|
||||
|
||||
/* Don't allow binding the buffer to multiple targets at the same time */
|
||||
_COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[buffer->last_target] != buffer,
|
||||
NULL);
|
||||
/* create an empty store if we don't have one yet. creating the store
|
||||
* lazily allows the user of the CoglBuffer to set a hint before the
|
||||
* store is created. */
|
||||
if ((buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) &&
|
||||
!buffer->store_created)
|
||||
bo_recreate_store (buffer);
|
||||
|
||||
/* Don't allow nesting binds to the same target */
|
||||
_COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[target] == NULL, NULL);
|
||||
|
||||
buffer->last_target = target;
|
||||
ctx->current_buffer[target] = buffer;
|
||||
|
||||
if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT)
|
||||
{
|
||||
GLenum gl_target = convert_bind_target_to_gl_target (buffer->last_target);
|
||||
GE( ctx, glBindBuffer (gl_target, buffer->gl_handle) );
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return buffer->data;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user