mesa: Enable true refcounting for NullBufferObj.
authorMichal Krol <michal@vmware.com>
Tue, 9 Feb 2010 13:25:41 +0000 (14:25 +0100)
committerMichal Krol <michal@vmware.com>
Tue, 9 Feb 2010 13:52:52 +0000 (14:52 +0100)
This object can be shared with another context, so we cannot just
delete it when the owning context is being destroyed.

Ensuring that buffer objects are properly refcounted guarantees
NullBufferObj is destroyed when all references to it are removed.

src/mesa/main/arrayobj.c
src/mesa/main/bufferobj.c
src/mesa/main/bufferobj.h
src/mesa/main/context.c
src/mesa/main/pixel.c
src/mesa/main/shared.c
src/mesa/vbo/vbo_context.c
src/mesa/vbo/vbo_exec_api.c

index fd35d4e38c95f10567233e663f73dd5919ce2f59..e36137d3782d6825f8fc25d150e716753ad2b1be 100644 (file)
@@ -95,6 +95,10 @@ unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj)
 
    for (i = 0; i < Elements(obj->VertexAttrib); i++)
       _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL);
+
+#if FEATURE_point_size_array
+   _mesa_reference_buffer_object(ctx, &obj->PointSize.BufferObj, NULL);
+#endif
 }
 
 
index 2271550efe110569fcb55de3fd309af17178a3f8..dabb1386ca4ca29638093520ad3089057867fd95 100644 (file)
@@ -556,6 +556,17 @@ _mesa_init_buffer_objects( GLcontext *ctx )
 }
 
 
+void
+_mesa_free_buffer_objects( GLcontext *ctx )
+{
+   _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
+   _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj, NULL);
+
+   _mesa_reference_buffer_object(ctx, &ctx->CopyReadBuffer, NULL);
+   _mesa_reference_buffer_object(ctx, &ctx->CopyWriteBuffer, NULL);
+}
+
+
 /**
  * Bind the specified target to buffer for the specified context.
  * Called by glBindBuffer() and other functions.
index 2931962ac08a3dfeb4cbaea5af94480cab0737ee..f8bca5ff717a2b17041c862b2dfbed7b43eb32b2 100644 (file)
@@ -59,6 +59,9 @@ _mesa_is_bufferobj(const struct gl_buffer_object *obj)
 extern void
 _mesa_init_buffer_objects( GLcontext *ctx );
 
+extern void
+_mesa_free_buffer_objects( GLcontext *ctx );
+
 extern void
 _mesa_update_default_objects_buffer_objects(GLcontext *ctx);
 
index fccce51e8521fdd7560445af3f3d5995129301e2..591aa1121d129dec33e98d0956738089bd748b02 100644 (file)
@@ -955,6 +955,7 @@ _mesa_free_context_data( GLcontext *ctx )
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
 
    _mesa_free_attrib_data(ctx);
+   _mesa_free_buffer_objects(ctx);
    _mesa_free_lighting_data( ctx );
    _mesa_free_eval_data( ctx );
    _mesa_free_texture_data( ctx );
@@ -974,6 +975,7 @@ _mesa_free_context_data( GLcontext *ctx )
 #if FEATURE_ARB_pixel_buffer_object
    _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
    _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
+   _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
 #endif
 
 #if FEATURE_ARB_vertex_buffer_object
index f6f9c1173a1473053280d61e293aa341e764681e..ca6ecd7bfb6b15ffe322eb7cecc41391da24b2f2 100644 (file)
@@ -150,13 +150,17 @@ validate_pbo_access(GLcontext *ctx, struct gl_pixelstore_attrib *pack,
    GLboolean ok;
 
    /* Note, need to use DefaultPacking and Unpack's buffer object */
-   ctx->DefaultPacking.BufferObj = pack->BufferObj;
+   _mesa_reference_buffer_object(ctx,
+                                 &ctx->DefaultPacking.BufferObj,
+                                 pack->BufferObj);
 
    ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
                                   format, type, ptr);
 
    /* restore */
-   ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
+   _mesa_reference_buffer_object(ctx,
+                                 &ctx->DefaultPacking.BufferObj,
+                                 ctx->Shared->NullBufferObj);
 
    if (!ok) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
index a7cf623c47dbe9421f3479299c32b54d3254ce2f..b889364f0dc19ef4ab4f18ee3137ddafb7cfdcaf 100644 (file)
@@ -95,12 +95,6 @@ _mesa_alloc_shared_state(GLcontext *ctx)
 
    /* Allocate the default buffer object */
    shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0);
-#ifndef DEBUG
-   /* Set refcount so high that it never gets deleted.
-    * XXX with recent/improved refcounting this should be no longer be needed.
-    */
-   shared->NullBufferObj->RefCount = 1000 * 1000 * 1000;
-#endif
 
    /* Create default texture objects */
    for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
index 75c32e0b9bedb89c58454ee0984986804af66998..a5b0070bd3cceeb05378bf1f2a9c61ba038d884d 100644 (file)
@@ -249,17 +249,25 @@ void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state )
 
 void _vbo_DestroyContext( GLcontext *ctx )
 {
+   struct vbo_context *vbo = vbo_context(ctx);
+
    if (ctx->aelt_context) {
       _ae_destroy_context( ctx );
       ctx->aelt_context = NULL;
    }
 
-   if (vbo_context(ctx)) {
+   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 FEATURE_dlist
       vbo_save_destroy(ctx);
 #endif
-      FREE(vbo_context(ctx));
+      FREE(vbo);
       ctx->swtnl_im = NULL;
    }
 }
index f0a7eeadd0f8194a05d34929c0833ff52a066b63..8ee14be26102fee88d93cde4a01f6cc79a4b84d8 100644 (file)
@@ -759,6 +759,7 @@ void vbo_use_buffer_objects(GLcontext *ctx)
    }
 
    /* Allocate a real buffer object now */
+   _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
    exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
    ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
 }
@@ -803,8 +804,19 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
    
    {
       struct gl_client_array *arrays = exec->vtx.arrays;
+      unsigned i;
+
       memcpy(arrays,      vbo->legacy_currval,  16 * sizeof(arrays[0]));
       memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0]));
+
+      for (i = 0; i < 16; ++i) {
+         arrays[i     ].BufferObj = NULL;
+         arrays[i + 16].BufferObj = NULL;
+         _mesa_reference_buffer_object(ctx, &arrays[i     ].BufferObj,
+                                       vbo->legacy_currval[i].BufferObj);
+         _mesa_reference_buffer_object(ctx, &arrays[i + 16].BufferObj,
+                                       vbo->generic_currval[i].BufferObj);
+      }
    }
 
    exec->vtx.vertex_size = 0;