summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-05-16 09:56:59 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-05-16 15:40:44 -0600
commit470f69950577e05e3dfd09653c268cf22c034d7f (patch)
tree09beeee8f5cf1b9ec317d753b23946b7ce5bfe0e
parentffbd455a36f1d7600bd5b60e91768133d901d2f4 (diff)
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.
-rw-r--r--src/mesa/shader/shader_api.c29
-rw-r--r--src/mesa/shader/slang/slang_link.c32
2 files changed, 20 insertions, 41 deletions
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index badc457c1c0..fbaaf8ddea5 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -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;
}
}
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 8213b7772c2..80cd4b6df62 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -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 */
@@ -437,18 +437,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;*/
_mesa_problem(ctx, "_slang_resolve_attributes() failed");