summaryrefslogtreecommitdiff
path: root/src/mesa/main/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/context.c')
-rw-r--r--src/mesa/main/context.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 63dc1379e9..d94876e70b 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -444,7 +444,6 @@ alloc_shared_state( GLcontext *ctx )
ss->ArrayObjects = _mesa_NewHashTable();
#if FEATURE_ARB_shader_objects
- ss->ShaderProgramObjects = _mesa_NewHashTable();
ss->ShaderObjects = _mesa_NewHashTable();
#endif
@@ -524,8 +523,6 @@ cleanup:
_mesa_DeleteHashTable (ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
- if (ss->ShaderProgramObjects)
- _mesa_DeleteHashTable (ss->ShaderProgramObjects);
if (ss->ShaderObjects)
_mesa_DeleteHashTable (ss->ShaderObjects);
#endif
@@ -626,25 +623,37 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData)
}
/**
- * Callback for deleting shader and shader programs objects.
- * Called by _mesa_HashDeleteAll().
+ * Callback for freeing shader program data. Call it before delete_shader_cb
+ * to avoid memory access error.
*/
static void
-delete_shader_cb(GLuint id, void *data, void *userData)
+free_shader_program_data_cb(GLuint id, void *data, void *userData)
{
GLcontext *ctx = (GLcontext *) userData;
- struct gl_shader *sh = (struct gl_shader *) data;
- assert(sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER);
- _mesa_free_shader(ctx, sh);
+ 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().
+ */
static void
-delete_shader_program_cb(GLuint id, void *data, void *userData)
+delete_shader_cb(GLuint id, void *data, void *userData)
{
GLcontext *ctx = (GLcontext *) userData;
- struct gl_shader_program *shProg = (struct gl_shader_program *) data;
- assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
- _mesa_free_shader_program(ctx, shProg);
+ struct gl_shader *sh = (struct gl_shader *) data;
+ if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
+ _mesa_free_shader(ctx, sh);
+ }
+ else {
+ struct gl_shader_program *shProg = (struct gl_shader_program *) data;
+ ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
+ _mesa_free_shader_program(ctx, shProg);
+ }
}
/**
@@ -706,10 +715,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- _mesa_delete_program(ctx, ss->DefaultVertexProgram);
+ ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
#endif
#if FEATURE_ARB_fragment_program
- _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
+ ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
#endif
#if FEATURE_ATI_fragment_shader
@@ -727,8 +736,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
- _mesa_HashDeleteAll(ss->ShaderProgramObjects, delete_shader_program_cb, ctx);
- _mesa_DeleteHashTable(ss->ShaderProgramObjects);
+ _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
_mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
_mesa_DeleteHashTable(ss->ShaderObjects);
#endif