Fix a program refcounting error, don't share program parameter lists.

The refcounting bug was causing a memleak (unfreed programs).
The old parameter list sharing is not needed since the change in how
uniforms are handled.
This commit is contained in:
Brian Paul 2008-05-16 09:56:59 -06:00
parent ffbd455a36
commit 470f699505
2 changed files with 20 additions and 41 deletions

View File

@ -75,21 +75,8 @@ void
_mesa_clear_shader_program_data(GLcontext *ctx,
struct gl_shader_program *shProg)
{
if (shProg->VertexProgram) {
/* Set ptr to NULL since the param list is shared with the
* original/unlinked program.
*/
shProg->VertexProgram->Base.Parameters = NULL;
_mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
}
if (shProg->FragmentProgram) {
/* Set ptr to NULL since the param list is shared with the
* original/unlinked program.
*/
shProg->FragmentProgram->Base.Parameters = NULL;
_mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
}
_mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
_mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
if (shProg->Uniforms) {
_mesa_free_uniform_list(shProg->Uniforms);
@ -176,8 +163,10 @@ _mesa_reference_shader_program(GLcontext *ctx,
ASSERT(old->RefCount > 0);
old->RefCount--;
/*printf("SHPROG DECR %p (%d) to %d\n",
(void*) old, old->Name, old->RefCount);*/
#if 0
printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
(void *) old, old->Name, old->RefCount);
#endif
deleteFlag = (old->RefCount == 0);
if (deleteFlag) {
@ -191,8 +180,10 @@ _mesa_reference_shader_program(GLcontext *ctx,
if (shProg) {
shProg->RefCount++;
/*printf("SHPROG INCR %p (%d) to %d\n",
(void*) shProg, shProg->Name, shProg->RefCount);*/
#if 0
printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
(void *) shProg, shProg->Name, shProg->RefCount);
#endif
*ptr = shProg;
}
}

View File

@ -406,20 +406,20 @@ _slang_link(GLcontext *ctx,
* Make copies of the vertex/fragment programs now since we'll be
* changing src/dst registers after merging the uniforms and varying vars.
*/
_mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
if (vertProg) {
_mesa_reference_vertprog(ctx, &shProg->VertexProgram,
vertex_program(_mesa_clone_program(ctx, &vertProg->Base)));
}
else {
_mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
struct gl_vertex_program *linked_vprog =
vertex_program(_mesa_clone_program(ctx, &vertProg->Base));
shProg->VertexProgram = linked_vprog; /* refcount OK */
ASSERT(shProg->VertexProgram->Base.RefCount == 1);
}
_mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
if (fragProg) {
_mesa_reference_fragprog(ctx, &shProg->FragmentProgram,
fragment_program(_mesa_clone_program(ctx, &fragProg->Base)));
}
else {
_mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
struct gl_fragment_program *linked_fprog =
fragment_program(_mesa_clone_program(ctx, &fragProg->Base));
shProg->FragmentProgram = linked_fprog; /* refcount OK */
ASSERT(shProg->FragmentProgram->Base.RefCount == 1);
}
/* link varying vars */
@ -436,18 +436,6 @@ _slang_link(GLcontext *ctx,
/*_mesa_print_uniforms(shProg->Uniforms);*/
if (shProg->VertexProgram) {
/* Rather than cloning the parameter list here, just share it.
* We need to be careful _mesa_clear_shader_program_data() in
* to avoid double-freeing.
*/
shProg->VertexProgram->Base.Parameters = vertProg->Base.Parameters;
}
if (shProg->FragmentProgram) {
/* see comment just above */
shProg->FragmentProgram->Base.Parameters = fragProg->Base.Parameters;
}
if (shProg->VertexProgram) {
if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) {
/*goto cleanup;*/