[cogl/wip/neil/snippets: 8/21] pipeline: Wrap each snippet in its own function



commit 0b1d548e2e54c87258825a151909ce96ea38e23e
Author: Neil Roberts <neil linux intel com>
Date:   Fri Nov 25 13:41:13 2011 +0000

    pipeline: Wrap each snippet in its own function
    
    Each snippet is now given its own function which contains the pre and
    post strings. Between these strings the function will chain on to
    another function. The generated cogl source is now stored in a
    function called cogl_generated_source() which the last snippet will
    chain on to. This should make it so that each snippet has its own
    namespace for local variables and it can share variables declared in
    the pre string in the post string. Hopefully the GLSL compiler will
    just inline all of the functions so it shouldn't make much difference
    to the compiled output.

 cogl/cogl-pipeline-fragend-glsl.c |   91 +++++++++++++++++++------------------
 cogl/cogl-pipeline-vertend-glsl.c |   89 +++++++++++++++++++-----------------
 tests/conform/test-snippets.c     |   10 ++--
 3 files changed, 98 insertions(+), 92 deletions(-)
---
diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c
index d445190..aa8a8d9 100644
--- a/cogl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/cogl-pipeline-fragend-glsl.c
@@ -200,7 +200,6 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
   CoglPipelineShaderState *shader_state;
   CoglPipeline *authority;
   CoglPipeline *template_pipeline = NULL;
-  CoglPipelineSnippet *snippet;
   CoglProgram *user_program;
   int i;
 
@@ -327,40 +326,9 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
 
   g_string_append (shader_state->source,
                    "void\n"
-                   "main ()\n"
+                   "cogl_generated_source ()\n"
                    "{\n");
 
-  COGL_LIST_FOREACH (snippet, get_fragment_snippets (pipeline), list_node)
-    {
-      const char *declarations =
-        cogl_snippet_get_declarations (snippet->snippet);
-
-      /* Add all of the declarations for fragment snippets */
-      if (declarations)
-        {
-          g_string_append (shader_state->header, declarations);
-          g_string_append_c (shader_state->header, '\n');
-        }
-
-      /* Add all of the pre-hooks for fragment processing */
-      if (snippet->hook == COGL_PIPELINE_SNIPPET_HOOK_FRAGMENT)
-        {
-          const char *pre =
-            cogl_snippet_get_pre (snippet->snippet);
-
-          if (pre)
-            {
-              g_string_append (shader_state->source, "  {\n");
-              g_string_append (shader_state->source, pre);
-              g_string_append (shader_state->source, "  }\n");
-            }
-        }
-    }
-
-  /* Enclose the generated fragment processing in a block so that any
-     variables declared in it won't be in the scope of the snippets */
-  g_string_append (shader_state->source, "  {\n");
-
   for (i = 0; i < n_layers; i++)
     {
       shader_state->unit_state[i].sampled = FALSE;
@@ -928,6 +896,7 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
       GLint compile_status;
       GLuint shader;
       CoglPipelineSnippet *snippet;
+      int snippet_num;
 
       COGL_STATIC_COUNTER (fragend_glsl_compile_counter,
                            "glsl fragment compile counter",
@@ -965,24 +934,58 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
         add_alpha_test_snippet (pipeline, shader_state);
 #endif
 
-      /* Close the block surrounding the generated fragment processing */
-      g_string_append (shader_state->source, "  }\n");
+      /* Close the function surrounding the generated fragment processing */
+      g_string_append (shader_state->source, "}\n");
 
       /* Add all of the post-hooks for fragment processing */
+      snippet_num = 0;
       COGL_LIST_FOREACH (snippet, get_fragment_snippets (pipeline), list_node)
         if (snippet->hook == COGL_PIPELINE_SNIPPET_HOOK_FRAGMENT)
           {
-            const char *post =
-              cogl_snippet_get_post (snippet->snippet);
-
-            if (post)
-              {
-                g_string_append (shader_state->source, "  {\n");
-                g_string_append (shader_state->source, post);
-                g_string_append (shader_state->source, "  }\n");
-              }
+            const char *source;
+
+            if ((source = cogl_snippet_get_declarations (snippet->snippet)))
+              g_string_append (shader_state->source, source);
+
+            g_string_append_printf (shader_state->source,
+                                    "\n"
+                                    "void\n"
+                                    "cogl_snippet%i ()\n"
+                                    "{\n",
+                                    snippet_num);
+
+            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)
+              g_string_append_printf (shader_state->source,
+                                      "  cogl_snippet%i ();\n",
+                                      snippet_num - 1);
+            else
+              g_string_append (shader_state->source,
+                               "  cogl_generated_source ();\n");
+
+            if ((source = cogl_snippet_get_post (snippet->snippet)))
+              g_string_append (shader_state->source, source);
+
+            g_string_append (shader_state->source, "}\n");
+
+            snippet_num++;
           }
 
+      g_string_append (shader_state->source,
+                       "\n"
+                       "void\n"
+                       "main ()\n"
+                       "{\n");
+      if (snippet_num > 0)
+        g_string_append_printf (shader_state->source,
+                                "  cogl_snippet%i ();\n",
+                                snippet_num - 1);
+      else
+        g_string_append (shader_state->source,
+                         "  cogl_generated_source ();\n");
       g_string_append (shader_state->source, "}\n");
 
       GE_RET( shader, ctx, glCreateShader (GL_FRAGMENT_SHADER) );
diff --git a/cogl/cogl-pipeline-vertend-glsl.c b/cogl/cogl-pipeline-vertend-glsl.c
index a6cadee..6803758 100644
--- a/cogl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/cogl-pipeline-vertend-glsl.c
@@ -146,7 +146,6 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
 {
   CoglPipelineShaderState *shader_state;
   CoglPipeline *template_pipeline = NULL;
-  CoglPipelineSnippet *snippet;
   CoglProgram *user_program;
 
   _COGL_GET_CONTEXT (ctx, FALSE);
@@ -262,40 +261,9 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
 
   g_string_append (shader_state->source,
                    "void\n"
-                   "main ()\n"
+                   "cogl_generated_source ()\n"
                    "{\n");
 
-  COGL_LIST_FOREACH (snippet, get_vertex_snippets (pipeline), list_node)
-    {
-      const char *declarations =
-        cogl_snippet_get_declarations (snippet->snippet);
-
-      /* Add all of the declarations for vertex snippets */
-      if (declarations)
-        {
-          g_string_append (shader_state->header, declarations);
-          g_string_append_c (shader_state->header, '\n');
-        }
-
-      /* Add all of the pre-hooks for vertex processing */
-      if (snippet->hook == COGL_PIPELINE_SNIPPET_HOOK_VERTEX)
-        {
-          const char *pre =
-            cogl_snippet_get_pre (snippet->snippet);
-
-          if (pre)
-            {
-              g_string_append (shader_state->source, "  {\n");
-              g_string_append (shader_state->source, pre);
-              g_string_append (shader_state->source, "  }\n");
-            }
-        }
-    }
-
-  /* Enclose the generated vertex processing in a block so that any
-     variables declared in it won't be in the scope of the snippets */
-  g_string_append (shader_state->source, "  {\n");
-
   if (ctx->driver == COGL_DRIVER_GLES2)
     /* There is no builtin uniform for the pointsize on GLES2 so we need
        to copy it from the custom uniform in the vertex shader */
@@ -393,6 +361,7 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
       GLint compile_status;
       GLuint shader;
       CoglPipelineSnippet *snippet;
+      int snippet_num;
 
       COGL_STATIC_COUNTER (vertend_glsl_compile_counter,
                            "glsl vertex compile counter",
@@ -406,23 +375,57 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
                        "cogl_modelview_projection_matrix * "
                        "cogl_position_in;\n"
                        "  cogl_color_out = cogl_color_in;\n"
-                       "  }\n");
+                       "}\n");
 
       /* Add all of the post-hooks for vertex processing */
+      snippet_num = 0;
       COGL_LIST_FOREACH (snippet, get_vertex_snippets (pipeline), list_node)
         if (snippet->hook == COGL_PIPELINE_SNIPPET_HOOK_VERTEX)
           {
-            const char *post =
-              cogl_snippet_get_post (snippet->snippet);
-
-            if (post)
-              {
-                g_string_append (shader_state->source, "  {\n");
-                g_string_append (shader_state->source, post);
-                g_string_append (shader_state->source, "  }\n");
-              }
+            const char *source;
+
+            if ((source = cogl_snippet_get_declarations (snippet->snippet)))
+              g_string_append (shader_state->source, source);
+
+            g_string_append_printf (shader_state->source,
+                                    "\n"
+                                    "void\n"
+                                    "cogl_snippet%i ()\n"
+                                    "{\n",
+                                    snippet_num);
+
+            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)
+              g_string_append_printf (shader_state->source,
+                                      "  cogl_snippet%i ();\n",
+                                      snippet_num - 1);
+            else
+              g_string_append (shader_state->source,
+                               "  cogl_generated_source ();\n");
+
+            if ((source = cogl_snippet_get_post (snippet->snippet)))
+              g_string_append (shader_state->source, source);
+
+            g_string_append (shader_state->source, "}\n");
+
+            snippet_num++;
           }
 
+      g_string_append (shader_state->source,
+                       "\n"
+                       "void\n"
+                       "main ()\n"
+                       "{\n");
+      if (snippet_num > 0)
+        g_string_append_printf (shader_state->source,
+                                "  cogl_snippet%i ();\n",
+                                snippet_num - 1);
+      else
+        g_string_append (shader_state->source,
+                         "  cogl_generated_source ();\n");
       g_string_append (shader_state->source, "}\n");
 
       GE_RET( shader, ctx, glCreateShader (GL_VERTEX_SHADER) );
diff --git a/tests/conform/test-snippets.c b/tests/conform/test-snippets.c
index 1246fdf..6a5bf60 100644
--- a/tests/conform/test-snippets.c
+++ b/tests/conform/test-snippets.c
@@ -105,14 +105,14 @@ paint (TestState *state)
 
   cogl_object_unref (pipeline);
 
-  /* The pre string can't really do anything with the current hooks,
-     but let's just test that it compiles */
+  /* Test that the pre string can declare variables used by the post
+     string */
   pipeline = cogl_pipeline_new ();
 
-  cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
+  cogl_pipeline_set_color4ub (pipeline, 255, 255, 255, 255);
 
-  snippet = cogl_snippet_new (NULL, NULL);
-  cogl_snippet_set_pre (snippet, "cogl_color_out = vec4 (1.0, 0.5, 0.8, 1.0);");
+  snippet = cogl_snippet_new (NULL, "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_object_unref (snippet);



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