[cogl/wip/neil/pipeline-uniforms: 8/9] Stash
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/neil/pipeline-uniforms: 8/9] Stash
- Date: Fri, 28 Oct 2011 19:14:03 +0000 (UTC)
commit f58a2961f5d75cbbdd59789009c29396bc0523d1
Author: Neil Roberts <neil linux intel com>
Date: Thu Oct 27 16:56:11 2011 +0100
Stash
cogl/cogl-pipeline-state-private.h | 4 +
cogl/cogl-pipeline-state.c | 248 +++++++++++++++++++++++++++---------
cogl/cogl-pipeline.c | 5 +-
cogl/cogl-pipeline.h | 27 ++++
4 files changed, 221 insertions(+), 63 deletions(-)
---
diff --git a/cogl/cogl-pipeline-state-private.h b/cogl/cogl-pipeline-state-private.h
index dd00f00..8b8fe3f 100644
--- a/cogl/cogl-pipeline-state-private.h
+++ b/cogl/cogl-pipeline-state-private.h
@@ -87,6 +87,10 @@ gboolean
_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0,
CoglPipeline *authority1);
+gboolean
+_cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0,
+ CoglPipeline *authority1);
+
void
_cogl_pipeline_hash_color_state (CoglPipeline *authority,
CoglPipelineHashState *state);
diff --git a/cogl/cogl-pipeline-state.c b/cogl/cogl-pipeline-state.c
index 5270756..7709335 100644
--- a/cogl/cogl-pipeline-state.c
+++ b/cogl/cogl-pipeline-state.c
@@ -238,6 +238,94 @@ _cogl_pipeline_user_shader_equal (CoglPipeline *authority0,
authority1->big_state->user_program);
}
+typedef struct
+{
+ const CoglBoxedValue **values;
+ const CoglPipelineUniformOverride *override_values;
+} GetUniformsClosure;
+
+static gboolean
+get_uniforms_cb (int uniform_num, void *user_data)
+{
+ GetUniformsClosure *data = user_data;
+
+ if (data->values[uniform_num] == NULL)
+ data->values[uniform_num] = &data->override_values->value;
+
+ data->override_values = COGL_SLIST_NEXT (data->override_values, list_node);
+
+ return TRUE;
+}
+
+static void
+_cogl_pipeline_get_all_uniform_values (CoglPipeline *pipeline,
+ const CoglBoxedValue **values)
+{
+ GetUniformsClosure data;
+
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+ memset (values, 0,
+ sizeof (const CoglBoxedValue *) *
+ g_hash_table_size (ctx->uniform_names));
+
+ data.values = values;
+
+ do
+ {
+ const CoglPipelineUniformsState *uniforms_state =
+ &pipeline->big_state->uniforms_state;
+
+ data.override_values = COGL_SLIST_FIRST (&uniforms_state->override_list);
+
+ if ((pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS))
+ _cogl_bitmask_foreach (&uniforms_state->override_mask,
+ get_uniforms_cb,
+ &data);
+
+ pipeline = _cogl_pipeline_get_parent (pipeline);
+ }
+ while (pipeline);
+}
+
+gboolean
+_cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0,
+ CoglPipeline *authority1)
+{
+ const CoglBoxedValue **values0, **values1;
+ int n_uniform_names;
+ int i;
+
+ _COGL_GET_CONTEXT (ctx, FALSE);
+
+ if (authority0 == authority1)
+ return TRUE;
+
+ n_uniform_names = g_hash_table_size (ctx->uniform_names);
+
+ values0 = g_alloca (sizeof (const CoglBoxedValue *) * n_uniform_names);
+ values1 = g_alloca (sizeof (const CoglBoxedValue *) * n_uniform_names);
+
+ _cogl_pipeline_get_all_uniform_values (authority0, values0);
+ _cogl_pipeline_get_all_uniform_values (authority1, values1);
+
+ for (i = 0; i < n_uniform_names; i++)
+ {
+ const CoglBoxedValue *value0 = values0[i];
+ const CoglBoxedValue *value1 = values1[i];
+
+ if (value0 == NULL || value0->type == COGL_BOXED_NONE)
+ {
+ if (value1 != NULL && value1->type != COGL_BOXED_NONE)
+ return FALSE;
+ }
+ else if (!_cogl_boxed_value_equal (value0, value1))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
void
cogl_pipeline_get_color (CoglPipeline *pipeline,
CoglColor *color)
@@ -1262,6 +1350,106 @@ cogl_pipeline_set_point_size (CoglPipeline *pipeline,
_cogl_pipeline_point_size_equal);
}
+typedef struct
+{
+ int location;
+ CoglPipelineUniformOverride *previous_override;
+ CoglPipelineUniformOverride *found_override;
+ CoglPipelineUniformOverride *it;
+} FindUniformOverrideClosure;
+
+static gboolean
+find_uniform_override_cb (int it_location,
+ void *user_data)
+{
+ FindUniformOverrideClosure *data = user_data;
+
+ if (it_location < data->location)
+ {
+ data->previous_override = data->it;
+ data->it = COGL_SLIST_NEXT (data->it, list_node);
+
+ return TRUE;
+ }
+ else
+ {
+ if (it_location == data->location)
+ data->found_override = data->it;
+
+ return FALSE;
+ }
+}
+
+static CoglBoxedValue *
+_cogl_pipeline_override_uniform (CoglPipeline *pipeline,
+ int location)
+{
+ CoglPipelineState state = COGL_PIPELINE_STATE_POINT_SIZE;
+ CoglPipelineUniformsState *uniforms_state;
+ CoglPipeline *authority;
+ FindUniformOverrideClosure find_data;
+ CoglPipelineUniformOverride *override;
+
+ _COGL_GET_CONTEXT (ctx, NULL);
+
+ g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL);
+ g_return_val_if_fail (location >= 0, NULL);
+ 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
+ * changed, then initialize that state from the current authority.
+ */
+ _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
+
+ uniforms_state = &authority->big_state->uniforms_state;
+
+ find_data.previous_override = NULL;
+ find_data.found_override = NULL;
+ find_data.it = COGL_SLIST_FIRST (&uniforms_state->override_list);
+ find_data.location = location;
+
+ _cogl_bitmask_foreach (&uniforms_state->override_mask,
+ find_uniform_override_cb,
+ &find_data);
+
+ /* If this pipeline already has an override for this value then we
+ can just use it directly */
+ if (find_data.found_override)
+ return &find_data.found_override->value;
+
+ /* We need to add a new override */
+ override = g_slice_new (CoglPipelineUniformOverride);
+ _cogl_boxed_value_init (&override->value);
+
+ if (find_data.previous_override)
+ COGL_SLIST_INSERT_AFTER (find_data.previous_override, override, list_node);
+ else
+ COGL_SLIST_INSERT_HEAD (&uniforms_state->override_list,
+ override,
+ list_node);
+
+ _cogl_bitmask_set (&uniforms_state->override_mask, location, TRUE);
+
+ return &override->value;
+}
+
+void
+cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline,
+ int uniform_location,
+ float value)
+{
+ CoglBoxedValue *boxed_value;
+
+ boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location);
+
+ _cogl_boxed_value_set_1f (boxed_value, value);
+}
+
void
_cogl_pipeline_hash_color_state (CoglPipeline *authority,
CoglPipelineHashState *state)
@@ -1455,63 +1643,3 @@ _cogl_pipeline_hash_cull_face_state (CoglPipeline *authority,
cull_face_state,
sizeof (CoglPipelineCullFaceState));
}
-
-static void
-cogl_pipeline_set_uniform_x (CoglPipeline *pipeline,
- int location,
- int size,
- int count,
- CoglBoxedType type,
- gsize value_size,
- gconstpointer value,
- gboolean transpose)
-{
- CoglPipelineUniformOverride *previous_override = NULL;
- CoglPipelineUniformOverride *override = NULL;
-
- _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
- g_return_if_fail (cogl_is_pipeline (pipeline));
- g_return_if_fail (location >= 0);
- g_return_if_fail (location < g_hash_table_size (ctx->uniform_names));
- g_return_if_fail (size >= 1 && size <= 4 && count >= 1);
-#if 0
- if (uniform_no >= 0 && uniform_no < program->custom_uniforms->len &&
- size >= 1 && size <= 4 && count >= 1)
- {
- CoglProgramUniform *uniform =
- &g_array_index (program->custom_uniforms,
- CoglProgramUniform, uniform_no);
-
- if (count == 1)
- {
- if (uniform->value.count > 1)
- g_free (uniform->value.v.array);
-
- memcpy (uniform->value.v.float_value, value, value_size);
- }
- else
- {
- if (uniform->value.count > 1)
- {
- if (uniform->value.count != count ||
- uniform->value.size != size ||
- uniform->value.type != type)
- {
- g_free (uniform->value.v.array);
- uniform->value.v.array = g_malloc (count * value_size);
- }
- }
- else
- uniform->value.v.array = g_malloc (count * value_size);
-
- memcpy (uniform->value.v.array, value, count * value_size);
- }
-
- uniform->value.type = type;
- uniform->value.size = size;
- uniform->value.count = count;
- uniform->dirty = TRUE;
- }
-#endif
-}
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index 9f755aa..eeb3858 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -469,9 +469,8 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
list_node,
tmp)
{
- if (override->value.count > 1)
- g_free (override->value.v.array);
- g_free (override);
+ _cogl_boxed_value_destroy (&override->value);
+ g_slice_free (CoglPipelineUniformOverride, override);
}
_cogl_bitmask_destroy (&uniforms_state->override_mask);
diff --git a/cogl/cogl-pipeline.h b/cogl/cogl-pipeline.h
index d93c6f8..11b71a0 100644
--- a/cogl/cogl-pipeline.h
+++ b/cogl/cogl-pipeline.h
@@ -138,6 +138,33 @@ cogl_pipeline_foreach_layer (CoglPipeline *pipeline,
CoglPipelineLayerCallback callback,
void *user_data);
+#define cogl_pipeline_get_uniform_location \
+ cogl_pipeline_get_uniform_location_EXP
+/**
+ * cogl_pipeline_get_uniform_location:
+ * @pipeline: A #CoglPipeline object
+ * @uniform_name: The name of a uniform
+ *
+ * This is used to get an integer representing the uniform with the
+ * name @uniform_name. The integer can be passed to functions such as
+ * cogl_pipeline_set_uniform_1f() to set the value of a uniform.
+ *
+ * This function will always return a valid integer. Ie, unlike
+ * OpenGL, it does not return -1 if the uniform is not available in
+ * this pipeline so it can not be used to test whether uniforms are
+ * present. It is not necessary to set the program on the pipeline
+ * before calling this function.
+ *
+ * Return value: A integer representing the location of the given uniform.
+ *
+ * Since: 2.0
+ * Stability: Unstable
+ */
+int
+cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
+ const char *uniform_name);
+
+
#endif /* COGL_ENABLE_EXPERIMENTAL_API */
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]