Ejemplo n.º 1
0
/**
 * 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;
}
Ejemplo n.º 2
0
/**
 * 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);
}