[Cogl] [PATCH] gles2-context: only insert prelude + wrapper into strv once

Robert Bragg robert at sixbynine.org
Tue Aug 28 05:56:43 PDT 2012


From: Robert Bragg <robert at linux.intel.com>

In our wrapper for glShaderSource we special case when a vertex shader
is being specified so we can sneak in a wrapper for the main function to
potentially flip all rendering upside down for better integration with
Cogl.

Previously we were appending the wrapper to all the sub-strings passed
via the vector of strings to glShaderSource but we now grow the vector
instead and insert the prelude and wrapper strings into the beginning
and end of the vector respectively so we should only have one copy for a
single shader.
---
 cogl/cogl-gles2-context.c |   55 ++++++++++++++++++++++++--------------------
 1 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/cogl/cogl-gles2-context.c b/cogl/cogl-gles2-context.c
index 8568e43..b7406b3 100644
--- a/cogl/cogl-gles2-context.c
+++ b/cogl/cogl-gles2-context.c
@@ -60,9 +60,9 @@ static CoglUserDataKey offscreen_wrapper_key;
  * whether we are rendering to an offscreen buffer or not */
 #define MAIN_WRAPPER_FLIP_UNIFORM "_cogl_flip_vector"
 
-/* This wrapper function around 'main' is appended to every program in
- * a separate shader so that we can add some extra code to flip the
- * rendering when rendering to an offscreen buffer */
+/* This wrapper function around 'main' is appended to every vertex shader
+ * so that we can add some extra code to flip the rendering when
+ * rendering to an offscreen buffer */
 static const char
 main_wrapper_prelude[] =
   "uniform vec4 " MAIN_WRAPPER_FLIP_UNIFORM ";\n"
@@ -827,43 +827,48 @@ gl_shader_source_wrapper (GLuint shader,
                                           GINT_TO_POINTER (shader))) &&
       shader_data->type == GL_VERTEX_SHADER)
     {
-      char **string_copy = g_alloca (count * sizeof (char *));
-      GLint *length_copy = g_alloca (count * sizeof (GLint));
+      char **string_copy = g_alloca ((count + 2) * sizeof (char *));
+      int *length_copy = g_alloca ((count +2) * sizeof (int));
       int i;
 
-      /* First, copy the shader into a new string; then, replace all
-       * instances of the symbol 'main' with our replacement symbol
-       * so we can provide our own wrapper main function; then append
-       * that wrapper function. */
+      string_copy[0] = main_wrapper_prelude;
+      length_copy[0] = -1;
+
+      /* Replace any occurences of the symbol 'main' with a different
+       * symbol so that we can provide our own wrapper main
+       * function */
+
       for (i = 0; i < count; i++)
         {
-          int string_length = length ? length[i] : strlen (string[i]);
-          int prelude_length = strlen (main_wrapper_prelude);
-          int wrapper_length = strlen (main_wrapper_function);
-
-          length_copy[i] = string_length + prelude_length + wrapper_length;
-          string_copy[i] = g_malloc (length_copy[i] + 1);
-          memcpy (string_copy[i], string[i], string_length);
-          string_copy[i][string_length] = '\0';
+          int string_length;
+
+          if (length == NULL || length[i] < 0)
+            string_length = strlen (string[i]);
+          else
+            string_length = length[i];
+
+          string_copy[i + 1] = g_memdup (string[i], string_length);
+
           replace_token (string_copy[i],
                          "main",
                          MAIN_WRAPPER_REPLACEMENT_NAME,
                          string_length);
 
-          memmove (&string_copy[i][prelude_length], string_copy[i],
-                   string_length);
-          memcpy (string_copy[i], main_wrapper_prelude, prelude_length);
-          memcpy (&string_copy[i][prelude_length + string_length],
-                  main_wrapper_function, wrapper_length);
-          string_copy[i][length_copy[i]] = '\0';
+          length_copy[i + 1] = string_length;
         }
 
+      string_copy[count + 1] = main_wrapper_function;
+      length_copy[count + 1] = -1;
+
       gles2_ctx->context->glShaderSource (shader,
-                                          count,
+                                          count + 2,
                                           (const char *const *) string_copy,
                                           length_copy);
 
-      for (i = 0; i < count; i++)
+      /* Note: we don't need to free the first and last entries in
+       * string_copy[] which are our prelude and wrapper strings
+       * respectively... */
+      for (i = 1; i < count; i++)
         g_free (string_copy[i]);
     }
   else
-- 
1.7.7.6



More information about the Cogl mailing list