diff options
-rw-r--r-- | src/mesa/vbo/vbo_save.h | 7 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_api.c | 25 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_draw.c | 31 |
3 files changed, 53 insertions, 10 deletions
diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index 9558f838837..86bbd24f7b1 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -64,6 +64,13 @@ struct vbo_save_vertex_list { GLubyte attrsz[VBO_ATTRIB_MAX]; GLuint vertex_size; + /* Copy of the final vertex from node->vertex_store->bufferobj. + * Keep this in regular (non-VBO) memory to avoid repeated + * map/unmap of the VBO when updating GL current data. + */ + GLfloat *current_data; + GLuint current_size; + GLuint buffer_offset; GLuint count; GLuint wrap_count; /* number of copied vertices at start */ diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 52b6f1884ee..868226075ac 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -289,6 +289,31 @@ static void _save_compile_vertex_list( GLcontext *ctx ) node->vertex_store->refcount++; node->prim_store->refcount++; + + node->current_size = node->vertex_size - node->attrsz[0]; + node->current_data = NULL; + + if (node->current_size) { + /* If the malloc fails, we just pull the data out of the VBO + * later instead. + */ + node->current_data = MALLOC( node->current_size * sizeof(GLfloat) ); + if (node->current_data) { + const char *buffer = (const char *)save->vertex_store->buffer; + unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat); + unsigned vertex_offset = 0; + + if (node->count) + vertex_offset = (node->count-1) * node->vertex_size * sizeof(GLfloat); + + memcpy( node->current_data, + buffer + node->buffer_offset + vertex_offset + attr_offset, + node->current_size * sizeof(GLfloat) ); + } + } + + + assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->count == 0); diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index f59e1036d01..5110648c282 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -46,20 +46,31 @@ static void _playback_copy_to_current( GLcontext *ctx, const struct vbo_save_vertex_list *node ) { struct vbo_context *vbo = vbo_context(ctx); - GLfloat vertex[VBO_ATTRIB_MAX * 4], *data = vertex; + GLfloat vertex[VBO_ATTRIB_MAX * 4]; + GLfloat *data; GLuint i, offset; - if (node->count) - offset = (node->buffer_offset + - (node->count-1) * node->vertex_size * sizeof(GLfloat)); - else - offset = node->buffer_offset; + if (node->current_size == 0) + return; - ctx->Driver.GetBufferSubData( ctx, 0, offset, - node->vertex_size * sizeof(GLfloat), - data, node->vertex_store->bufferobj ); + if (node->current_data) { + data = node->current_data; + } + else { + data = vertex; + + if (node->count) + offset = (node->buffer_offset + + (node->count-1) * node->vertex_size * sizeof(GLfloat)); + else + offset = node->buffer_offset; - data += node->attrsz[0]; /* skip vertex position */ + ctx->Driver.GetBufferSubData( ctx, 0, offset, + node->vertex_size * sizeof(GLfloat), + data, node->vertex_store->bufferobj ); + + data += node->attrsz[0]; /* skip vertex position */ + } for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { if (node->attrsz[i]) { |