Commit 01d7e3d5 authored by Michal Krol's avatar Michal Krol

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.
parent eeec2c3d
......@@ -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
}
......
......@@ -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.
......
......@@ -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);
......
......@@ -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
......
......@@ -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,
......
......@@ -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++) {
......
......@@ -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;
}
}
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment