Do more bookkeeping of vertex buffer object reference counts.
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 11 Feb 2004 22:06:05 +0000 (22:06 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 11 Feb 2004 22:06:05 +0000 (22:06 +0000)
Incr/decr counts when doing glPush/PopClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT).

src/mesa/main/attrib.c
src/mesa/main/bufferobj.c
src/mesa/main/varray.c

index c5339fdbf35da24007c8dd545a7a20b95e9cb5e2..e3423c74170a6b8f6203f63c5335fa2f4560e6c6 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -1143,6 +1142,31 @@ _mesa_PopAttrib(void)
 }
 
 
+/**
+ * Helper for incrementing/decrementing vertex buffer object reference
+ * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group.
+ */
+static void
+adjust_buffer_object_ref_counts(struct gl_array_attrib *array, GLint step)
+{
+   GLuint i;
+   array->Vertex.BufferObj->RefCount += step;
+   array->Normal.BufferObj->RefCount += step;
+   array->Color.BufferObj->RefCount += step;
+   array->SecondaryColor.BufferObj->RefCount += step;
+   array->FogCoord.BufferObj->RefCount += step;
+   array->Index.BufferObj->RefCount += step;
+   array->EdgeFlag.BufferObj->RefCount += step;
+   for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++)
+      array->TexCoord[i].BufferObj->RefCount += step;
+   for (i = 0; i < VERT_ATTRIB_MAX; i++)
+      array->VertexAttrib[i].BufferObj->RefCount += step;
+
+   array->ArrayBufferObj->RefCount += step;
+   array->ElementArrayBufferObj->RefCount += step;
+}
+
+
 #define GL_CLIENT_PACK_BIT (1<<20)
 #define GL_CLIENT_UNPACK_BIT (1<<21)
 
@@ -1190,6 +1214,8 @@ _mesa_PushClientAttrib(GLbitfield mask)
       newnode->data = attr;
       newnode->next = head;
       head = newnode;
+      /* bump reference counts on buffer objects */
+      adjust_buffer_object_ref_counts(&ctx->Array, 1);
    }
 
    ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
@@ -1228,8 +1254,10 @@ _mesa_PopClientAttrib(void)
            ctx->NewState |= _NEW_PACKUNPACK;
             break;
          case GL_CLIENT_VERTEX_ARRAY_BIT:
+            adjust_buffer_object_ref_counts(&ctx->Array, -1);
             MEMCPY( &ctx->Array, attr->data,
                    sizeof(struct gl_array_attrib) );
+            /* decrement reference counts on buffer objects */
            ctx->NewState |= _NEW_ARRAY;
             break;
          default:
index 25457183431bd061d91f43c9317ab4dc5f28b816..97893b721dbf2b9a40476c69e18d07684c96cfe5 100644 (file)
@@ -329,7 +329,13 @@ _mesa_init_buffer_objects( GLcontext *ctx )
 {
    GLuint i;
 
+   /* Allocate the default buffer object and set refcount so high that
+    * it never gets deleted.
+    */
    ctx->Array.NullBufferObj = _mesa_new_buffer_object(ctx, 0, 0);
+   if (ctx->Array.NullBufferObj)
+      ctx->Array.NullBufferObj->RefCount = 1000;
+
    ctx->Array.ArrayBufferObj = ctx->Array.NullBufferObj;
    ctx->Array.ElementArrayBufferObj = ctx->Array.NullBufferObj;
 
index c9896ae3ca642e702df89594fa6e80b2367c85ff..c0b7bcfabe9a07b3f4b7bd3979da50a3a6f6992d 100644 (file)
@@ -58,7 +58,9 @@ update_array(GLcontext *ctx, struct gl_client_array *array,
    array->Ptr = (const GLubyte *) ptr;
 #if FEATURE_ARB_vertex_buffer_object
    array->BufferObj->RefCount--;
-   /* XXX free buffer object if RefCount == 0 ? */
+   if (array->BufferObj->RefCount <= 0) {
+      (*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.