summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2008-05-06 22:13:06 -0600
committerBrian <brian.paul@tungstengraphics.com>2008-05-06 22:13:06 -0600
commit103ae5d16fd9fef566096570f731bb634a8025d4 (patch)
tree184578514c317c199b6b05bee1f3c57bf3e19877 /src/mesa/main
parent10f6ae0355937615d137c79c060b9e5a923f0d65 (diff)
gallium: implement full reference counting for vertex/fragment programs
Use _mesa_reference_vert/fragprog() wherever we assign program pointers. Fixes a memory corruption bug found with glean/api2 test. Another memory bug involving shaders yet to be fixed...
Diffstat (limited to 'src/mesa/main')
-rwxr-xr-xsrc/mesa/main/context.c26
-rw-r--r--src/mesa/main/mtypes.h4
-rw-r--r--src/mesa/main/state.c32
3 files changed, 38 insertions, 24 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 7b8d9341701..b9053344b26 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)
@@ -695,10 +693,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
@@ -1190,6 +1188,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 );
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 50b22d25bf3..463142fe395 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2203,10 +2203,10 @@ struct gl_shared_state
/*@{*/
struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
#if FEATURE_ARB_vertex_program
- struct gl_program *DefaultVertexProgram;
+ struct gl_vertex_program *DefaultVertexProgram;
#endif
#if FEATURE_ARB_fragment_program
- struct gl_program *DefaultFragmentProgram;
+ struct gl_fragment_program *DefaultFragmentProgram;
#endif
/*@}*/
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 0b1c56fdd5f..90379a17726 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -982,16 +982,20 @@ update_program(GLcontext *ctx)
#endif
if (shProg && shProg->LinkStatus && shProg->FragmentProgram) {
/* user-defined fragment shader */
- ctx->FragmentProgram._Current = shProg->FragmentProgram;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
+ shProg->FragmentProgram);
}
else if (ctx->FragmentProgram._Enabled) {
/* use user-defined fragment program */
- ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
+ ctx->FragmentProgram.Current);
}
else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
/* fragment program generated from fixed-function state */
- ctx->FragmentProgram._Current = _mesa_get_fixed_func_fragment_program(ctx);
- ctx->FragmentProgram._TexEnvProgram = ctx->FragmentProgram._Current;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
+ _mesa_get_fixed_func_fragment_program(ctx));
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
+ ctx->FragmentProgram._Current);
/* XXX get rid of this confusing stuff someday? */
ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
@@ -1000,7 +1004,7 @@ update_program(GLcontext *ctx)
}
else {
/* no fragment program */
- ctx->FragmentProgram._Current = NULL;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
}
if (ctx->FragmentProgram._Current != prevFP && ctx->Driver.BindProgram) {
@@ -1013,29 +1017,33 @@ update_program(GLcontext *ctx)
**/
#if 1
/* XXX get rid of this someday? */
- ctx->VertexProgram._TnlProgram = NULL;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
#endif
if (shProg && shProg->LinkStatus && shProg->VertexProgram) {
/* user-defined vertex shader */
- ctx->VertexProgram._Current = shProg->VertexProgram;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
+ shProg->VertexProgram);
}
else if (ctx->VertexProgram._Enabled) {
/* use user-defined vertex program */
- ctx->VertexProgram._Current = ctx->VertexProgram.Current;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
+ ctx->VertexProgram.Current);
}
else if (ctx->VertexProgram._MaintainTnlProgram) {
/* vertex program generated from fixed-function state */
- ctx->VertexProgram._Current = _mesa_get_fixed_func_vertex_program(ctx);
- ctx->VertexProgram._TnlProgram = ctx->VertexProgram._Current;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
+ _mesa_get_fixed_func_vertex_program(ctx));
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram,
+ ctx->VertexProgram._Current);
}
else {
/* no vertex program / used fixed-function code */
- ctx->VertexProgram._Current = NULL;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
}
if (ctx->VertexProgram._Current != prevVP && ctx->Driver.BindProgram) {
ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
- (struct gl_program *) ctx->VertexProgram._Current);
+ (struct gl_program *) ctx->VertexProgram._Current);
}
}