diff --git a/cogl/cogl-buffer-private.h b/cogl/cogl-buffer-private.h index cf2d9b920..4b21fa388 100644 --- a/cogl/cogl-buffer-private.h +++ b/cogl/cogl-buffer-private.h @@ -137,13 +137,17 @@ _cogl_buffer_immutable_ref (CoglBuffer *buffer); void _cogl_buffer_immutable_unref (CoglBuffer *buffer); -/* This is a wrapper around cogl_buffer_map for internal use when we - want to map the buffer for write only to replace the entire +/* This is a wrapper around cogl_buffer_map_range for internal use + when we want to map the buffer for write only to replace the entire contents. If the map fails then it will fallback to writing to a temporary buffer. When _cogl_buffer_unmap_for_fill_or_fallback is called the temporary buffer will be copied into the array. Note that these calls share a global array so they can not be nested. */ void * +_cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, + size_t offset, + size_t size); +void * _cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer); void diff --git a/cogl/cogl-buffer.c b/cogl/cogl-buffer.c index 7a1a08463..72fd3f852 100644 --- a/cogl/cogl-buffer.c +++ b/cogl/cogl-buffer.c @@ -261,6 +261,14 @@ cogl_buffer_unmap (CoglBuffer *buffer) void * _cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer) +{ + return _cogl_buffer_map_range_for_fill_or_fallback (buffer, 0, buffer->size); +} + +void * +_cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, + size_t offset, + size_t size) { CoglContext *ctx = buffer->context; void *ret; @@ -269,9 +277,11 @@ _cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer) ctx->buffer_map_fallback_in_use = TRUE; - ret = cogl_buffer_map (buffer, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); + ret = cogl_buffer_map_range (buffer, + offset, + size, + COGL_BUFFER_ACCESS_WRITE, + COGL_BUFFER_MAP_HINT_DISCARD); if (ret) return ret; @@ -281,7 +291,8 @@ _cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer) 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); + g_byte_array_set_size (ctx->buffer_map_fallback_array, size); + ctx->buffer_map_fallback_offset = offset; buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK; @@ -300,9 +311,10 @@ _cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer) if ((buffer->flags & COGL_BUFFER_FLAG_MAPPED_FALLBACK)) { - cogl_buffer_set_data (buffer, 0, + cogl_buffer_set_data (buffer, + ctx->buffer_map_fallback_offset, ctx->buffer_map_fallback_array->data, - buffer->size); + ctx->buffer_map_fallback_array->len); buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED_FALLBACK; } else diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h index 7321455d3..788cf3d3c 100644 --- a/cogl/cogl-context-private.h +++ b/cogl/cogl-context-private.h @@ -269,6 +269,7 @@ struct _CoglContext data */ GByteArray *buffer_map_fallback_array; CoglBool buffer_map_fallback_in_use; + size_t buffer_map_fallback_offset; CoglWinsysRectangleState rectangle_state; diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c index e8eee7906..c762a0b2a 100644 --- a/cogl/cogl-journal.c +++ b/cogl/cogl-journal.c @@ -1079,7 +1079,9 @@ upload_vertices (CoglJournal *journal, buffer = COGL_BUFFER (attribute_buffer); cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_STATIC); - vout = _cogl_buffer_map_for_fill_or_fallback (buffer); + vout = _cogl_buffer_map_range_for_fill_or_fallback (buffer, + 0, /* offset */ + needed_vbo_len * 4); vin = &g_array_index (vertices, float, 0); /* Expand the number of vertices from 2 to 4 while uploading */