mesa: Keep track of the last looked-up VAO
authorFredrik Höglund <fredrik@kde.org>
Mon, 2 Mar 2015 17:25:45 +0000 (18:25 +0100)
committerFredrik Höglund <fredrik@kde.org>
Fri, 8 May 2015 13:31:02 +0000 (15:31 +0200)
This saves the cost of repeated hash table lookups when the same
vertex array object is referenced in a sequence of calls such as:

    glVertexArrayAttribFormat(vao, ...);
    glVertexArrayAttribBinding(vao, ...);
    glEnableVertexArrayAttrib(vao, ...);
    ...

Note that VAO's are container objects that are not shared between
contexts.

Reviewed-by: Laura Ekstrand <laura@jlekstrand.net>
src/mesa/main/arrayobj.c
src/mesa/main/mtypes.h

index 33c6a45953993c7f886191fb130d9c1673ac1a4a..42214d8d6a02ea1435f035c7f43586421018145d 100644 (file)
@@ -100,20 +100,28 @@ _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, const char *caller)
 
       return ctx->Array.DefaultVAO;
    } else {
-      struct gl_vertex_array_object *vao =
-         (struct gl_vertex_array_object *)
-         _mesa_HashLookup(ctx->Array.Objects, id);
+      struct gl_vertex_array_object *vao;
 
-      /* The ARB_direct_state_access specification says:
-       *
-       *    "An INVALID_OPERATION error is generated if <vaobj> is not
-       *     [compatibility profile: zero or] the name of an existing
-       *     vertex array object."
-       */
-      if (!vao || !vao->EverBound) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "%s(non-existent vaobj=%u)", caller, id);
-         return NULL;
+      if (ctx->Array.LastLookedUpVAO &&
+          ctx->Array.LastLookedUpVAO->Name == id) {
+         vao = ctx->Array.LastLookedUpVAO;
+      } else {
+         vao = (struct gl_vertex_array_object *)
+            _mesa_HashLookup(ctx->Array.Objects, id);
+
+         /* The ARB_direct_state_access specification says:
+          *
+          *    "An INVALID_OPERATION error is generated if <vaobj> is not
+          *     [compatibility profile: zero or] the name of an existing
+          *     vertex array object."
+          */
+         if (!vao || !vao->EverBound) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "%s(non-existent vaobj=%u)", caller, id);
+            return NULL;
+         }
+
+         _mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, vao);
       }
 
       return vao;
@@ -517,6 +525,9 @@ _mesa_DeleteVertexArrays(GLsizei n, const GLuint *ids)
         /* The ID is immediately freed for re-use */
         remove_array_object(ctx, obj);
 
+         if (ctx->Array.LastLookedUpVAO == obj)
+            _mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, NULL);
+
          /* Unreference the array object. 
           * If refcount hits zero, the object will be deleted.
           */
index dddbba5a44dcfba3e3ac94511d1c361b365b7cc1..737f0be6d626e509128a70bb7b4d2235fc7ba52d 100644 (file)
@@ -1674,6 +1674,9 @@ struct gl_array_attrib
    /** The default vertex array object */
    struct gl_vertex_array_object *DefaultVAO;
 
+   /** The last VAO accessed by a DSA function */
+   struct gl_vertex_array_object *LastLookedUpVAO;
+
    /** Array objects (GL_ARB/APPLE_vertex_array_object) */
    struct _mesa_HashTable *Objects;