summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-08-14 11:56:59 +0100
committerBrian <brian.paul@tungstengraphics.com>2007-08-14 11:58:37 +0100
commitdc73217294efcba83c46183ed2f208250217486f (patch)
tree1a79d59f479740d58c2bad548a386efa8c71889f /src/mesa
parent5dab3bf4bc94ac45e4d25c75dc09fbd6f4a6025e (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/mesa')
-rw-r--r--src/mesa/main/context.c66
-rw-r--r--src/mesa/main/texobj.c5
2 files changed, 43 insertions, 28 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 5fbc69693e..37a14d3004 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -647,6 +647,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);
}
@@ -657,6 +662,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);
}
@@ -683,23 +689,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);
- ctx->Driver.DeleteTexture(ctx, ss->Default1DArray);
- ctx->Driver.DeleteTexture(ctx, ss->Default2DArray);
-
- /* 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);
@@ -737,6 +726,23 @@ 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);
+ ctx->Driver.DeleteTexture(ctx, ss->Default1DArray);
+ ctx->Driver.DeleteTexture(ctx, ss->Default2DArray);
+ /* all other textures */
+ _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
+ _mesa_DeleteHashTable(ss->TexObjects);
+
_glthread_DESTROY_MUTEX(ss->Mutex);
_mesa_free(ss);
@@ -1190,18 +1196,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 );
@@ -1233,6 +1240,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 ac70e5a22e..ea3328a047 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;