From 09c2e4abe796e5f4cc5b164a3770be754099d9ff Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Fri, 25 Nov 2011 20:54:14 +0000 Subject: 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. Reviewed-by: Robert Bragg --- 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 ++++++++++++++++++++++++++++++++++- 11 files changed, 230 insertions(+), 152 deletions(-) (limited to 'cogl') diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c index 1a341359..d23541b9 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 8df86fca..1523d364 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 7d6965b2..a4ad16b2 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 - * global 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 0df49726..24ff610b 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 bb57abd6..794e163c 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); @@ -235,9 +233,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 3477820c..44384ed5 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 02728762..b3500bf3 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 - * global 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 - * global 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 64b4737b..a6f04ca6 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 bcc6abe0..519738b0 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 d3a066f1..0af6473e 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 260aed91..81817d76 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. + * + * + * + * %COGL_SNIPPET_HOOK_VERTEX + * + * + * 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. + * + * + * The ‘declarations’ string in @snippet will be inserted in the + * global 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. + * + * + * + * + * %COGL_SNIPPET_HOOK_FRAGMENT + * + * + * 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. + * + * + * The ‘declarations’ string in @snippet will be inserted in the + * global 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. + * + * + * + * + * %COGL_SNIPPET_HOOK_TEXTURE_LOOKUP + * 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 + * global 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. + * + * + * + * + * 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: -- cgit v1.2.1