void _vbo_DestroyContext(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); if (ctx->aelt_context) { _ae_destroy_context(ctx); ctx->aelt_context = NULL; } if (vbo) { GLuint i; for (i = 0; i < VBO_ATTRIB_MAX; i++) { _mesa_reference_buffer_object(ctx, &vbo->currval[i].BufferObj, NULL); } vbo_exec_destroy(ctx); if (ctx->API == API_OPENGL_COMPAT) vbo_save_destroy(ctx); _mesa_reference_vao(ctx, &vbo->VAO, NULL); free(vbo); ctx->vbo_context = NULL; } }
/** * Delete a set of array objects. * * \param n Number of array objects to delete. * \param ids Array of \c n array object IDs. */ void GLAPIENTRY _mesa_DeleteVertexArrays(GLsizei n, const GLuint *ids) { GET_CURRENT_CONTEXT(ctx); GLsizei i; if (n < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteVertexArray(n)"); return; } for (i = 0; i < n; i++) { struct gl_vertex_array_object *obj = _mesa_lookup_vao(ctx, ids[i]); if ( obj != NULL ) { ASSERT( obj->Name == ids[i] ); /* If the array object is currently bound, the spec says "the binding * for that object reverts to zero and the default vertex array * becomes current." */ if ( obj == ctx->Array.VAO ) { _mesa_BindVertexArray(0); } /* The ID is immediately freed for re-use */ remove_array_object(ctx, obj); /* Unreference the array object. * If refcount hits zero, the object will be deleted. */ _mesa_reference_vao(ctx, &obj, NULL); } } }
/** * Looks up the array object for the given ID. * * Unlike _mesa_lookup_vao, this function generates a GL_INVALID_OPERATION * error if the array object does not exist. It also returns the default * array object when ctx is a compatibility profile context and id is zero. */ struct gl_vertex_array_object * _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, const char *caller) { /* The ARB_direct_state_access specification says: * * "<vaobj> is [compatibility profile: * zero, indicating the default vertex array object, or] * the name of the vertex array object." */ if (id == 0) { if (ctx->API == API_OPENGL_CORE) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(zero is not valid vaobj name in a core profile " "context)", caller); return NULL; } return ctx->Array.DefaultVAO; } else { struct gl_vertex_array_object *vao; 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; } }
void _vbo_DestroyContext(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); if (ctx->aelt_context) { _ae_destroy_context(ctx); ctx->aelt_context = NULL; } if (vbo) { _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, NULL); vbo_exec_destroy(ctx); if (ctx->API == API_OPENGL_COMPAT) vbo_save_destroy(ctx); _mesa_reference_vao(ctx, &vbo->VAO, NULL); free(vbo); ctx->vbo_context = NULL; } }
/** * Helper for _mesa_BindVertexArray() and _mesa_BindVertexArrayAPPLE(). * \param genRequired specifies behavour when id was not generated with * glGenVertexArrays(). */ static void bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired) { struct gl_vertex_array_object * const oldObj = ctx->Array.VAO; struct gl_vertex_array_object *newObj = NULL; assert(oldObj != NULL); if ( oldObj->Name == id ) return; /* rebinding the same array object- no change */ /* * Get pointer to new array object (newObj) */ if (id == 0) { /* The spec says there is no array object named 0, but we use * one internally because it simplifies things. */ newObj = ctx->Array.DefaultVAO; } else { /* 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); } 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; } } if (ctx->Array.DrawMethod == DRAW_ARRAYS) { /* The _DrawArrays pointer is pointing at the VAO being unbound and * that VAO may be in the process of being deleted. If it's not going * to be deleted, this will have no effect, because the pointer needs * to be updated by the VBO module anyway. * * Before the VBO module can update the pointer, we have to set it * to NULL for drivers not to set up arrays which are not bound, * or to prevent a crash if the VAO being unbound is going to be * deleted. */ ctx->Array._DrawArrays = NULL; ctx->Array.DrawMethod = DRAW_NONE; } ctx->NewState |= _NEW_ARRAY; _mesa_reference_vao(ctx, &ctx->Array.VAO, newObj); }