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 <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2011-11-25 20:54:14 +00:00 committed by Robert Bragg
parent 5be5a03343
commit 09c2e4abe7
12 changed files with 270 additions and 174 deletions

View File

@ -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";

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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.
* 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_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.
*
* 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 */

View File

@ -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";

View File

@ -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. */

View File

@ -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)
{

View File

@ -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
* global 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
* global 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
* global 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:

View File

@ -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