summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2011-10-23 20:22:23 +0100
committerNeil Roberts <neil@linux.intel.com>2011-10-24 14:35:58 +0100
commit6ce87a0877726eaa432c7ee5fc46c8a04e52f4f3 (patch)
tree2c46c45e740ace421ec6162f8634bfeb8400a233
parentede125103ca6db0c9b638a2d853c8de4b6b50a0a (diff)
downloadcogl-6ce87a0877726eaa432c7ee5fc46c8a04e52f4f3.tar.gz
pipeline: Reset last_used_for_pipeline when the pipeline is destroyed
Both the GLSL and the ARBfp pipeline backends were using a variable called last_used_for_pipeline to keep track of the last pipeline that the shader or program state was used for. If this address is the same as last time when the pipeline state is flushed then Cogl will only flush the uniforms that have been modified, otherwise it will flush all of them. The problem with this is that there was nothing to keep that address alive so it could be destroyed and reused for a different pipeline by the time the shader state is reused. This is quite likely to happen in an application using legacy state because in that case the shader state will always be used with a one-shot pipeline that will likely be recycled in the next frame. There is already a destroy callback to unref the shader state when the pipeline is destroyed so this patch just makes that callback also clear the last_used_for_pipeline pointer if it matches the pipeline being destroyed. https://bugzilla.gnome.org/show_bug.cgi?id=662542 Reviewed-by: Robert Bragg <robert@linux.intel.com> (cherry picked from commit 49e733fcdcb12978ae165c6352e2c0acb6bc6757)
-rw-r--r--cogl/cogl-pipeline-fragend-arbfp.c18
-rw-r--r--cogl/cogl-pipeline-progend-glsl.c18
2 files changed, 26 insertions, 10 deletions
diff --git a/cogl/cogl-pipeline-fragend-arbfp.c b/cogl/cogl-pipeline-fragend-arbfp.c
index 11538a0d..c07a8fb1 100644
--- a/cogl/cogl-pipeline-fragend-arbfp.c
+++ b/cogl/cogl-pipeline-fragend-arbfp.c
@@ -107,12 +107,20 @@ get_shader_state (CoglPipeline *pipeline)
}
static void
-destroy_shader_state (void *user_data)
+destroy_shader_state (void *user_data,
+ void *instance)
{
CoglPipelineShaderState *shader_state = user_data;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
+ /* If the shader state was last used for this pipeline then clear it
+ so that if same address gets used again for a new pipeline then
+ we won't think it's the same pipeline and avoid updating the
+ constants */
+ if (shader_state->last_used_for_pipeline == instance)
+ shader_state->last_used_for_pipeline = NULL;
+
if (--shader_state->ref_count == 0)
{
if (shader_state->gl_program)
@@ -130,10 +138,10 @@ destroy_shader_state (void *user_data)
static void
set_shader_state (CoglPipeline *pipeline, CoglPipelineShaderState *shader_state)
{
- cogl_object_set_user_data (COGL_OBJECT (pipeline),
- &shader_state_key,
- shader_state,
- destroy_shader_state);
+ _cogl_object_set_user_data (COGL_OBJECT (pipeline),
+ &shader_state_key,
+ shader_state,
+ destroy_shader_state);
}
static void
diff --git a/cogl/cogl-pipeline-progend-glsl.c b/cogl/cogl-pipeline-progend-glsl.c
index 4a6fa78e..bade8531 100644
--- a/cogl/cogl-pipeline-progend-glsl.c
+++ b/cogl/cogl-pipeline-progend-glsl.c
@@ -318,12 +318,20 @@ program_state_new (int n_layers)
}
static void
-destroy_program_state (void *user_data)
+destroy_program_state (void *user_data,
+ void *instance)
{
CoglPipelineProgramState *program_state = user_data;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
+ /* If the program state was last used for this pipeline then clear
+ it so that if same address gets used again for a new pipeline
+ then we won't think it's the same pipeline and avoid updating the
+ uniforms */
+ if (program_state->last_used_for_pipeline == instance)
+ program_state->last_used_for_pipeline = NULL;
+
if (--program_state->ref_count == 0)
{
#ifdef HAVE_COGL_GLES2
@@ -347,10 +355,10 @@ static void
set_program_state (CoglPipeline *pipeline,
CoglPipelineProgramState *program_state)
{
- cogl_object_set_user_data (COGL_OBJECT (pipeline),
- &program_state_key,
- program_state,
- destroy_program_state);
+ _cogl_object_set_user_data (COGL_OBJECT (pipeline),
+ &program_state_key,
+ program_state,
+ destroy_program_state);
}
static void