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



commit d2904d518718e3fbf4441abe2c2bcfd63edfd64b
Author: Robert Bragg <robert linux intel com>
Date:   Tue Aug 28 13:56:43 2012 +0100

    gles2-context: only insert prelude + wrapper into strv once
    
    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.
    
    Reviewed-by: Neil Roberts <neil linux intel com>

 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 789f848..e5646b2 100644
--- a/cogl/cogl-gles2-context.c
+++ b/cogl/cogl-gles2-context.c
@@ -62,9 +62,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"
@@ -829,43 +829,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



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