summaryrefslogtreecommitdiff
path: root/src/mesa/main/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/context.c')
-rwxr-xr-xsrc/mesa/main/context.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 7b8d934170..893c79f28c 100755
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -150,8 +150,6 @@ int MESA_DEBUG_FLAGS = 0;
/* ubyte -> float conversion */
GLfloat _mesa_ubyte_to_float_color_tab[256];
-static void
-free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
/**
@@ -423,12 +421,14 @@ alloc_shared_state( GLcontext *ctx )
#endif
#if FEATURE_ARB_vertex_program
- ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
+ ss->DefaultVertexProgram = (struct gl_vertex_program *)
+ ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
if (!ss->DefaultVertexProgram)
goto cleanup;
#endif
#if FEATURE_ARB_fragment_program
- ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+ ss->DefaultFragmentProgram = (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
if (!ss->DefaultFragmentProgram)
goto cleanup;
#endif
@@ -513,12 +513,10 @@ alloc_shared_state( GLcontext *ctx )
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- if (ss->DefaultVertexProgram)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
+ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
#endif
#if FEATURE_ARB_fragment_program
- if (ss->DefaultFragmentProgram)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
+ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
#endif
#if FEATURE_ATI_fragment_shader
if (ss->DefaultFragmentShader)
@@ -633,6 +631,21 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData)
}
/**
+ * Callback for freeing shader program data. Call it before delete_shader_cb
+ * to avoid memory access error.
+ */
+static void
+free_shader_program_data_cb(GLuint id, void *data, void *userData)
+{
+ GLcontext *ctx = (GLcontext *) userData;
+ struct gl_shader_program *shProg = (struct gl_shader_program *) data;
+
+ if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
+ _mesa_free_shader_program_data(ctx, shProg);
+ }
+}
+
+/**
* Callback for deleting shader and shader programs objects.
* Called by _mesa_HashDeleteAll().
*/
@@ -695,10 +708,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
+ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
#endif
#if FEATURE_ARB_fragment_program
- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
+ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
#endif
#if FEATURE_ATI_fragment_shader
@@ -716,6 +729,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
+ _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
_mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
_mesa_DeleteHashTable(ss->ShaderObjects);
#endif
@@ -1190,6 +1204,14 @@ _mesa_free_context_data( GLcontext *ctx )
_mesa_unreference_framebuffer(&ctx->ReadBuffer);
}
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
+
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
+
_mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx );
_mesa_free_texture_data( ctx );