diff options
author | Brian <[email protected]> | 2007-08-14 11:57:16 +0100 |
---|---|---|
committer | Brian <[email protected]> | 2007-08-14 11:57:16 +0100 |
commit | 75ebda3ce66ccfd5b4de695c11a8793afb22b829 (patch) | |
tree | 02a339def98579bf89530157b306e0d2519f8b8c /src | |
parent | 53ff15fcbfecc76dbda94649e22bcf3112f74b23 (diff) |
Fix a few more problems with freeing FBOs/textures during context destruction.
Free FBOs before textures since the later may be referenced by the former.
Need to bind the context we're destroying if there isn't a current context
so that ctx->DeleteTexture() etc can be used.
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/main/context.c | 61 | ||||
-rw-r--r-- | src/mesa/main/texobj.c | 5 |
2 files changed, 41 insertions, 25 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index ee59f0e4664..4c1b5386a6e 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -635,6 +635,11 @@ static void delete_framebuffer_cb(GLuint id, void *data, void *userData) { struct gl_framebuffer *fb = (struct gl_framebuffer *) data; + /* The fact that the framebuffer is in the hashtable means its refcount + * is one, but we're removing from the hashtable now. So clear refcount. + */ + /*assert(fb->RefCount == 1);*/ + fb->RefCount = 0; fb->Delete(fb); } @@ -645,6 +650,7 @@ static void delete_renderbuffer_cb(GLuint id, void *data, void *userData) { struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data; + rb->RefCount = 0; /* see comment for FBOs above */ rb->Delete(rb); } @@ -671,20 +677,6 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx); _mesa_DeleteHashTable(ss->DisplayList); - /* - * Free texture objects - */ - ASSERT(ctx->Driver.DeleteTexture); - /* the default textures */ - ctx->Driver.DeleteTexture(ctx, ss->Default1D); - ctx->Driver.DeleteTexture(ctx, ss->Default2D); - ctx->Driver.DeleteTexture(ctx, ss->Default3D); - ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap); - ctx->Driver.DeleteTexture(ctx, ss->DefaultRect); - /* all other textures */ - _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx); - _mesa_DeleteHashTable(ss->TexObjects); - #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program) _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx); _mesa_DeleteHashTable(ss->Programs); @@ -722,6 +714,21 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->RenderBuffers); #endif + /* + * Free texture objects (after FBOs since some textures might have + * been bound to FBOs). + */ + ASSERT(ctx->Driver.DeleteTexture); + /* the default textures */ + ctx->Driver.DeleteTexture(ctx, ss->Default1D); + ctx->Driver.DeleteTexture(ctx, ss->Default2D); + ctx->Driver.DeleteTexture(ctx, ss->Default3D); + ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap); + ctx->Driver.DeleteTexture(ctx, ss->DefaultRect); + /* all other textures */ + _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx); + _mesa_DeleteHashTable(ss->TexObjects); + _glthread_DESTROY_MUTEX(ss->Mutex); _mesa_free(ss); @@ -1174,18 +1181,19 @@ _mesa_create_context(const GLvisual *visual, void _mesa_free_context_data( GLcontext *ctx ) { - /* if we're destroying the current context, unbind it first */ - if (ctx == _mesa_get_current_context()) { - _mesa_make_current(NULL, NULL, NULL); - } - else { - /* unreference WinSysDraw/Read buffers */ - _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer); - _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer); - _mesa_unreference_framebuffer(&ctx->DrawBuffer); - _mesa_unreference_framebuffer(&ctx->ReadBuffer); + if (!_mesa_get_current_context()){ + /* No current context, but we may need one in order to delete + * texture objs, etc. So temporarily bind the context now. + */ + _mesa_make_current(ctx, NULL, NULL); } + /* unreference WinSysDraw/Read buffers */ + _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer); + _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer); + _mesa_unreference_framebuffer(&ctx->DrawBuffer); + _mesa_unreference_framebuffer(&ctx->ReadBuffer); + _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); @@ -1217,6 +1225,11 @@ _mesa_free_context_data( GLcontext *ctx ) if (ctx->Extensions.String) _mesa_free((void *) ctx->Extensions.String); + + /* unbind the context if it's currently bound */ + if (ctx == _mesa_get_current_context()) { + _mesa_make_current(NULL, NULL, NULL); + } } diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 78225b1dd96..06f1f815b1b 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -287,7 +287,10 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, if (deleteFlag) { GET_CURRENT_CONTEXT(ctx); - ctx->Driver.DeleteTexture(ctx, oldTex); + if (ctx) + ctx->Driver.DeleteTexture(ctx, oldTex); + else + _mesa_problem(NULL, "Unable to delete texture, no context"); } *ptr = NULL; |