/** * Update the fields of a vertex array structure. * We need to do a few special things for arrays that live in * vertex buffer objects. */ static void update_array(GLcontext *ctx, struct gl_client_array *array, GLuint dirtyFlag, GLsizei elementSize, GLint size, GLenum type, GLsizei stride, GLboolean normalized, const GLvoid *ptr) { array->Size = size; array->Type = type; array->Stride = stride; array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Ptr = (const GLubyte *) ptr; #if FEATURE_ARB_vertex_buffer_object array->BufferObj->RefCount--; if (array->BufferObj->RefCount <= 0) { ASSERT(array->BufferObj->Name); _mesa_remove_buffer_object( ctx, array->BufferObj ); (*ctx->Driver.DeleteBuffer)( ctx, array->BufferObj ); } array->BufferObj = ctx->Array.ArrayBufferObj; array->BufferObj->RefCount++; /* Compute the index of the last array element that's inside the buffer. * Later in glDrawArrays we'll check if start + count > _MaxElement to * be sure we won't go out of bounds. */ if (ctx->Array.ArrayBufferObj->Name) array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size - (GLsizeiptrARB) array->Ptr) / array->StrideB; else #endif array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= dirtyFlag; }
/** * Delete a set of buffer objects. * * \param n Number of buffer objects to delete. * \param ids Array of \c n buffer object IDs. */ void GLAPIENTRY _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids) { GET_CURRENT_CONTEXT(ctx); GLsizei i; ASSERT_OUTSIDE_BEGIN_END(ctx); if (n < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteBuffersARB(n)"); return; } _glthread_LOCK_MUTEX(ctx->Shared->Mutex); for (i = 0; i < n; i++) { if (ids[i] != 0) { struct gl_buffer_object *bufObj = (struct gl_buffer_object *) _mesa_HashLookup(ctx->Shared->BufferObjects, ids[i]); if (bufObj) { /* unbind any vertex pointers bound to this buffer */ GLuint j; ASSERT(bufObj->Name == ids[i]); if (ctx->Array.Vertex.BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.Vertex.BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } if (ctx->Array.Normal.BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.Normal.BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } if (ctx->Array.Color.BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.Color.BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } if (ctx->Array.SecondaryColor.BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.SecondaryColor.BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } if (ctx->Array.FogCoord.BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.FogCoord.BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } if (ctx->Array.Index.BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.Index.BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } if (ctx->Array.EdgeFlag.BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.EdgeFlag.BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } for (j = 0; j < MAX_TEXTURE_UNITS; j++) { if (ctx->Array.TexCoord[j].BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.TexCoord[j].BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } } for (j = 0; j < VERT_ATTRIB_MAX; j++) { if (ctx->Array.VertexAttrib[j].BufferObj == bufObj) { bufObj->RefCount--; ctx->Array.VertexAttrib[j].BufferObj = ctx->Array.NullBufferObj; ctx->Array.NullBufferObj->RefCount++; } } if (ctx->Array.ArrayBufferObj == bufObj) { _mesa_BindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); } if (ctx->Array.ElementArrayBufferObj == bufObj) { _mesa_BindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 ); } if (ctx->Pack.BufferObj == bufObj) { _mesa_BindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, 0 ); } if (ctx->Unpack.BufferObj == bufObj) { _mesa_BindBufferARB( GL_PIXEL_UNPACK_BUFFER_EXT, 0 ); } /* The ID is immediately freed for re-use */ _mesa_remove_buffer_object(ctx, bufObj); bufObj->RefCount--; if (bufObj->RefCount <= 0) { ASSERT(ctx->Array.ArrayBufferObj != bufObj); ASSERT(ctx->Array.ElementArrayBufferObj != bufObj); ASSERT(ctx->Array.Vertex.BufferObj != bufObj); ASSERT(ctx->Driver.DeleteBuffer); ctx->Driver.DeleteBuffer(ctx, bufObj); } } } } _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); }