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:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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.
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
|
@@ -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++) {
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user