[cogl/cogl-1.12] gles2-context: Don't split the wrapper snippet into two



commit 1b3a7ac0ab882278638a787dc339e56255c3feea
Author: Neil Roberts <neil linux intel com>
Date:   Tue Aug 28 17:30:47 2012 +0100

    gles2-context: Don't split the wrapper snippet into two
    
    We don't need to split the wrapper snippet into two separate parts
    because it should be ok to declare the flip uniform in the middle of
    the shader as long as it is somewhere in the global scope. Therefore
    we can just declare it right before the definition for the replacement
    main function. This is important because we don't want to put anything
    at the top of the application's shader in case it is using a
    '#version' directive. In that case moving it to anything other than
    the first line would break things.
    
    This patch also adds a marker in a comment around the wrapper snippet
    so that we can easily locate the snippet when glGetShaderSource is
    called and remove it.
    
    The wrapper for glGetAttachedShaders has been removed because there
    are no longer any additional shaders attached to the program so we can
    just let GL handle it directly.
    
    Reviewed-by: Robert Bragg <robert linux intel com>
    
    (cherry picked from commit dbd92e24ae61dcbe7ef26f61c9117c5516a7fa87)

 cogl/cogl-gles2-context.c |   87 ++++++++++++++++++--------------------------
 1 files changed, 36 insertions(+), 51 deletions(-)
---
diff --git a/cogl/cogl-gles2-context.c b/cogl/cogl-gles2-context.c
index 012b362..ba2923e 100644
--- a/cogl/cogl-gles2-context.c
+++ b/cogl/cogl-gles2-context.c
@@ -59,24 +59,27 @@ static CoglUserDataKey offscreen_wrapper_key;
 /* This uniform is used to flip the rendering or not depending on
  * whether we are rendering to an offscreen buffer or not */
 #define MAIN_WRAPPER_FLIP_UNIFORM "_cogl_flip_vector"
+/* These comments are used to delimit the added wrapper snippet so
+ * that we can remove it again when the shader source is requested via
+ * glGetShaderSource */
+#define MAIN_WRAPPER_BEGIN "/*_COGL_WRAPPER_BEGIN*/"
+#define MAIN_WRAPPER_END "/*_COGL_WRAPPER_END*/"
 
 /* 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"
-  "\n";
-
-static const char
 main_wrapper_function[] =
+  MAIN_WRAPPER_BEGIN "\n"
+  "uniform vec4 " MAIN_WRAPPER_FLIP_UNIFORM ";\n"
   "\n"
   "void\n"
   "main ()\n"
   "{\n"
   "  " MAIN_WRAPPER_REPLACEMENT_NAME " ();\n"
   "  gl_Position *= " MAIN_WRAPPER_FLIP_UNIFORM ";\n"
-  "}\n";
+  "}\n"
+  MAIN_WRAPPER_END;
 
 enum {
   RESTORE_FB_NONE,
@@ -827,13 +830,10 @@ gl_shader_source_wrapper (GLuint shader,
                                           GINT_TO_POINTER (shader))) &&
       shader_data->type == GL_VERTEX_SHADER)
     {
-      char **string_copy = g_alloca ((count + 2) * sizeof (char *));
-      int *length_copy = g_alloca ((count +2) * sizeof (int));
+      char **string_copy = g_alloca ((count + 1) * sizeof (char *));
+      int *length_copy = g_alloca ((count + 1) * sizeof (int));
       int i;
 
-      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 */
@@ -847,28 +847,27 @@ gl_shader_source_wrapper (GLuint shader,
           else
             string_length = length[i];
 
-          string_copy[i + 1] = g_memdup (string[i], string_length);
+          string_copy[i] = g_memdup (string[i], string_length);
 
           replace_token (string_copy[i],
                          "main",
                          MAIN_WRAPPER_REPLACEMENT_NAME,
                          string_length);
 
-          length_copy[i + 1] = string_length;
+          length_copy[i] = string_length;
         }
 
-      string_copy[count + 1] = main_wrapper_function;
-      length_copy[count + 1] = -1;
+      string_copy[count] = (char *) main_wrapper_function;
+      length_copy[count] = sizeof (main_wrapper_function) - 1;
 
       gles2_ctx->context->glShaderSource (shader,
-                                          count + 2,
+                                          count + 1,
                                           (const char *const *) string_copy,
                                           length_copy);
 
-      /* 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++)
+      /* Note: we don't need to free the last entry in string_copy[]
+       * because it is our static wrapper string... */
+      for (i = 0; i < count; i++)
         g_free (string_copy[i]);
     }
   else
@@ -895,6 +894,23 @@ gl_get_shader_source_wrapper (GLuint shader,
       shader_data->type == GL_VERTEX_SHADER)
     {
       GLsizei copy_length = MIN (length, buf_size - 1);
+      static const char wrapper_marker[] = MAIN_WRAPPER_BEGIN;
+      char *wrapper_start;
+
+      /* Strip out the wrapper snippet we added when the source was
+       * specified */
+      wrapper_start = _cogl_util_memmem (source,
+                                         copy_length,
+                                         wrapper_marker,
+                                         sizeof (wrapper_marker) - 1);
+      if (wrapper_start)
+        {
+          length = wrapper_start - source;
+          copy_length = length;
+          *wrapper_start = '\0';
+        }
+
+      /* Correct the name of the main function back to its original */
       replace_token (source,
                      MAIN_WRAPPER_REPLACEMENT_NAME,
                      "main",
@@ -950,36 +966,6 @@ gl_get_program_iv_wrapper (GLuint program,
 }
 
 static void
-gl_get_attached_shaders_wrapper (GLuint program,
-                                 GLsizei max_count,
-                                 GLsizei *count_ret,
-                                 GLuint *obj)
-{
-  CoglGLES2Context *gles2_ctx = current_gles2_context;
-  GLuint *tmp_buf;
-  GLsizei count, count_out;
-  int i;
-
-  /* We need to remove the wrapper shader we added from this list */
-
-  /* Allocate a temporary buffer that is one larger than the buffer
-   * passed in in case the application allocated exactly the size
-   * returned by GL_ATTACHED_SHADERS. */
-  tmp_buf = g_alloca (sizeof (GLuint) * (max_count + 1));
-
-  gles2_ctx->context->glGetAttachedShaders (program,
-                                            max_count + 1,
-                                            &count,
-                                            tmp_buf);
-
-  for (i = 0, count_out = 0; i < count; i++)
-    obj[count_out++] = tmp_buf[i];
-
-  if (count_ret)
-    *count_ret = count_out;
-}
-
-static void
 flush_viewport_state (CoglGLES2Context *gles2_ctx)
 {
   if (gles2_ctx->viewport_dirty)
@@ -1636,7 +1622,6 @@ cogl_gles2_context_new (CoglContext *ctx, GError **error)
   gles2_ctx->vtable->glGetShaderSource = gl_get_shader_source_wrapper;
   gles2_ctx->vtable->glLinkProgram = gl_link_program_wrapper;
   gles2_ctx->vtable->glGetProgramiv = gl_get_program_iv_wrapper;
-  gles2_ctx->vtable->glGetAttachedShaders = gl_get_attached_shaders_wrapper;
   gles2_ctx->vtable->glGetProgramInfoLog = gl_get_program_info_log_wrapper;
   gles2_ctx->vtable->glGetShaderInfoLog = gl_get_shader_info_log_wrapper;
   gles2_ctx->vtable->glClear = gl_clear_wrapper;



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