OSDN Git Service

vbo: cache last dlist vertex in malloced memory
authorKeith Whitwell <keithw@vmware.com>
Thu, 16 Apr 2009 11:19:19 +0000 (12:19 +0100)
committerKeith Whitwell <keithw@vmware.com>
Thu, 16 Apr 2009 11:19:19 +0000 (12:19 +0100)
Avoids repeated mapping of the VBO buffer on display list replay.  We
need access to the final vertex in order to update the GL current attrib
values.

src/mesa/vbo/vbo_save.h
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_save_draw.c

index 9558f83..86bbd24 100644 (file)
@@ -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 */
index 52b6f18..8682260 100644 (file)
@@ -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);
 
index f59e103..5110648 100644 (file)
@@ -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]) {