diff options
author | Neil Roberts <neil@linux.intel.com> | 2012-02-25 19:14:25 +0000 |
---|---|---|
committer | Neil Roberts <neil@linux.intel.com> | 2012-03-05 17:46:59 +0000 |
commit | 2501899044759a4e9bd91b78cf622b61bad7d0fb (patch) | |
tree | 5383b3eaaefa189abababdb43c01757ac8a99592 | |
parent | 1b47ff0dfe1c73d9c580f876781b06f7a9720047 (diff) | |
download | cogl-2501899044759a4e9bd91b78cf622b61bad7d0fb.tar.gz |
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>
-rw-r--r-- | cogl/cogl-buffer.c | 107 |
1 files changed, 59 insertions, 48 deletions
diff --git a/cogl/cogl-buffer.c b/cogl/cogl-buffer.c index 68254017..23cd15a5 100644 --- a/cogl/cogl-buffer.c +++ b/cogl/cogl-buffer.c @@ -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; - - _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); + void *ret; - /* Don't allow nesting binds to the same target */ - _COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[target] == NULL, NULL); + ret = _cogl_buffer_bind_no_create (buffer, target); - buffer->last_target = target; - ctx->current_buffer[target] = buffer; + /* 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); - 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 |