From 3ffd11f71d021f672b9bc15b3c39c155a0e2fecb Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 28 Feb 2008 21:27:16 +0800 Subject: mesa: separate shader program object from shader object. Currently a callback delete_shader_cb is used for deleting shader and shader program objects. Mesa detaches all attached shaders in _mesa_free_shader_program_data when deleting shader program objects. However it is likely that these shaders have been freed in _mesa_free_shader, which will result in unexpected behaviour. This fix uses a single callback for shader program objects and deletes shader program objects before shader objects. --- src/mesa/main/context.c | 24 ++++++++++++++++-------- src/mesa/main/mtypes.h | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index e3096b5f96..69c361f63e 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -444,6 +444,7 @@ alloc_shared_state( GLcontext *ctx ) ss->ArrayObjects = _mesa_NewHashTable(); #if FEATURE_ARB_shader_objects + ss->ShaderProgramObjects = _mesa_NewHashTable(); ss->ShaderObjects = _mesa_NewHashTable(); #endif @@ -523,6 +524,8 @@ 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 @@ -631,14 +634,17 @@ delete_shader_cb(GLuint id, void *data, void *userData) { GLcontext *ctx = (GLcontext *) userData; 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); - } + assert(sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER); + _mesa_free_shader(ctx, sh); +} + +static void +delete_shader_program_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); } /** @@ -721,6 +727,8 @@ 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_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx); _mesa_DeleteHashTable(ss->ShaderObjects); #endif diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index c8718a7f63..da60a469a4 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2202,8 +2202,8 @@ struct gl_shared_state #endif #if FEATURE_ARB_shader_objects - /** Table of both gl_shader and gl_shader_program objects */ struct _mesa_HashTable *ShaderObjects; + struct _mesa_HashTable *ShaderProgramObjects; #endif #if FEATURE_EXT_framebuffer_object -- cgit v1.2.3