/**
* \file arrayobj.c
*
- * Implementation of Vertex Array Objects (VAOs), from OpenGL 3.1+,
- * the GL_ARB_vertex_array_object extension, or the older
- * GL_APPLE_vertex_array_object extension.
+ * Implementation of Vertex Array Objects (VAOs), from OpenGL 3.1+ /
+ * the GL_ARB_vertex_array_object extension.
*
* \todo
* The code in this file borrows a lot from bufferobj.c. There's a certain
return NULL;
else
return (struct gl_vertex_array_object *)
- _mesa_HashLookup(ctx->Array.Objects, id);
+ _mesa_HashLookupLocked(ctx->Array.Objects, id);
}
vao = ctx->Array.LastLookedUpVAO;
} else {
vao = (struct gl_vertex_array_object *)
- _mesa_HashLookup(ctx->Array.Objects, id);
+ _mesa_HashLookupLocked(ctx->Array.Objects, id);
/* The ARB_direct_state_access specification says:
*
{
unbind_array_object_vbos(ctx, obj);
_mesa_reference_buffer_object(ctx, &obj->IndexBufferObj, NULL);
- mtx_destroy(&obj->Mutex);
free(obj->Label);
free(obj);
}
if (*ptr) {
/* Unreference the old array object */
- GLboolean deleteFlag = GL_FALSE;
struct gl_vertex_array_object *oldObj = *ptr;
- mtx_lock(&oldObj->Mutex);
assert(oldObj->RefCount > 0);
oldObj->RefCount--;
- deleteFlag = (oldObj->RefCount == 0);
- mtx_unlock(&oldObj->Mutex);
- if (deleteFlag)
+ if (oldObj->RefCount == 0)
_mesa_delete_vao(ctx, oldObj);
*ptr = NULL;
if (vao) {
/* reference new array object */
- mtx_lock(&vao->Mutex);
- if (vao->RefCount == 0) {
- /* this array's being deleted (look just above) */
- /* Not sure this can every really happen. Warn if it does. */
- _mesa_problem(NULL, "referencing deleted array object");
- *ptr = NULL;
- }
- else {
- vao->RefCount++;
- *ptr = vao;
- }
- mtx_unlock(&vao->Mutex);
+ assert(vao->RefCount > 0);
+
+ vao->RefCount++;
+ *ptr = vao;
}
}
vao->Name = name;
- mtx_init(&vao->Mutex, mtx_plain);
vao->RefCount = 1;
/* Init the individual arrays */
{
if (vao->Name > 0) {
/* insert into hash table */
- _mesa_HashInsert(ctx->Array.Objects, vao->Name, vao);
+ _mesa_HashInsertLocked(ctx->Array.Objects, vao->Name, vao);
}
}
{
if (vao->Name > 0) {
/* remove from hash table */
- _mesa_HashRemove(ctx->Array.Objects, vao->Name);
+ _mesa_HashRemoveLocked(ctx->Array.Objects, vao->Name);
}
}
/**
- * Updates the derived gl_client_arrays when a gl_vertex_attrib_array
+ * Updates the derived gl_vertex_arrays when a gl_vertex_attrib_array
* or a gl_vertex_buffer_binding has changed.
*/
void
while (arrays) {
const int attrib = u_bit_scan64(&arrays);
- struct gl_client_array *client_array = &vao->_VertexAttrib[attrib];
+ struct gl_vertex_array *client_array = &vao->_VertexAttrib[attrib];
const struct gl_array_attributes *attrib_array =
&vao->VertexAttrib[attrib];
const struct gl_vertex_buffer_binding *buffer_binding =
/**
- * Helper for _mesa_BindVertexArray() and _mesa_BindVertexArrayAPPLE().
- * \param genRequired specifies behavour when id was not generated with
- * glGenVertexArrays().
+ * ARB version of glBindVertexArray()
*/
-static void
-bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired)
+void GLAPIENTRY
+_mesa_BindVertexArray( GLuint id )
{
+ GET_CURRENT_CONTEXT(ctx);
+
struct gl_vertex_array_object * const oldObj = ctx->Array.VAO;
struct gl_vertex_array_object *newObj = NULL;
assert(oldObj != NULL);
- if ( oldObj->Name == id )
+ if (oldObj->Name == id)
return; /* rebinding the same array object- no change */
/*
/* non-default array object */
newObj = _mesa_lookup_vao(ctx, id);
if (!newObj) {
- if (genRequired) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBindVertexArray(non-gen name)");
- return;
- }
-
- /* For APPLE version, generate a new array object now */
- newObj = _mesa_new_vao(ctx, id);
- if (!newObj) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE");
- return;
- }
-
- save_array_object(ctx, newObj);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindVertexArray(non-gen name)");
+ return;
}
- if (!newObj->EverBound) {
- /* The "Interactions with APPLE_vertex_array_object" section of the
- * GL_ARB_vertex_array_object spec says:
- *
- * "The first bind call, either BindVertexArray or
- * BindVertexArrayAPPLE, determines the semantic of the object."
- */
- newObj->ARBsemantics = genRequired;
- newObj->EverBound = GL_TRUE;
- }
+ newObj->EverBound = GL_TRUE;
}
if (ctx->Array.DrawMethod == DRAW_ARRAYS) {
}
-/**
- * ARB version of glBindVertexArray()
- * This function behaves differently from glBindVertexArrayAPPLE() in
- * that this function requires all ids to have been previously generated
- * by glGenVertexArrays[APPLE]().
- */
-void GLAPIENTRY
-_mesa_BindVertexArray( GLuint id )
-{
- GET_CURRENT_CONTEXT(ctx);
- bind_vertex_array(ctx, id, GL_TRUE);
-}
-
-
-/**
- * Bind a new array.
- *
- * \todo
- * The binding could be done more efficiently by comparing the non-NULL
- * pointers in the old and new objects. The only arrays that are "dirty" are
- * the ones that are non-NULL in either object.
- */
-void GLAPIENTRY
-_mesa_BindVertexArrayAPPLE( GLuint id )
-{
- GET_CURRENT_CONTEXT(ctx);
- bind_vertex_array(ctx, id, GL_FALSE);
-}
-
-
/**
* Delete a set of array objects.
*
/**
* Generate a set of unique array object IDs and store them in \c arrays.
- * Helper for _mesa_GenVertexArrays[APPLE]() and _mesa_CreateVertexArrays()
+ * Helper for _mesa_GenVertexArrays() and _mesa_CreateVertexArrays()
* below.
*
* \param n Number of IDs to generate.
}
-/**
- * APPLE version of glGenVertexArraysAPPLE()
- * Arrays may live in VBOs or ordinary memory.
- */
-void GLAPIENTRY
-_mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays)
-{
- GET_CURRENT_CONTEXT(ctx);
- gen_vertex_arrays(ctx, n, arrays, false, "glGenVertexArraysAPPLE");
-}
-
-
/**
* ARB_direct_state_access
* Generates ID's and creates the array objects.
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (id == 0)
- return GL_FALSE;
-
obj = _mesa_lookup_vao(ctx, id);
- if (obj == NULL)
- return GL_FALSE;
- return obj->EverBound;
+ return obj != NULL && obj->EverBound;
}