[cogl/wip/neil/snippets: 13/21] snippet: Move the hook to be a property of the snippet
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/neil/snippets: 13/21] snippet: Move the hook to be a property of the snippet
- Date: Tue, 29 Nov 2011 22:14:29 +0000 (UTC)
commit cd19e9f6c467ba67bf3a735608b6c2dadd2c17ef
Author: Neil Roberts <neil linux intel com>
Date: Fri Nov 25 20:54:14 2011 +0000
snippet: Move the hook to be a property of the snippet
Instead of specifying the hook point when adding to the pipeline using
a separate function for each hook, the hook is now a property of the
snippet. The hook is set on construction and is then read-only.
cogl/cogl-pipeline-fragend-glsl.c | 4 +-
cogl/cogl-pipeline-layer-state.c | 27 ++++---
cogl/cogl-pipeline-layer-state.h | 44 +++-------
cogl/cogl-pipeline-snippet-private.h | 15 +---
cogl/cogl-pipeline-snippet.c | 9 +--
cogl/cogl-pipeline-state.c | 34 ++------
cogl/cogl-pipeline-state.h | 67 ++-------------
cogl/cogl-pipeline-vertend-glsl.c | 2 +-
cogl/cogl-snippet-private.h | 16 ++++
cogl/cogl-snippet.c | 13 +++-
cogl/cogl-snippet.h | 151 +++++++++++++++++++++++++++++++++-
tests/conform/test-snippets.c | 62 +++++++++-----
12 files changed, 270 insertions(+), 174 deletions(-)
---
diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c
index 1a34135..d23541b 100644
--- a/cogl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/cogl-pipeline-fragend-glsl.c
@@ -481,7 +481,7 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
/* Wrap the texture lookup in any snippets that have been hooked */
memset (&snippet_data, 0, sizeof (snippet_data));
snippet_data.snippets = get_layer_fragment_snippets (layer);
- snippet_data.hook = COGL_PIPELINE_SNIPPET_HOOK_TEXTURE_LOOKUP;
+ snippet_data.hook = COGL_SNIPPET_HOOK_TEXTURE_LOOKUP;
snippet_data.chain_function = g_strdup_printf ("cogl_real_texture_lookup%i",
unit_index);
snippet_data.final_name = g_strdup_printf ("cogl_texture_lookup%i",
@@ -977,7 +977,7 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
/* Add all of the hooks for fragment processing */
memset (&snippet_data, 0, sizeof (snippet_data));
snippet_data.snippets = get_fragment_snippets (pipeline);
- snippet_data.hook = COGL_PIPELINE_SNIPPET_HOOK_FRAGMENT;
+ snippet_data.hook = COGL_SNIPPET_HOOK_FRAGMENT;
snippet_data.chain_function = "cogl_generated_source";
snippet_data.final_name = "main";
snippet_data.function_prefix = "cogl_fragment_hook";
diff --git a/cogl/cogl-pipeline-layer-state.c b/cogl/cogl-pipeline-layer-state.c
index 8df86fc..1523d36 100644
--- a/cogl/cogl-pipeline-layer-state.c
+++ b/cogl/cogl-pipeline-layer-state.c
@@ -34,6 +34,7 @@
#include "cogl-blend-string.h"
#include "cogl-util.h"
#include "cogl-matrix.h"
+#include "cogl-snippet-private.h"
#include "string.h"
#if 0
@@ -777,14 +778,11 @@ cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline,
static void
_cogl_pipeline_layer_add_fragment_snippet (CoglPipeline *pipeline,
int layer_index,
- CoglPipelineSnippetHook hook,
CoglSnippet *snippet)
{
CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS;
CoglPipelineLayer *layer, *authority;
- _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
-
/* Note: this will ensure that the layer exists, creating one if it
* doesn't already.
*
@@ -800,7 +798,6 @@ _cogl_pipeline_layer_add_fragment_snippet (CoglPipeline *pipeline,
layer = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change);
_cogl_pipeline_snippet_list_add (&layer->big_state->fragment_snippets,
- hook,
snippet);
/* If we weren't previously the authority on this state then we need
@@ -815,15 +812,21 @@ _cogl_pipeline_layer_add_fragment_snippet (CoglPipeline *pipeline,
}
void
-cogl_pipeline_add_texture_lookup_hook (CoglPipeline *pipeline,
- int layer_index,
- CoglSnippet *snippet)
+cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline,
+ int layer_index,
+ CoglSnippet *snippet)
{
- CoglPipelineSnippetHook hook = COGL_PIPELINE_SNIPPET_HOOK_TEXTURE_LOOKUP;
- _cogl_pipeline_layer_add_fragment_snippet (pipeline,
- layer_index,
- hook,
- snippet);
+ _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
+ _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet));
+ _COGL_RETURN_IF_FAIL (snippet->hook >= COGL_SNIPPET_FIRST_LAYER_HOOK);
+
+ if (snippet->hook < COGL_SNIPPET_FIRST_LAYER_FRAGMENT_HOOK)
+ /* TODO */
+ g_assert_not_reached ();
+ else
+ _cogl_pipeline_layer_add_fragment_snippet (pipeline,
+ layer_index,
+ snippet);
}
gboolean
diff --git a/cogl/cogl-pipeline-layer-state.h b/cogl/cogl-pipeline-layer-state.h
index c44f1d9..a4ad16b 100644
--- a/cogl/cogl-pipeline-layer-state.h
+++ b/cogl/cogl-pipeline-layer-state.h
@@ -497,46 +497,26 @@ cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline,
int layer_index,
CoglPipelineWrapMode mode);
+#define cogl_pipeline_add_layer_snippet cogl_pipeline_add_layer_snippet_EXP
/**
- * cogl_pipeline_add_texture_lookup_hook:
+ * cogl_pipeline_add_layer_snippet:
* @pipeline: A #CoglPipeline
- * @layer: The layer whose texutre lookup should be hooked
- * @snippet: The #CoglSnippet to add to the texture lookup for @layer
+ * @layer: The layer to hook the snippet to
+ * @snippet: A #CoglSnippet
*
- * Adds a shader snippet that will hook on to the texture lookup part
- * of a given layer. This gives a chance for the application to modify
- * the coordinates that will be used for the texture lookup or to
- * alter the returned texel.
- *
- * Within the snippet code for this hook there are two extra variables
- * available. âcogl_tex_coordâ is a vec4 which contains the texture
- * coordinates that will be used for the texture lookup this can be
- * modified. âcogl_texelâ will contain the result of the texture
- * lookup. This can be modified.
- *
- * The âdeclarationsâ string in @snippet will be inserted in the main
- * scope of the shader. Use this to declare any uniforms, attributes
- * or functions that the snippet requires.
- *
- * The âpreâ string in @snippet will be inserted at the top of the
- * main() function before any fragment processing is done. This is a
- * good place to modify the cogl_tex_coord variable.
- *
- * If a âreplaceâ string is given then this will be used instead of a
- * the default texture lookup. The snippet would typically use its own
- * sampler in this case.
- *
- * The âpostâ string in @snippet will be inserted after texture lookup
- * has been preformed. Here the snippet can modify the cogl_texel
- * variable to alter the returned texel.
+ * Adds a shader snippet that will hook on to the given layer of the
+ * pipeline. The exact part of the pipeline that the snippet wraps
+ * around depends on the hook that is given to
+ * cogl_snippet_new(). Note that some hooks can't be used with a layer
+ * and need to be added with cogl_pipeline_add_snippet() instead.
*
* Since: 1.10
* Stability: Unstable
*/
void
-cogl_pipeline_add_texture_lookup_hook (CoglPipeline *pipeline,
- int layer_index,
- CoglSnippet *snippet);
+cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline,
+ int layer,
+ CoglSnippet *snippet);
#endif /* COGL_ENABLE_EXPERIMENTAL_API */
diff --git a/cogl/cogl-pipeline-snippet-private.h b/cogl/cogl-pipeline-snippet-private.h
index 0df4972..24ff610 100644
--- a/cogl/cogl-pipeline-snippet-private.h
+++ b/cogl/cogl-pipeline-snippet-private.h
@@ -31,15 +31,6 @@
#include "cogl-snippet.h"
#include "cogl-queue.h"
-/* Enumeration of all the hook points that a snippet can be attached
- to within a pipeline. */
-typedef enum
-{
- COGL_PIPELINE_SNIPPET_HOOK_VERTEX,
- COGL_PIPELINE_SNIPPET_HOOK_FRAGMENT,
- COGL_PIPELINE_SNIPPET_HOOK_TEXTURE_LOOKUP
-} CoglPipelineSnippetHook;
-
typedef struct _CoglPipelineSnippet CoglPipelineSnippet;
COGL_LIST_HEAD (CoglPipelineSnippetList, CoglPipelineSnippet);
@@ -48,9 +39,6 @@ struct _CoglPipelineSnippet
{
COGL_LIST_ENTRY (CoglPipelineSnippet) list_node;
- /* Hook where this snippet is attached */
- CoglPipelineSnippetHook hook;
-
CoglSnippet *snippet;
};
@@ -60,7 +48,7 @@ typedef struct
CoglPipelineSnippetList *snippets;
/* Only snippets at this hook point will be used */
- CoglPipelineSnippetHook hook;
+ CoglSnippetHook hook;
/* The final function to chain on to after all of the snippets code
has been run */
@@ -98,7 +86,6 @@ _cogl_pipeline_snippet_list_free (CoglPipelineSnippetList *list);
void
_cogl_pipeline_snippet_list_add (CoglPipelineSnippetList *list,
- CoglPipelineSnippetHook hook,
CoglSnippet *snippet);
void
diff --git a/cogl/cogl-pipeline-snippet.c b/cogl/cogl-pipeline-snippet.c
index bb57abd..794e163 100644
--- a/cogl/cogl-pipeline-snippet.c
+++ b/cogl/cogl-pipeline-snippet.c
@@ -44,7 +44,7 @@ _cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data)
int snippet_num = 0;
COGL_LIST_FOREACH (snippet, data->snippets, list_node)
- if (snippet->hook == data->hook)
+ if (snippet->snippet->hook == data->hook)
{
const char *source;
@@ -179,12 +179,10 @@ _cogl_pipeline_snippet_list_free (CoglPipelineSnippetList *list)
void
_cogl_pipeline_snippet_list_add (CoglPipelineSnippetList *list,
- CoglPipelineSnippetHook hook,
CoglSnippet *snippet)
{
CoglPipelineSnippet *pipeline_snippet = g_slice_new (CoglPipelineSnippet);
- pipeline_snippet->hook = hook;
pipeline_snippet->snippet = cogl_object_ref (snippet);
_cogl_snippet_make_immutable (pipeline_snippet->snippet);
@@ -236,9 +234,6 @@ _cogl_pipeline_snippet_list_hash (CoglPipelineSnippetList *list,
COGL_LIST_FOREACH (l, list, list_node)
{
*hash = _cogl_util_one_at_a_time_hash (*hash,
- &l->hook,
- sizeof (CoglPipelineSnippetHook));
- *hash = _cogl_util_one_at_a_time_hash (*hash,
&l->snippet,
sizeof (CoglSnippet *));
}
@@ -253,7 +248,7 @@ _cogl_pipeline_snippet_list_equal (CoglPipelineSnippetList *list0,
for (l0 = COGL_LIST_FIRST (list0), l1 = COGL_LIST_FIRST (list1);
l0 && l1;
l0 = COGL_LIST_NEXT (l0, list_node), l1 = COGL_LIST_NEXT (l1, list_node))
- if (l0->hook != l1->hook || l0->snippet != l1->snippet)
+ if (l0->snippet != l1->snippet)
return FALSE;
return l0 == NULL && l1 == NULL;
diff --git a/cogl/cogl-pipeline-state.c b/cogl/cogl-pipeline-state.c
index 3477820..44384ed 100644
--- a/cogl/cogl-pipeline-state.c
+++ b/cogl/cogl-pipeline-state.c
@@ -1571,14 +1571,10 @@ cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline,
static void
_cogl_pipeline_add_vertex_snippet (CoglPipeline *pipeline,
- CoglPipelineSnippetHook hook,
CoglSnippet *snippet)
{
CoglPipelineState state = COGL_PIPELINE_STATE_VERTEX_SNIPPETS;
- g_return_if_fail (cogl_is_pipeline (pipeline));
- g_return_if_fail (cogl_is_snippet (snippet));
-
/* - 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
@@ -1587,29 +1583,15 @@ _cogl_pipeline_add_vertex_snippet (CoglPipeline *pipeline,
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
_cogl_pipeline_snippet_list_add (&pipeline->big_state->vertex_snippets,
- hook,
snippet);
}
-void
-cogl_pipeline_add_vertex_hook (CoglPipeline *pipeline,
- CoglSnippet *snippet)
-{
- _cogl_pipeline_add_vertex_snippet (pipeline,
- COGL_PIPELINE_SNIPPET_HOOK_VERTEX,
- snippet);
-}
-
static void
_cogl_pipeline_add_fragment_snippet (CoglPipeline *pipeline,
- CoglPipelineSnippetHook hook,
CoglSnippet *snippet)
{
CoglPipelineState state = COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS;
- g_return_if_fail (cogl_is_pipeline (pipeline));
- g_return_if_fail (cogl_is_snippet (snippet));
-
/* - 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
@@ -1618,17 +1600,21 @@ _cogl_pipeline_add_fragment_snippet (CoglPipeline *pipeline,
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
_cogl_pipeline_snippet_list_add (&pipeline->big_state->fragment_snippets,
- hook,
snippet);
}
void
-cogl_pipeline_add_fragment_hook (CoglPipeline *pipeline,
- CoglSnippet *snippet)
+cogl_pipeline_add_snippet (CoglPipeline *pipeline,
+ CoglSnippet *snippet)
{
- _cogl_pipeline_add_fragment_snippet (pipeline,
- COGL_PIPELINE_SNIPPET_HOOK_FRAGMENT,
- snippet);
+ g_return_if_fail (cogl_is_pipeline (pipeline));
+ g_return_if_fail (cogl_is_snippet (snippet));
+ g_return_if_fail (snippet->hook < COGL_SNIPPET_FIRST_LAYER_HOOK);
+
+ if (snippet->hook < COGL_SNIPPET_FIRST_PIPELINE_FRAGMENT_HOOK)
+ _cogl_pipeline_add_vertex_snippet (pipeline, snippet);
+ else
+ _cogl_pipeline_add_fragment_snippet (pipeline, snippet);
}
gboolean
diff --git a/cogl/cogl-pipeline-state.h b/cogl/cogl-pipeline-state.h
index 4781a9e..b3500bf 100644
--- a/cogl/cogl-pipeline-state.h
+++ b/cogl/cogl-pipeline-state.h
@@ -937,73 +937,24 @@ cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline,
gboolean transpose,
const float *value);
+#define cogl_pipeline_add_snippet cogl_pipeline_add_snippet_EXP
/**
- * cogl_pipeline_add_vertex_hook:
+ * cogl_pipeline_add_snippet:
* @pipeline: A #CoglPipeline
* @snippet: The #CoglSnippet to add to the vertex processing hook
*
- * Adds a shader snippet that will hook on to the vertex processing
- * stage of @pipeline. This gives a chance for the application to
- * modify the vertex attributes generated by the shader. Typically the
- * snippet will modify cogl_color_out or cogl_position_out builtins.
- *
- * The âdeclarationsâ string in @snippet will be inserted in the main
- * scope of the shader. Use this to declare any uniforms, attributes
- * or functions that the snippet requires.
- *
- * The âpreâ string in @snippet will be inserted at the top of the
- * main() function before any vertex processing is done.
- *
- * The âreplaceâ string in @snippet will be used instead of the
- * generated vertex processing if it is present. This can be used if
- * the application wants to provide a complete vertex shader and
- * doesn't need the generated output from Cogl.
- *
- * The âpostâ string in @snippet will be inserted after all of the
- * standard vertex processing is done. This can be used to modify the
- * outputs.
- *
- * Since: 1.10
- * Stability: Unstable
- */
-void
-cogl_pipeline_add_vertex_hook (CoglPipeline *pipeline,
- CoglSnippet *snippet);
-
-/**
- * cogl_pipeline_add_fragment_hook:
- * @pipeline: A #CoglPipeline
- * @snippet: The #CoglSnippet to add to the fragment processing hook
- *
- * Adds a shader snippet that will hook on to the fragment processing
- * stage of @pipeline. This gives a chance for the application to
- * modify the fragment color generated by the shader. Typically the
- * snippet will modify cogl_color_out.
- *
- * The âdeclarationsâ string in @snippet will be inserted in the main
- * scope of the shader. Use this to declare any uniforms, attributes
- * or functions that the snippet requires.
- *
- * The âpreâ string in @snippet will be inserted at the top of the
- * main() function before any fragment processing is done.
- *
- * The âreplaceâ string in @snippet will be used instead of the
- * generated fragment processing if it is present. This can be used if
- * the application wants to provide a complete fragment shader and
- * doesn't need the generated output from Cogl.
- *
- * The âpostâ string in @snippet will be inserted after all of the
- * standard fragment processing is done. At this point the generated
- * value for the rest of the pipeline state will already be in
- * cogl_color_out so the application can modify the result by altering
- * this variable.
+ * Adds a shader snippet that to @pipeline. The snippet will wrap
+ * around or replace some part of the pipeline as defined by the hook
+ * point in @snippet. Note that some hook points are specific to a
+ * layer and must be added with cogl_pipeline_add_layer_snippet()
+ * instead.
*
* Since: 1.10
* Stability: Unstable
*/
void
-cogl_pipeline_add_fragment_hook (CoglPipeline *pipeline,
- CoglSnippet *snippet);
+cogl_pipeline_add_snippet (CoglPipeline *pipeline,
+ CoglSnippet *snippet);
#endif /* COGL_ENABLE_EXPERIMENTAL_API */
diff --git a/cogl/cogl-pipeline-vertend-glsl.c b/cogl/cogl-pipeline-vertend-glsl.c
index 64b4737..a6f04ca 100644
--- a/cogl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/cogl-pipeline-vertend-glsl.c
@@ -381,7 +381,7 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
/* Add all of the hooks for vertex processing */
memset (&snippet_data, 0, sizeof (snippet_data));
snippet_data.snippets = get_vertex_snippets (pipeline);
- snippet_data.hook = COGL_PIPELINE_SNIPPET_HOOK_VERTEX;
+ snippet_data.hook = COGL_SNIPPET_HOOK_VERTEX;
snippet_data.chain_function = "cogl_generated_source";
snippet_data.final_name = "main";
snippet_data.function_prefix = "cogl_vertex_hook";
diff --git a/cogl/cogl-snippet-private.h b/cogl/cogl-snippet-private.h
index bcc6abe..519738b 100644
--- a/cogl/cogl-snippet-private.h
+++ b/cogl/cogl-snippet-private.h
@@ -33,10 +33,26 @@
#include "cogl-snippet.h"
#include "cogl-object-private.h"
+/* These values are also used in the enum for CoglSnippetHook. They
+ are copied here because we don't really want these names to be part
+ of the public API */
+#define COGL_SNIPPET_HOOK_BAND_SIZE 2048
+#define COGL_SNIPPET_FIRST_PIPELINE_HOOK 0
+#define COGL_SNIPPET_FIRST_PIPELINE_VERTEX_HOOK \
+ COGL_SNIPPET_FIRST_PIPELINE_HOOK
+#define COGL_SNIPPET_FIRST_PIPELINE_FRAGMENT_HOOK \
+ (COGL_SNIPPET_FIRST_PIPELINE_VERTEX_HOOK + COGL_SNIPPET_HOOK_BAND_SIZE)
+#define COGL_SNIPPET_FIRST_LAYER_HOOK (COGL_SNIPPET_HOOK_BAND_SIZE * 2)
+#define COGL_SNIPPET_FIRST_LAYER_VERTEX_HOOK COGL_SNIPPET_FIRST_LAYER_HOOK
+#define COGL_SNIPPET_FIRST_LAYER_FRAGMENT_HOOK \
+ (COGL_SNIPPET_FIRST_LAYER_VERTEX_HOOK + COGL_SNIPPET_HOOK_BAND_SIZE)
+
struct _CoglSnippet
{
CoglObject _parent;
+ CoglSnippetHook hook;
+
/* This is set to TRUE the first time the snippet is attached to the
pipeline. After that any attempts to modify the snippet will be
ignored. */
diff --git a/cogl/cogl-snippet.c b/cogl/cogl-snippet.c
index d3a066f..0af6473 100644
--- a/cogl/cogl-snippet.c
+++ b/cogl/cogl-snippet.c
@@ -38,19 +38,30 @@ _cogl_snippet_free (CoglSnippet *snippet);
COGL_OBJECT_DEFINE (Snippet, snippet);
CoglSnippet *
-cogl_snippet_new (const char *declarations,
+cogl_snippet_new (CoglSnippetHook hook,
+ const char *declarations,
const char *post)
{
CoglSnippet *snippet = g_slice_new0 (CoglSnippet);
_cogl_snippet_object_new (snippet);
+ snippet->hook = hook;
+
cogl_snippet_set_declarations (snippet, declarations);
cogl_snippet_set_post (snippet, post);
return snippet;
}
+CoglSnippetHook
+cogl_snippet_get_hook (CoglSnippet *snippet)
+{
+ _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), 0);
+
+ return snippet->hook;
+}
+
static gboolean
_cogl_snippet_modify (CoglSnippet *snippet)
{
diff --git a/cogl/cogl-snippet.h b/cogl/cogl-snippet.h
index 260aed9..d966f17 100644
--- a/cogl/cogl-snippet.h
+++ b/cogl/cogl-snippet.h
@@ -46,9 +46,146 @@ typedef struct _CoglSnippet CoglSnippet;
#define COGL_SNIPPET(OBJECT) ((CoglSnippet *)OBJECT)
+/* Enumeration of all the hook points that a snippet can be attached
+ to within a pipeline. */
+/**
+ * CoglSnippetHook:
+ * @COGL_SNIPPET_HOOK_VERTEX: A hook for the entire vertex processing
+ * stage of the pipeline.
+ * @COGL_SNIPPET_HOOK_FRAGMENT: A hook for the entire fragment
+ * processing stage of the pipeline.
+ * @COGL_SNIPPET_HOOK_TEXTURE_LOOKUP: A hook for the texture lookup
+ * stage of a given layer in a pipeline.
+ *
+ * #CoglSnippetHook is used to specify a location within a
+ * #CoglPipeline where the code of the snippet should be used when it
+ * is attached to a pipeline.
+ *
+ * <glosslist>
+ * <glossentry>
+ * <glossterm>%COGL_SNIPPET_HOOK_VERTEX</glossterm>
+ * <glossdef>
+ * <para>
+ * Adds a shader snippet that will hook on to the vertex processing
+ * stage of the pipeline. This gives a chance for the application to
+ * modify the vertex attributes generated by the shader. Typically the
+ * snippet will modify cogl_color_out or cogl_position_out builtins.
+ * </para>
+ * <para>
+ * The âdeclarationsâ string in @snippet will be inserted in the main
+ * scope of the shader. Use this to declare any uniforms, attributes
+ * or functions that the snippet requires.
+ * </para>
+ * <para>
+ * The âpreâ string in @snippet will be inserted at the top of the
+ * main() function before any vertex processing is done.
+ * </para>
+ * <para>
+ * The âreplaceâ string in @snippet will be used instead of the
+ * generated vertex processing if it is present. This can be used if
+ * the application wants to provide a complete vertex shader and
+ * doesn't need the generated output from Cogl.
+ * </para>
+ * <para>
+ * The âpostâ string in @snippet will be inserted after all of the
+ * standard vertex processing is done. This can be used to modify the
+ * outputs.
+ * </para>
+ * </glossdef>
+ * </glossentry>
+ * <glossentry>
+ * <glossterm>%COGL_SNIPPET_HOOK_FRAGMENT</glossterm>
+ * <glossdef>
+ * <para>
+ * Adds a shader snippet that will hook on to the fragment processing
+ * stage of the pipeline. This gives a chance for the application to
+ * modify the fragment color generated by the shader. Typically the
+ * snippet will modify cogl_color_out.
+ * </para>
+ * <para>
+ * The âdeclarationsâ string in @snippet will be inserted in the main
+ * scope of the shader. Use this to declare any uniforms, attributes
+ * or functions that the snippet requires.
+ * </para>
+ * <para>
+ * The âpreâ string in @snippet will be inserted at the top of the
+ * main() function before any fragment processing is done.
+ * </para>
+ * <para>
+ * The âreplaceâ string in @snippet will be used instead of the
+ * generated fragment processing if it is present. This can be used if
+ * the application wants to provide a complete fragment shader and
+ * doesn't need the generated output from Cogl.
+ * </para>
+ * <para>
+ * The âpostâ string in @snippet will be inserted after all of the
+ * standard fragment processing is done. At this point the generated
+ * value for the rest of the pipeline state will already be in
+ * cogl_color_out so the application can modify the result by altering
+ * this variable.
+ * </para>
+ * </glossdef>
+ * </glossentry>
+ * <glossentry>
+ * <glossterm>%COGL_SNIPPET_HOOK_TEXTURE_LOOKUP</glossterm>
+ * Adds a shader snippet that will hook on to the texture lookup part
+ * of a given layer. This gives a chance for the application to modify
+ * the coordinates that will be used for the texture lookup or to
+ * alter the returned texel.
+ * </para>
+ * <para>
+ * Within the snippet code for this hook there are two extra variables
+ * available. âcogl_tex_coordâ is a vec4 which contains the texture
+ * coordinates that will be used for the texture lookup this can be
+ * modified. âcogl_texelâ will contain the result of the texture
+ * lookup. This can be modified.
+ * </para>
+ * <para>
+ * The âdeclarationsâ string in @snippet will be inserted in the main
+ * scope of the shader. Use this to declare any uniforms, attributes
+ * or functions that the snippet requires.
+ * </para>
+ * <para>
+ * The âpreâ string in @snippet will be inserted at the top of the
+ * main() function before any fragment processing is done. This is a
+ * good place to modify the cogl_tex_coord variable.
+ * </para>
+ * <para>
+ * If a âreplaceâ string is given then this will be used instead of a
+ * the default texture lookup. The snippet would typically use its own
+ * sampler in this case.
+ * </para>
+ * <para>
+ * The âpostâ string in @snippet will be inserted after texture lookup
+ * has been preformed. Here the snippet can modify the cogl_texel
+ * variable to alter the returned texel.
+ * </para>
+ * </glossentry>
+ * </glosslist>
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+typedef enum {
+ /* Per pipeline vertex hooks */
+ COGL_SNIPPET_HOOK_VERTEX = 0,
+
+ /* Per pipeline fragment hooks */
+ COGL_SNIPPET_HOOK_FRAGMENT = 2048,
+
+ /* Per layer vertex hooks */
+ /* TODO */
+ /* ... = 4096 */
+
+ /* Per layer fragment hooks */
+ COGL_SNIPPET_HOOK_TEXTURE_LOOKUP = 6144
+} CoglSnippetHook;
+
#define cogl_snippet_new cogl_snippet_new_EXP
/**
* cogl_snippet_new:
+ * @hook: The point in the pipeline that this snippet will wrap around
+ * or replace.
* @declarations: The source code for the declarations for this
* snippet or %NULL. See cogl_snippet_set_declarations().
* @post: The source code to run after the hook point where this
@@ -62,9 +199,21 @@ typedef struct _CoglSnippet CoglSnippet;
* Stability: Unstable
*/
CoglSnippet *
-cogl_snippet_new (const char *declarations,
+cogl_snippet_new (CoglSnippetHook hook,
+ const char *declarations,
const char *post);
+#define cogl_snippet_get_hook cogl_snipet_get_hook_EXP
+/**
+ * cogl_snippet_get_hook:
+ * @snippet: A #CoglSnippet
+ *
+ * Return value: the hook that was set when cogl_snippet_new() was
+ * called.
+ */
+CoglSnippetHook
+cogl_snippet_get_hook (CoglSnippet *snippet);
+
#define cogl_is_snippet cogl_is_snippet_EXP
/**
* cogl_is_snippet:
diff --git a/tests/conform/test-snippets.c b/tests/conform/test-snippets.c
index 2d96a99..b53aeca 100644
--- a/tests/conform/test-snippets.c
+++ b/tests/conform/test-snippets.c
@@ -57,8 +57,10 @@ paint (TestState *state)
cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
- snippet = cogl_snippet_new (NULL, "cogl_color_out.g += 1.0;");
- cogl_pipeline_add_fragment_hook (pipeline, snippet);
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
+ NULL, /* declarations */
+ "cogl_color_out.g += 1.0;");
+ cogl_pipeline_add_snippet (pipeline, snippet);
cogl_object_unref (snippet);
cogl_push_source (pipeline);
@@ -72,8 +74,10 @@ paint (TestState *state)
cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
- snippet = cogl_snippet_new (NULL, "cogl_color_out.b += 1.0;");
- cogl_pipeline_add_vertex_hook (pipeline, snippet);
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
+ NULL,
+ "cogl_color_out.b += 1.0;");
+ cogl_pipeline_add_snippet (pipeline, snippet);
cogl_object_unref (snippet);
cogl_push_source (pipeline);
@@ -82,8 +86,8 @@ paint (TestState *state)
cogl_object_unref (pipeline);
- /* Single snippet used with in both the vertex and fragment hooks
- with a uniform */
+ /* Snippets sharing a uniform across the vertex and fragment
+ hooks */
pipeline = cogl_pipeline_new ();
location = cogl_pipeline_get_uniform_location (pipeline, "a_value");
@@ -91,10 +95,15 @@ paint (TestState *state)
cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
- snippet = cogl_snippet_new ("uniform float a_value;",
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
+ "uniform float a_value;",
"cogl_color_out.b += a_value;");
- cogl_pipeline_add_fragment_hook (pipeline, snippet);
- cogl_pipeline_add_vertex_hook (pipeline, snippet);
+ cogl_pipeline_add_snippet (pipeline, snippet);
+ cogl_object_unref (snippet);
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
+ "uniform float a_value;",
+ "cogl_color_out.b += a_value;");
+ cogl_pipeline_add_snippet (pipeline, snippet);
cogl_object_unref (snippet);
cogl_push_source (pipeline);
@@ -121,8 +130,10 @@ paint (TestState *state)
location = cogl_pipeline_get_uniform_location (pipeline, uniform_name);
cogl_pipeline_set_uniform_1f (pipeline, location, (i + 1) * 0.1f);
- snippet = cogl_snippet_new (declarations, code);
- cogl_pipeline_add_fragment_hook (pipeline, snippet);
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
+ declarations,
+ code);
+ cogl_pipeline_add_snippet (pipeline, snippet);
cogl_object_unref (snippet);
g_free (code);
@@ -142,10 +153,11 @@ paint (TestState *state)
cogl_pipeline_set_color4ub (pipeline, 255, 255, 255, 255);
- snippet = cogl_snippet_new (NULL, "cogl_color_out = redvec;");
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
+ NULL, /* declarations */
+ "cogl_color_out = redvec;");
cogl_snippet_set_pre (snippet, "vec4 redvec = vec4 (1.0, 0.0, 0.0, 1.0);");
- cogl_pipeline_add_vertex_hook (pipeline, snippet);
- cogl_pipeline_add_fragment_hook (pipeline, snippet);
+ cogl_pipeline_add_snippet (pipeline, snippet);
cogl_object_unref (snippet);
cogl_push_source (pipeline);
@@ -159,21 +171,22 @@ paint (TestState *state)
the conformance test but at least it should be possible to see by
setting COGL_DEBUG=show-source to check whether this shader gets
generated twice */
- snippet = cogl_snippet_new ("/* This comment should only be seen ONCE\n"
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
+ "/* This comment should only be seen ONCE\n"
" when COGL_DEBUG=show-source is TRUE\n"
" even though it is used in two different\n"
" unrelated pipelines */",
"cogl_color_out = vec4 (0.0, 1.0, 0.0, 1.0);\n");
pipeline = cogl_pipeline_new ();
- cogl_pipeline_add_fragment_hook (pipeline, snippet);
+ cogl_pipeline_add_snippet (pipeline, snippet);
cogl_push_source (pipeline);
cogl_rectangle (50, 0, 60, 10);
cogl_pop_source ();
cogl_object_unref (pipeline);
pipeline = cogl_pipeline_new ();
- cogl_pipeline_add_fragment_hook (pipeline, snippet);
+ cogl_pipeline_add_snippet (pipeline, snippet);
cogl_push_source (pipeline);
cogl_rectangle (60, 0, 70, 10);
cogl_pop_source ();
@@ -182,7 +195,7 @@ paint (TestState *state)
cogl_object_unref (snippet);
/* Check the replace string */
- snippet = cogl_snippet_new (NULL, NULL);
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, NULL, NULL);
cogl_snippet_set_pre (snippet,
"cogl_color_out = vec4 (0.0, 0.5, 0.0, 1.0);");
/* Remove the generated output. If the replace string isn't working
@@ -193,7 +206,7 @@ paint (TestState *state)
"cogl_color_out += vec4 (0.5, 0.0, 0.0, 1.0);");
pipeline = cogl_pipeline_new ();
- cogl_pipeline_add_fragment_hook (pipeline, snippet);
+ cogl_pipeline_add_snippet (pipeline, snippet);
cogl_push_source (pipeline);
cogl_rectangle (70, 0, 80, 10);
cogl_pop_source ();
@@ -202,14 +215,15 @@ paint (TestState *state)
cogl_object_unref (snippet);
/* Check the texture lookup hook */
- snippet = cogl_snippet_new (NULL,
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
+ NULL,
"cogl_texel.b += 1.0;");
/* Flip the texture coordinates around the y axis so that it will
get the green texel */
cogl_snippet_set_pre (snippet, "cogl_tex_coord.x = 1.0 - cogl_tex_coord.x;");
pipeline = create_texture_pipeline ();
- cogl_pipeline_add_texture_lookup_hook (pipeline, 0, snippet);
+ cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
cogl_push_source (pipeline);
cogl_rectangle_with_texture_coords (80, 0, 90, 10,
0, 0, 0, 0);
@@ -219,7 +233,7 @@ paint (TestState *state)
cogl_object_unref (snippet);
/* Sanity check modifying the snippet */
- snippet = cogl_snippet_new ("foo", "bar");
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, "foo", "bar");
g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "foo");
g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "bar");
g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
@@ -248,6 +262,10 @@ paint (TestState *state)
g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, "baba");
g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, "fuba");
+
+ g_assert_cmpint (cogl_snippet_get_hook (snippet),
+ ==,
+ COGL_SNIPPET_HOOK_FRAGMENT);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]