mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
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:
parent
5be5a03343
commit
09c2e4abe7
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user