summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2012-02-25 19:14:25 +0000
committerNeil Roberts <neil@linux.intel.com>2012-03-05 17:46:59 +0000
commit2501899044759a4e9bd91b78cf622b61bad7d0fb (patch)
tree5383b3eaaefa189abababdb43c01757ac8a99592
parent1b47ff0dfe1c73d9c580f876781b06f7a9720047 (diff)
downloadcogl-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.c107
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