[cogl/wip/neil/pipeline-uniforms: 13/17] Stash
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/neil/pipeline-uniforms: 13/17] Stash
- Date: Wed, 2 Nov 2011 14:06:02 +0000 (UTC)
commit fb576aa4970757c95e18bce43ee6057464a4ad34
Author: Neil Roberts <neil linux intel com>
Date: Fri Oct 28 15:01:09 2011 +0100
Stash
cogl/cogl-context.c | 7 ++++-
cogl/cogl-pipeline-progend-glsl.c | 56 +++++++++++++++++++++++++++++++++++-
cogl/cogl-pipeline-state-private.h | 4 ++
cogl/cogl-pipeline-state.c | 17 ++++++++---
cogl/cogl-pipeline-state.h | 5 +++
cogl/cogl-pipeline.c | 31 +++++++++++---------
6 files changed, 99 insertions(+), 21 deletions(-)
---
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index 6f64cc6..9058625 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -221,7 +221,12 @@ cogl_context_new (CoglDisplay *display,
g_assert_not_reached ();
}
- context->uniform_names = NULL;
+ /* We don't need a destructor for the uniform name string because
+ it is contained within the allocation of the struct */
+ context->uniform_names = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ g_free);
/* Initialise the driver specific state */
_cogl_init_feature_overrides (context);
diff --git a/cogl/cogl-pipeline-progend-glsl.c b/cogl/cogl-pipeline-progend-glsl.c
index c82bc76..6d94a14 100644
--- a/cogl/cogl-pipeline-progend-glsl.c
+++ b/cogl/cogl-pipeline-progend-glsl.c
@@ -140,6 +140,17 @@ typedef struct
* so know if we need to update all of the uniforms */
CoglPipeline *last_used_for_pipeline;
+ /* TRUE if any of the uniforms on this pipeline have been modified
+ since it was last flushed. If so then we'll flush all of the
+ uniforms that this pipeline overrides (but not necessarily those
+ that the parent overrides if we've already flushed them) */
+ gboolean uniforms_changed;
+
+ /* Array of GL uniform locations indexed by Cogl's uniform
+ location. We are careful only to allocated this array if a custom
+ uniform is actually set */
+ GArray *uniform_locations;
+
UnitState *unit_state;
} CoglPipelineProgramState;
@@ -309,6 +320,8 @@ program_state_new (int n_layers)
program_state->program = 0;
program_state->n_tex_coord_attribs = 0;
program_state->unit_state = g_new (UnitState, n_layers);
+ program_state->uniforms_changed = TRUE;
+ program_state->uniform_locations = NULL;
#ifdef HAVE_COGL_GLES2
program_state->tex_coord_attribute_locations = NULL;
program_state->flushed_modelview_stack = NULL;
@@ -349,6 +362,9 @@ destroy_program_state (void *user_data,
g_free (program_state->unit_state);
+ if (program_state->uniform_locations)
+ g_array_free (program_state->uniform_locations, TRUE);
+
g_slice_free (CoglPipelineProgramState, program_state);
}
}
@@ -540,6 +556,34 @@ update_builtin_uniforms (CoglPipeline *pipeline,
#endif /* HAVE_COGL_GLES2 */
static void
+_cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline,
+ CoglPipelineProgramState *
+ program_state,
+ GLuint gl_program,
+ gboolean program_changed)
+{
+ CoglPipeline *flushed_ancestor;
+
+ /* Try to find a common ancestor for the values that were already
+ flushed on the pipeline that this program state was last used for
+ so we can avoid flushing those */
+
+ if (program_changed)
+ {
+ /* The program has changed so we have no common ancestor and we
+ need to flush everything */
+ flushed_ancestor = NULL;
+ /* All of the uniform locations are invalid */
+ if (program_state->uniform_locations)
+ g_array_set_size (program_state->uniform_locations, 0);
+ }
+ else
+ {
+ flushed_ancestor = program_state->last_used_for_pipeline;
+ }
+}
+
+static void
_cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
unsigned long pipelines_difference,
int n_tex_coord_attribs)
@@ -746,6 +790,11 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
}
#endif
+ _cogl_pipeline_progend_glsl_flush_uniforms (pipeline,
+ program_state,
+ gl_program,
+ program_changed);
+
if (user_program)
_cogl_program_flush_uniforms (user_program,
gl_program,
@@ -765,7 +814,12 @@ _cogl_pipeline_progend_glsl_pre_change_notify (CoglPipeline *pipeline,
if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx)))
dirty_program_state (pipeline);
-
+ else if ((change & COGL_PIPELINE_STATE_UNIFORMS))
+ {
+ CoglPipelineProgramState *program_state = get_program_state (pipeline);
+ if (program_state)
+ program_state->uniforms_changed = TRUE;
+ }
#ifdef HAVE_COGL_GLES2
else if (ctx->driver == COGL_DRIVER_GLES2)
{
diff --git a/cogl/cogl-pipeline-state-private.h b/cogl/cogl-pipeline-state-private.h
index 8b8fe3f..dbc0bc6 100644
--- a/cogl/cogl-pipeline-state-private.h
+++ b/cogl/cogl-pipeline-state-private.h
@@ -143,4 +143,8 @@ void
_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority,
CoglPipelineHashState *state);
+void
+_cogl_pipeline_hash_uniforms_state (CoglPipeline *authority,
+ CoglPipelineHashState *state);
+
#endif /* __COGL_PIPELINE_STATE_PRIVATE_H */
diff --git a/cogl/cogl-pipeline-state.c b/cogl/cogl-pipeline-state.c
index 21fce94..e1c2a49 100644
--- a/cogl/cogl-pipeline-state.c
+++ b/cogl/cogl-pipeline-state.c
@@ -1384,9 +1384,8 @@ static CoglBoxedValue *
_cogl_pipeline_override_uniform (CoglPipeline *pipeline,
int location)
{
- CoglPipelineState state = COGL_PIPELINE_STATE_POINT_SIZE;
+ CoglPipelineState state = COGL_PIPELINE_STATE_UNIFORMS;
CoglPipelineUniformsState *uniforms_state;
- CoglPipeline *authority;
FindUniformOverrideClosure find_data;
CoglPipelineUniformOverride *override;
@@ -1397,8 +1396,6 @@ _cogl_pipeline_override_uniform (CoglPipeline *pipeline,
g_return_val_if_fail (location < g_hash_table_size (ctx->uniform_names),
NULL);
- authority = _cogl_pipeline_get_authority (pipeline, state);
-
/* - Flush journal primitives referencing the current state.
* - Make sure the pipeline has no dependants so it may be modified.
* - If the pipeline isn't currently an authority for the state being
@@ -1406,7 +1403,7 @@ _cogl_pipeline_override_uniform (CoglPipeline *pipeline,
*/
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
- uniforms_state = &authority->big_state->uniforms_state;
+ uniforms_state = &pipeline->big_state->uniforms_state;
find_data.previous_override = NULL;
find_data.found_override = NULL;
@@ -1643,3 +1640,13 @@ _cogl_pipeline_hash_cull_face_state (CoglPipeline *authority,
cull_face_state,
sizeof (CoglPipelineCullFaceState));
}
+
+void
+_cogl_pipeline_hash_uniforms_state (CoglPipeline *authority,
+ CoglPipelineHashState *state)
+{
+ /* This isn't used anywhere yet because the uniform state doesn't
+ affect program generation. It's quite a hassle to implement so
+ let's just leave it until something actually needs it */
+ g_warn_if_reached ();
+}
diff --git a/cogl/cogl-pipeline-state.h b/cogl/cogl-pipeline-state.h
index 7015b00..fa97863 100644
--- a/cogl/cogl-pipeline-state.h
+++ b/cogl/cogl-pipeline-state.h
@@ -686,6 +686,11 @@ void
cogl_pipeline_get_depth_state (CoglPipeline *pipeline,
CoglDepthState *state_out);
+void
+cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline,
+ int uniform_location,
+ float value);
+
#endif /* COGL_ENABLE_EXPERIMENTAL_API */
G_END_DECLS
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index 762cdec..5575f2b 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -111,6 +111,7 @@ _cogl_pipeline_init_default_pipeline (void)
CoglDepthState *depth_state = &big_state->depth_state;
CoglPipelineLogicOpsState *logic_ops_state = &big_state->logic_ops_state;
CoglPipelineCullFaceState *cull_face_state = &big_state->cull_face_state;
+ CoglPipelineUniformsState *uniforms_state = &big_state->uniforms_state;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@@ -221,6 +222,9 @@ _cogl_pipeline_init_default_pipeline (void)
cull_face_state->mode = COGL_PIPELINE_CULL_FACE_MODE_NONE;
cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE;
+ _cogl_bitmask_init (&uniforms_state->override_mask);
+ COGL_SLIST_INIT (&uniforms_state->override_list);
+
ctx->default_pipeline = _cogl_pipeline_object_new (pipeline);
}
@@ -1029,6 +1033,13 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline,
sizeof (CoglPipelineCullFaceState));
break;
}
+ case COGL_PIPELINE_STATE_UNIFORMS:
+ {
+ CoglPipelineUniformsState *uniforms_state =
+ &pipeline->big_state->uniforms_state;
+ _cogl_bitmask_init (&uniforms_state->override_mask);
+ COGL_SLIST_INIT (&uniforms_state->override_list);
+ }
}
}
@@ -2628,9 +2639,11 @@ _cogl_pipeline_init_state_hash_functions (void)
_cogl_pipeline_hash_point_size_state;
state_hash_functions[COGL_PIPELINE_STATE_LOGIC_OPS_INDEX] =
_cogl_pipeline_hash_logic_ops_state;
+ state_hash_functions[COGL_PIPELINE_STATE_UNIFORMS_INDEX] =
+ _cogl_pipeline_hash_uniforms_state;
/* So we get a big error if we forget to update this code! */
- g_assert (COGL_PIPELINE_STATE_SPARSE_COUNT == 13);
+ g_assert (COGL_PIPELINE_STATE_SPARSE_COUNT == 14);
}
unsigned int
@@ -2845,19 +2858,9 @@ cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
be. */
/* Look for an existing uniform with this name */
- if (ctx->uniform_names)
- {
- name_node = g_hash_table_lookup (ctx->uniform_names, uniform_name);
- if (name_node)
- return name_node->index;
- }
- else
- /* We don't need a destructor for the uniform name string because
- it is contained within the allocation of the struct */
- ctx->uniform_names = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- g_free);
+ name_node = g_hash_table_lookup (ctx->uniform_names, uniform_name);
+ if (name_node)
+ return name_node->index;
name_len = strlen (uniform_name);
name_node = g_malloc (sizeof (CoglPipelineUniformName) + name_len);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]