mesa: Enable true refcounting for NullBufferObj.

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.
This commit is contained in:
Michal Krol
2010-02-09 14:25:41 +01:00
parent eeec2c3d95
commit 01d7e3d5a2
8 changed files with 48 additions and 10 deletions

View File

@@ -95,6 +95,10 @@ unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj)
for (i = 0; i < Elements(obj->VertexAttrib); i++) for (i = 0; i < Elements(obj->VertexAttrib); i++)
_mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL); _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
} }

View 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. * Bind the specified target to buffer for the specified context.
* Called by glBindBuffer() and other functions. * Called by glBindBuffer() and other functions.

View File

@@ -59,6 +59,9 @@ _mesa_is_bufferobj(const struct gl_buffer_object *obj)
extern void extern void
_mesa_init_buffer_objects( GLcontext *ctx ); _mesa_init_buffer_objects( GLcontext *ctx );
extern void
_mesa_free_buffer_objects( GLcontext *ctx );
extern void extern void
_mesa_update_default_objects_buffer_objects(GLcontext *ctx); _mesa_update_default_objects_buffer_objects(GLcontext *ctx);

View File

@@ -955,6 +955,7 @@ _mesa_free_context_data( GLcontext *ctx )
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
_mesa_free_attrib_data(ctx); _mesa_free_attrib_data(ctx);
_mesa_free_buffer_objects(ctx);
_mesa_free_lighting_data( ctx ); _mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx ); _mesa_free_eval_data( ctx );
_mesa_free_texture_data( ctx ); _mesa_free_texture_data( ctx );
@@ -974,6 +975,7 @@ _mesa_free_context_data( GLcontext *ctx )
#if FEATURE_ARB_pixel_buffer_object #if FEATURE_ARB_pixel_buffer_object
_mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
_mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL); _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
_mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
#endif #endif
#if FEATURE_ARB_vertex_buffer_object #if FEATURE_ARB_vertex_buffer_object

View File

@@ -150,13 +150,17 @@ validate_pbo_access(GLcontext *ctx, struct gl_pixelstore_attrib *pack,
GLboolean ok; GLboolean ok;
/* Note, need to use DefaultPacking and Unpack's buffer object */ /* 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, ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
format, type, ptr); format, type, ptr);
/* restore */ /* restore */
ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; _mesa_reference_buffer_object(ctx,
&ctx->DefaultPacking.BufferObj,
ctx->Shared->NullBufferObj);
if (!ok) { if (!ok) {
_mesa_error(ctx, GL_INVALID_OPERATION, _mesa_error(ctx, GL_INVALID_OPERATION,

View File

@@ -95,12 +95,6 @@ _mesa_alloc_shared_state(GLcontext *ctx)
/* Allocate the default buffer object */ /* Allocate the default buffer object */
shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0); 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 */ /* Create default texture objects */
for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {

View File

@@ -249,17 +249,25 @@ void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state )
void _vbo_DestroyContext( GLcontext *ctx ) void _vbo_DestroyContext( GLcontext *ctx )
{ {
struct vbo_context *vbo = vbo_context(ctx);
if (ctx->aelt_context) { if (ctx->aelt_context) {
_ae_destroy_context( ctx ); _ae_destroy_context( ctx );
ctx->aelt_context = NULL; 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); vbo_exec_destroy(ctx);
#if FEATURE_dlist #if FEATURE_dlist
vbo_save_destroy(ctx); vbo_save_destroy(ctx);
#endif #endif
FREE(vbo_context(ctx)); FREE(vbo);
ctx->swtnl_im = NULL; ctx->swtnl_im = NULL;
} }
} }

View File

@@ -759,6 +759,7 @@ void vbo_use_buffer_objects(GLcontext *ctx)
} }
/* Allocate a real buffer object now */ /* Allocate a real buffer object now */
_mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target); exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj); 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; struct gl_client_array *arrays = exec->vtx.arrays;
unsigned i;
memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0]));
memcpy(arrays + 16, vbo->generic_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; exec->vtx.vertex_size = 0;