[cogl/wip/neil/snippets: 11/27] snippet: Add a 'replace' string



commit 28c0850c57761fa570bf1083ef95dcf54b522607
Author: Neil Roberts <neil linux intel com>
Date:   Fri Nov 25 14:36:31 2011 +0000

    snippet: Add a 'replace' string
    
    If present, the 'replace' string will be used instead of whatever code
    would normally be invoked for that hook point. It will also replace
    any previous snippets.

 cogl/cogl-pipeline-fragend-glsl.c |    7 +++++--
 cogl/cogl-pipeline-state.h        |   10 ++++++++++
 cogl/cogl-pipeline-vertend-glsl.c |    7 +++++--
 cogl/cogl-snippet-private.h       |    1 +
 cogl/cogl-snippet.c               |   22 ++++++++++++++++++++++
 cogl/cogl-snippet.h               |   36 ++++++++++++++++++++++++++++++++++++
 tests/conform/test-snippets.c     |   31 +++++++++++++++++++++++++++++++
 7 files changed, 110 insertions(+), 4 deletions(-)
---
diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c
index aa8a8d9..8bbd9fa 100644
--- a/cogl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/cogl-pipeline-fragend-glsl.c
@@ -957,8 +957,11 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
             if ((source = cogl_snippet_get_pre (snippet->snippet)))
               g_string_append (shader_state->source, source);
 
-            /* Chain on to the next function */
-            if (snippet_num > 0)
+            /* Chain on to the next function, or bypass it if there is
+               a replace string */
+            if ((source = cogl_snippet_get_replace (snippet->snippet)))
+              g_string_append (shader_state->source, source);
+            else if (snippet_num > 0)
               g_string_append_printf (shader_state->source,
                                       "  cogl_snippet%i ();\n",
                                       snippet_num - 1);
diff --git a/cogl/cogl-pipeline-state.h b/cogl/cogl-pipeline-state.h
index d2c0ada..0272876 100644
--- a/cogl/cogl-pipeline-state.h
+++ b/cogl/cogl-pipeline-state.h
@@ -954,6 +954,11 @@ cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline,
  * 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.
@@ -982,6 +987,11 @@ cogl_pipeline_add_vertex_hook (CoglPipeline *pipeline,
  * 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
diff --git a/cogl/cogl-pipeline-vertend-glsl.c b/cogl/cogl-pipeline-vertend-glsl.c
index 6803758..16637ec 100644
--- a/cogl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/cogl-pipeline-vertend-glsl.c
@@ -397,8 +397,11 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
             if ((source = cogl_snippet_get_pre (snippet->snippet)))
               g_string_append (shader_state->source, source);
 
-            /* Chain on to the next function */
-            if (snippet_num > 0)
+            /* Chain on to the next function, or bypass it if there is
+               a replace string */
+            if ((source = cogl_snippet_get_replace (snippet->snippet)))
+              g_string_append (shader_state->source, source);
+            else if (snippet_num > 0)
               g_string_append_printf (shader_state->source,
                                       "  cogl_snippet%i ();\n",
                                       snippet_num - 1);
diff --git a/cogl/cogl-snippet-private.h b/cogl/cogl-snippet-private.h
index b7ee4a8..bcc6abe 100644
--- a/cogl/cogl-snippet-private.h
+++ b/cogl/cogl-snippet-private.h
@@ -44,6 +44,7 @@ struct _CoglSnippet
 
   char *declarations;
   char *pre;
+  char *replace;
   char *post;
 };
 
diff --git a/cogl/cogl-snippet.c b/cogl/cogl-snippet.c
index 08b19a8..d3a066f 100644
--- a/cogl/cogl-snippet.c
+++ b/cogl/cogl-snippet.c
@@ -109,6 +109,27 @@ cogl_snippet_get_pre (CoglSnippet *snippet)
 }
 
 void
+cogl_snippet_set_replace (CoglSnippet *snippet,
+                          const char *replace)
+{
+  _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet));
+
+  if (!_cogl_snippet_modify (snippet))
+    return;
+
+  g_free (snippet->replace);
+  snippet->replace = replace ? g_strdup (replace) : NULL;
+}
+
+const char *
+cogl_snippet_get_replace (CoglSnippet *snippet)
+{
+  _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), NULL);
+
+  return snippet->replace;
+}
+
+void
 cogl_snippet_set_post (CoglSnippet *snippet,
                        const char *post)
 {
@@ -140,6 +161,7 @@ _cogl_snippet_free (CoglSnippet *snippet)
 {
   g_free (snippet->declarations);
   g_free (snippet->pre);
+  g_free (snippet->replace);
   g_free (snippet->post);
   g_slice_free (CoglSnippet, snippet);
 }
diff --git a/cogl/cogl-snippet.h b/cogl/cogl-snippet.h
index 7afa18a..260aed9 100644
--- a/cogl/cogl-snippet.h
+++ b/cogl/cogl-snippet.h
@@ -154,6 +154,42 @@ cogl_snippet_set_pre (CoglSnippet *snippet,
 const char *
 cogl_snippet_get_pre (CoglSnippet *snippet);
 
+#define cogl_snippet_set_replace cogl_snippet_set_replace_EXP
+/**
+ * cogl_snippet_set_replace:
+ * @snippet: A #CoglSnippet
+ * @replace: The new source string for the replace section of this snippet.
+ *
+ * Sets a source string that will be used instead of any generated
+ * source code or any previous snippets for this hook point. Please
+ * see the documentation of each hook point in #CoglPipeline for a
+ * description of how this string should be used.
+ *
+ * This function should only be called before the snippet is attached
+ * to its first pipeline. After that the snippet should be considered
+ * immutable.
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+void
+cogl_snippet_set_replace (CoglSnippet *snippet,
+                          const char *replace);
+
+#define cogl_snippet_get_replace cogl_snippet_get_replace_EXP
+/**
+ * cogl_snippet_get_replace:
+ * @snippet: A #CoglSnippet
+ *
+ * Return value: the source string that was set with
+ *   cogl_snippet_set_replace() or %NULL if none was set.
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+const char *
+cogl_snippet_get_replace (CoglSnippet *snippet);
+
 #define cogl_snippet_set_post cogl_snippet_set_post_EXP
 /**
  * cogl_snippet_set_post:
diff --git a/tests/conform/test-snippets.c b/tests/conform/test-snippets.c
index 6a5bf60..f3e9ae1 100644
--- a/tests/conform/test-snippets.c
+++ b/tests/conform/test-snippets.c
@@ -150,25 +150,55 @@ paint (TestState *state)
 
   cogl_object_unref (snippet);
 
+  /* Check the replace string */
+  snippet = cogl_snippet_new (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
+     then the code from the pre string would get overwritten with
+     white */
+  cogl_snippet_set_replace (snippet, "/* do nothing */");
+  cogl_snippet_set_post (snippet,
+                         "cogl_color_out += vec4 (0.5, 0.0, 0.0, 1.0);");
+
+  pipeline = cogl_pipeline_new ();
+  cogl_pipeline_add_fragment_hook (pipeline, snippet);
+  cogl_push_source (pipeline);
+  cogl_rectangle (70, 0, 80, 10);
+  cogl_pop_source ();
+  cogl_object_unref (pipeline);
+
+  cogl_object_unref (snippet);
+
   /* Sanity check modifying the snippet */
   snippet = cogl_snippet_new ("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);
   g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
 
   cogl_snippet_set_declarations (snippet, "fu");
   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
   g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "bar");
+  g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
   g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
 
   cogl_snippet_set_post (snippet, "ba");
   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
   g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
+  g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
   g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
 
   cogl_snippet_set_pre (snippet, "fuba");
   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
   g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
+  g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
+  g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, "fuba");
+
+  cogl_snippet_set_replace (snippet, "baba");
+  g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
+  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");
 }
 
@@ -182,6 +212,7 @@ validate_result (void)
   test_utils_check_pixel (45, 5, 0xff0000ff);
   test_utils_check_pixel (55, 5, 0x00ff00ff);
   test_utils_check_pixel (65, 5, 0x00ff00ff);
+  test_utils_check_pixel (75, 5, 0x808000ff);
 }
 
 void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]