[cogl/wip/neil/pipeline-uniforms: 14/17] Stash
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/neil/pipeline-uniforms: 14/17] Stash
- Date: Wed, 2 Nov 2011 14:06:07 +0000 (UTC)
commit c77e69c8652b7e19630d3317892a704855f6f188
Author: Neil Roberts <neil linux intel com>
Date: Mon Oct 31 14:22:18 2011 +0000
Stash
cogl/cogl-bitmask.h | 20 +++++++++
cogl/cogl-pipeline-private.h | 3 +
cogl/cogl-pipeline-progend-glsl.c | 82 ++++++++++++++++++++++++++++++++++--
cogl/cogl-pipeline.c | 3 +
4 files changed, 103 insertions(+), 5 deletions(-)
---
diff --git a/cogl/cogl-bitmask.h b/cogl/cogl-bitmask.h
index e94f367..a1710af 100644
--- a/cogl/cogl-bitmask.h
+++ b/cogl/cogl-bitmask.h
@@ -251,6 +251,26 @@ _cogl_bitmask_is_empty (const CoglBitmask *bitmask)
return *bitmask == _cogl_bitmask_from_bits (0);
}
+/*
+ * _cogl_bitmask_set_flags:
+ * @bitmask: A pointer to a bitmask
+ * @flags: An array of unsigned ints
+ *
+ * This or's the bits from @bitmask into the flags array (see
+ * cogl-flags) pointed to by @flags.
+ */
+#if 0
+static inline void
+_cogl_bitmask_set_flags (const CoglBitmask *bitmask,
+ unsigned int *flags)
+{
+ if (_cogl_bitmask_has_array (bitmask))
+ return _cogl_bitmask_set_flags_array (bitmask, flags);
+ else
+ flags[0] |= _cogl_bitmask
+}
+#endif
+
G_END_DECLS
#endif /* __COGL_BITMASK_H */
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
index eaf807f..c9e91bc 100644
--- a/cogl/cogl-pipeline-private.h
+++ b/cogl/cogl-pipeline-private.h
@@ -375,6 +375,9 @@ struct _CoglPipelineUniformOverride
typedef struct
{
CoglBitmask override_mask;
+ /* Uniforms that have been modified since this pipeline was last
+ flushed */
+ CoglBitmask changed_mask;
CoglPipelineUniformOverrideList override_list;
} CoglPipelineUniformsState;
diff --git a/cogl/cogl-pipeline-progend-glsl.c b/cogl/cogl-pipeline-progend-glsl.c
index 6d94a14..9cda3c7 100644
--- a/cogl/cogl-pipeline-progend-glsl.c
+++ b/cogl/cogl-pipeline-progend-glsl.c
@@ -555,6 +555,27 @@ update_builtin_uniforms (CoglPipeline *pipeline,
#endif /* HAVE_COGL_GLES2 */
+static GSList *
+get_ancestors (CoglPipeline *pipeline)
+{
+ GSList *ancestors = NULL;
+
+ while (pipeline)
+ ancestors = g_slist_prepend (ancestors, pipeline);
+
+ return ancestors;
+}
+
+typedef struct
+{
+ CoglProgramState *program_state;
+ CoglPipeline *flushed_ancestor;
+ unsigned int *force_flush_uniforms;
+ unsigned int *flushed_uniforms;
+ const CoglPipelineUniformsState *uniforms_state;
+ int uniforms_count;
+} FlushUniformsClosure;
+
static void
_cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline,
CoglPipelineProgramState *
@@ -562,7 +583,24 @@ _cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline,
GLuint gl_program,
gboolean program_changed)
{
- CoglPipeline *flushed_ancestor;
+ FlushUniformsClosure data;
+ int uniforms_count;
+
+ _cogl_bitmask_init (&data.force_flush_uniforms);
+
+ if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS)
+ data.uniforms_state = &pipeline->big_state->data.uniforms_state;
+ else
+ data.uniforms_state = NULL;
+
+ data.flushed_ancestor = NULL;
+ data.uniforms_count = g_hash_table_size (ctx->uniform_names);
+ data.force_flush_uniforms = g_newa (unsigned int, data.uniforms_count);
+ memset (data.force_flush_uniforms, 0,
+ sizeof (unsigned int) * data.uniforms_count);
+ data.flushed_uniforms = g_newa (unsigned int, data.uniforms_count);
+ memset (data.data.flushed_uniforms, 0,
+ sizeof (unsigned int) * data.uniforms_count);
/* Try to find a common ancestor for the values that were already
flushed on the pipeline that this program state was last used for
@@ -571,16 +609,50 @@ _cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline,
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 */
+ need to flush everything. 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;
+ GSList *flushed_ancestors =
+ get_ancestors (program_state->last_used_for_pipeline);
+ GSList *new_ancestors =
+ get_ancestors (pipeline);
+ GSList *a, *b;
+
+ for (a = flushed_ancestors, b = new_ancestors;
+ a && b && a->data == b->data;
+ a = a->next, b = b->next)
+ data.flushed_ancestor = a->data;
+
+ g_slist_free (flushed_ancestors);
+ g_slist_free (new_ancestors);
+
+ /* We need to be sure to flush any uniforms that have changed
+ since the last flush */
+ if (data.uniforms_state)
+ _cogl_bitmask_set_bits (&data.force_flush_uniforms,
+ &data.uniforms_state->changed_mask);
+
+ /* We need to flush any uniforms that are children of the common
+ ancestor up to the last used pipeline */
+ while (a)
+ {
+ CoglPipeline *child_pipeline = a->data;
+ const CoglPipelineUniformsState *data.uniforms_state =
+ &child_pipeline->big_state->data.uniforms_state;
+ _cogl_bitmask_set_bits (&data.force_flush_uniforms,
+ &data.uniforms_state->override_mask);
+ a = a->next;
+ }
}
+
+ if (data.uniforms_state)
+ _cogl_bitmask_clear (&data.uniforms_state->changed_mask);
+
+ _cogl_bitmask_destroy (&data.force_flush_uniforms);
}
static void
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index 5575f2b..ba79aad 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -223,6 +223,7 @@ _cogl_pipeline_init_default_pipeline (void)
cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE;
_cogl_bitmask_init (&uniforms_state->override_mask);
+ _cogl_bitmask_init (&uniforms_state->changed_mask);
COGL_SLIST_INIT (&uniforms_state->override_list);
ctx->default_pipeline = _cogl_pipeline_object_new (pipeline);
@@ -478,6 +479,7 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
}
_cogl_bitmask_destroy (&uniforms_state->override_mask);
+ _cogl_bitmask_destroy (&uniforms_state->changed_mask);
}
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
@@ -1038,6 +1040,7 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline,
CoglPipelineUniformsState *uniforms_state =
&pipeline->big_state->uniforms_state;
_cogl_bitmask_init (&uniforms_state->override_mask);
+ _cogl_bitmask_init (&uniforms_state->changed_mask);
COGL_SLIST_INIT (&uniforms_state->override_list);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]