[cogl/cogl-1.14: 73/174] Adds back tex_coord array for CoglShader compatibility



commit 7fa04bb1a667abd27ffcf39bd595bc777dbe75c3
Author: Robert Bragg <robert linux intel com>
Date:   Sat Jan 19 16:00:33 2013 +0000

    Adds back tex_coord array for CoglShader compatibility
    
    This adds back compatibility for CoglShaders that reference the
    cogl_tex_coord_in[] or cogl_tex_coord_out[] varyings. Unlike the
    previous way this was done this patch maintains the use of layer numbers
    for attributes and maintains forwards compatibility by letting shaders
    alternatively access the per-layer tex_coord varyings via
    cogl_tex_coord%i_in/out defines that index into the array.

 cogl/cogl-context-private.h                 |    1 +
 cogl/cogl-context.c                         |    1 +
 cogl/cogl-glsl-shader-boilerplate.h         |    2 +
 cogl/cogl-glsl-shader-private.h             |    1 +
 cogl/cogl-glsl-shader.c                     |   67 ++++++++++-
 cogl/cogl-pipeline-private.h                |    4 +
 cogl/cogl-pipeline.c                        |   35 ++++++
 cogl/cogl-shader-private.h                  |   14 ++-
 cogl/cogl-shader.c                          |  172 +++++++++++++--------------
 cogl/driver/gl/cogl-pipeline-fragend-glsl.c |   48 +++-----
 cogl/driver/gl/cogl-pipeline-progend-glsl.c |    4 +-
 cogl/driver/gl/cogl-pipeline-vertend-glsl.c |   55 +++------
 12 files changed, 232 insertions(+), 172 deletions(-)
---
diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h
index 06acc3c..6340002 100644
--- a/cogl/cogl-context-private.h
+++ b/cogl/cogl-context-private.h
@@ -140,6 +140,7 @@ struct _CoglContext
   CoglPipeline     *texture_pipeline; /* used for set_source_texture */
   GString          *codegen_header_buffer;
   GString          *codegen_source_buffer;
+  GString          *codegen_boilerplate_buffer;
   GList            *source_stack;
 
   int               legacy_state_set;
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index 207d68c..86965e2 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -293,6 +293,7 @@ cogl_context_new (CoglDisplay *display,
   context->texture_pipeline = cogl_pipeline_new (context);
   context->codegen_header_buffer = g_string_new ("");
   context->codegen_source_buffer = g_string_new ("");
+  context->codegen_boilerplate_buffer = g_string_new ("");
   context->source_stack = NULL;
 
   context->legacy_state_set = 0;
diff --git a/cogl/cogl-glsl-shader-boilerplate.h b/cogl/cogl-glsl-shader-boilerplate.h
index 89b2c74..7a79fd3 100644
--- a/cogl/cogl-glsl-shader-boilerplate.h
+++ b/cogl/cogl-glsl-shader-boilerplate.h
@@ -44,6 +44,7 @@
   _COGL_COMMON_SHADER_BOILERPLATE \
   "#define cogl_color_out _cogl_color\n" \
   "varying vec4 _cogl_color;\n" \
+  "#define cogl_tex_coord_out _cogl_tex_coord\n" \
   "#define cogl_position_out gl_Position\n" \
   "#define cogl_point_size_out gl_PointSize\n" \
   "\n" \
@@ -61,6 +62,7 @@
   "varying vec4 _cogl_color;\n" \
   "\n" \
   "#define cogl_color_in _cogl_color\n" \
+  "#define cogl_tex_coord_in _cogl_tex_coord\n" \
   "\n" \
   "#define cogl_color_out gl_FragColor\n" \
   "#define cogl_depth_out gl_FragDepth\n" \
diff --git a/cogl/cogl-glsl-shader-private.h b/cogl/cogl-glsl-shader-private.h
index 1ec9762..816aec2 100644
--- a/cogl/cogl-glsl-shader-private.h
+++ b/cogl/cogl-glsl-shader-private.h
@@ -28,6 +28,7 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
                                                const char *version_string,
                                                GLuint shader_gl_handle,
                                                GLenum shader_gl_type,
+                                               CoglPipeline *pipeline,
                                                GLsizei count_in,
                                                const char **strings_in,
                                                const GLint *lengths_in);
diff --git a/cogl/cogl-glsl-shader.c b/cogl/cogl-glsl-shader.c
index fc3c4f0..894bafd 100644
--- a/cogl/cogl-glsl-shader.c
+++ b/cogl/cogl-glsl-shader.c
@@ -39,11 +39,42 @@
 
 #include <glib.h>
 
+static CoglBool
+add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer,
+                                 void *user_data)
+{
+  GString *layer_declarations = user_data;
+  int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
+  g_string_append_printf (layer_declarations,
+                          "attribute vec4 cogl_tex_coord%d_in;\n"
+                          "#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n"
+                          "#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n",
+                          layer->index,
+                          layer->index,
+                          unit_index,
+                          layer->index,
+                          unit_index);
+  return TRUE;
+}
+
+static CoglBool
+add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer,
+                                   void *user_data)
+{
+  GString *layer_declarations = user_data;
+  g_string_append_printf (layer_declarations,
+                          "#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n",
+                          layer->index,
+                          _cogl_pipeline_layer_get_unit_index (layer));
+  return TRUE;
+}
+
 void
 _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
                                                const char *version_string,
                                                GLuint shader_gl_handle,
                                                GLenum shader_gl_type,
+                                               CoglPipeline *pipeline,
                                                GLsizei count_in,
                                                const char **strings_in,
                                                const GLint *lengths_in)
@@ -54,7 +85,8 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
   const char **strings = g_alloca (sizeof (char *) * (count_in + 4));
   GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4));
   int count = 0;
-  char *tex_coord_declarations = NULL;
+
+  int n_layers;
 
   vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE;
   fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE;
@@ -85,6 +117,37 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
       lengths[count++] = strlen (fragment_boilerplate);
     }
 
+  n_layers = cogl_pipeline_get_n_layers (pipeline);
+  if (n_layers)
+    {
+      GString *layer_declarations = ctx->codegen_boilerplate_buffer;
+      g_string_set_size (layer_declarations, 0);
+
+      g_string_append_printf (layer_declarations,
+                              "varying vec4 _cogl_tex_coord[%d];\n",
+                              n_layers);
+
+      if (shader_gl_type == GL_VERTEX_SHADER)
+        {
+          g_string_append_printf (layer_declarations,
+                                  "uniform mat4 cogl_texture_matrix[%d];\n",
+                                  n_layers);
+
+          _cogl_pipeline_foreach_layer_internal (pipeline,
+                                                 add_layer_vertex_boilerplate_cb,
+                                                 layer_declarations);
+        }
+      else if (shader_gl_type == GL_FRAGMENT_SHADER)
+        {
+          _cogl_pipeline_foreach_layer_internal (pipeline,
+                                                 add_layer_fragment_boilerplate_cb,
+                                                 layer_declarations);
+        }
+
+      strings[count] = layer_declarations->str;
+      lengths[count++] = -1; /* null terminated */
+    }
+
   memcpy (strings + count, strings_in, sizeof (char *) * count_in);
   if (lengths_in)
     memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in);
@@ -119,6 +182,4 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
 
   GE( ctx, glShaderSource (shader_gl_handle, count,
                            (const char **) strings, lengths) );
-
-  g_free (tex_coord_declarations);
 }
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
index 595444f..74a5fd5 100644
--- a/cogl/cogl-pipeline-private.h
+++ b/cogl/cogl-pipeline-private.h
@@ -930,6 +930,10 @@ _cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0,
                                     CoglPipeline *pipeline1);
 
 CoglBool
+_cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0,
+                                             CoglPipeline *pipeline1);
+
+CoglBool
 _cogl_pipeline_need_texture_combine_separate
                                     (CoglPipelineLayer *combine_authority);
 
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index f18b044..ef2d933 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -646,6 +646,41 @@ _cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0,
   return TRUE;
 }
 
+CoglBool
+_cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0,
+                                             CoglPipeline *pipeline1)
+{
+  CoglPipeline *authority0 =
+    _cogl_pipeline_get_authority (pipeline0, COGL_PIPELINE_STATE_LAYERS);
+  CoglPipeline *authority1 =
+    _cogl_pipeline_get_authority (pipeline1, COGL_PIPELINE_STATE_LAYERS);
+  int n_layers = authority0->n_layers;
+  int i;
+
+  if (authority1->n_layers != n_layers)
+    return FALSE;
+
+  _cogl_pipeline_update_layers_cache (authority0);
+  _cogl_pipeline_update_layers_cache (authority1);
+
+  for (i = 0; i < n_layers; i++)
+    {
+      CoglPipelineLayer *layer0 = authority0->layers_cache[i];
+      CoglPipelineLayer *layer1 = authority1->layers_cache[i];
+      int unit0, unit1;
+
+      if (layer0->index != layer1->index)
+        return FALSE;
+
+      unit0 = _cogl_pipeline_layer_get_unit_index (layer0);
+      unit1 = _cogl_pipeline_layer_get_unit_index (layer1);
+      if (unit0 != unit1)
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
 typedef struct
 {
   int i;
diff --git a/cogl/cogl-shader-private.h b/cogl/cogl-shader-private.h
index b23cb42..8ad8335 100644
--- a/cogl/cogl-shader-private.h
+++ b/cogl/cogl-shader-private.h
@@ -27,6 +27,7 @@
 #include "cogl-object-private.h"
 #include "cogl-shader.h"
 #include "cogl-gl-header.h"
+#include "cogl-pipeline.h"
 
 typedef struct _CoglShader CoglShader;
 
@@ -38,16 +39,17 @@ typedef enum
 
 struct _CoglShader
 {
-  CoglHandleObject   _parent;
-  GLuint             gl_handle;
-  int                n_tex_coord_attribs;
-  CoglShaderType     type;
+  CoglHandleObject _parent;
+  GLuint gl_handle;
+  CoglPipeline *compilation_pipeline;
+  CoglShaderType type;
   CoglShaderLanguage language;
-  char              *source;
+  char *source;
 };
 
 void
-_cogl_shader_compile_real (CoglHandle handle, int n_tex_coord_attribs);
+_cogl_shader_compile_real (CoglHandle handle,
+                           CoglPipeline *pipeline);
 
 CoglShaderLanguage
 _cogl_program_get_language (CoglHandle handle);
diff --git a/cogl/cogl-shader.c b/cogl/cogl-shader.c
index d28133a..629575a 100644
--- a/cogl/cogl-shader.c
+++ b/cogl/cogl-shader.c
@@ -90,7 +90,7 @@ cogl_create_shader (CoglShaderType type)
   shader = g_slice_new (CoglShader);
   shader->language = COGL_SHADER_LANGUAGE_GLSL;
   shader->gl_handle = 0;
-  shader->n_tex_coord_attribs = 0;
+  shader->compilation_pipeline = NULL;
   shader->type = type;
 
   return _cogl_shader_handle_new (shader);
@@ -115,6 +115,12 @@ delete_shader (CoglShader *shader)
     }
 
   shader->gl_handle = 0;
+
+  if (shader->compilation_pipeline)
+    {
+      cogl_object_unref (shader->compilation_pipeline);
+      shader->compilation_pipeline = NULL;
+    }
 }
 
 void
@@ -151,14 +157,22 @@ cogl_shader_source (CoglHandle   handle,
 void
 cogl_shader_compile (CoglHandle handle)
 {
+  CoglShader *shader;
+
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
 
   if (!cogl_is_shader (handle))
     return;
 
-  /* XXX: We don't actually compile anything until the shader gets
-   * used so we have an opportunity to add some boilerplate to the
-   * shader.
+#ifdef HAVE_COGL_GL
+  shader = handle;
+  if (shader->language == COGL_SHADER_LANGUAGE_ARBFP)
+    _cogl_shader_compile_real (handle, NULL);
+#endif
+
+  /* XXX: For GLSL we don't actually compile anything until the shader
+   * gets used so we have an opportunity to add some boilerplate to
+   * the shader.
    *
    * At the end of the day this is obviously a badly designed API
    * given that we are having to lie to the user. It was a mistake to
@@ -168,7 +182,7 @@ cogl_shader_compile (CoglHandle handle)
 
 void
 _cogl_shader_compile_real (CoglHandle handle,
-                           int n_tex_coord_attribs)
+                           CoglPipeline *pipeline)
 {
   CoglShader *shader = handle;
   const char *version;
@@ -216,10 +230,20 @@ _cogl_shader_compile_real (CoglHandle handle,
 #endif
     {
       GLenum gl_type;
+      GLint status;
 
-      if (shader->gl_handle &&
-          shader->n_tex_coord_attribs == n_tex_coord_attribs)
-        return;
+      if (shader->gl_handle)
+        {
+          CoglPipeline *prev = shader->compilation_pipeline;
+
+          /* XXX: currently the only things that will affect the
+           * boilerplate for user shaders, apart from driver features,
+           * are the pipeline layer-indices and texture-unit-indices
+           */
+          if (pipeline == prev ||
+              _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline))
+            return;
+        }
 
       if (shader->gl_handle)
         delete_shader (shader);
@@ -253,6 +277,7 @@ _cogl_shader_compile_real (CoglHandle handle,
                                                      version,
                                                      shader->gl_handle,
                                                      gl_type,
+                                                     pipeline,
                                                      1,
                                                      (const char **)
                                                       &shader->source,
@@ -260,67 +285,51 @@ _cogl_shader_compile_real (CoglHandle handle,
 
       GE (ctx, glCompileShader (shader->gl_handle));
 
-      shader->n_tex_coord_attribs = n_tex_coord_attribs;
+      shader->compilation_pipeline = cogl_object_ref (pipeline);
 
-#ifdef COGL_GL_DEBUG
-      if (!cogl_shader_is_compiled (handle))
+      GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
+      if (!status)
         {
-          char *log = cogl_shader_get_info_log (handle);
-          g_warning ("Failed to compile GLSL program:\nsrc:\n%s\nerror:\n%s\n",
+          char buffer[512];
+          int len = 0;
+
+          ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
+          buffer[len] = '\0';
+
+          g_warning ("Failed to compile GLSL program:\n"
+                     "src:\n%s\n"
+                     "error:\n%s\n",
                      shader->source,
-                     log);
-          g_free (log);
+                     buffer);
         }
-#endif
     }
 }
 
 char *
 cogl_shader_get_info_log (CoglHandle handle)
 {
-  CoglShader *shader;
-
-  _COGL_GET_CONTEXT (ctx, NULL);
-
   if (!cogl_is_shader (handle))
     return NULL;
 
-  shader = handle;
+  /* XXX: This API doesn't really do anything!
+   *
+   * This API is purely for compatibility
+   *
+   * The reason we don't do anything is because a shader needs to
+   * be associated with a CoglPipeline for Cogl to be able to
+   * compile and link anything.
+   *
+   * The way this API was originally designed as a very thin wrapper
+   * over the GL api was a mistake and it's now very difficult to
+   * make the API work in a meaningful way given how the rest of Cogl
+   * has evolved.
+   *
+   * The CoglShader API is mostly deprecated by CoglSnippets and so
+   * these days we do the bare minimum to support the existing users
+   * of it until they are able to migrate to the snippets api.
+   */
 
-#ifdef HAVE_COGL_GL
-  if (shader->language == COGL_SHADER_LANGUAGE_ARBFP)
-    {
-      /* ARBfp exposes a program error string, but since cogl_program
-       * doesn't have any API to query an error log it is not currently
-       * exposed. */
-      return g_strdup ("");
-    }
-  else
-#endif
-    {
-      char buffer[512];
-      int len = 0;
-
-      /* We don't normally compile the shader when the user calls
-       * cogl_shader_compile() because we want to be able to add
-       * boilerplate code that depends on how it ends up finally being
-       * used.
-       *
-       * Here we force an early compile if the user is interested in
-       * log information to increase the chance that the log will be
-       * useful! We have to guess the number of texture coordinate
-       * attributes that may be used since that affects the
-       * boilerplate. We use four so that the shader will still
-       * compile if the user is using more than one
-       * layer. Unfortunately this is likely to end up causing it to
-       * be compiled again when we know the actual number of layers */
-      if (!shader->gl_handle)
-        _cogl_shader_compile_real (handle, 4);
-
-      ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
-      buffer[len] = '\0';
-      return g_strdup (buffer);
-    }
+  return g_strdup ("");
 }
 
 CoglShaderType
@@ -344,46 +353,29 @@ CoglBool
 cogl_shader_is_compiled (CoglHandle handle)
 {
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2)
-  GLint status;
-  CoglShader *shader;
-
-  _COGL_GET_CONTEXT (ctx, FALSE);
-
   if (!cogl_is_shader (handle))
     return FALSE;
 
-  shader = handle;
+  /* XXX: This API doesn't really do anything!
+   *
+   * This API is purely for compatibility and blatantly lies to the
+   * user about whether their shader has been compiled.
+   *
+   * I suppose we could say we're stretching the definition of
+   * "compile" and are deferring any related errors to be "linker"
+   * errors.
+   *
+   * The reason we don't do anything is because a shader needs to
+   * be associated with a CoglPipeline for Cogl to be able to
+   * compile and link anything.
+   *
+   * The CoglShader API is mostly deprecated by CoglSnippets and so
+   * these days we do the bare minimum to support the existing users
+   * of it until they are able to migrate to the snippets api.
+   */
 
-#ifdef HAVE_COGL_GL
-  if (shader->language == COGL_SHADER_LANGUAGE_ARBFP)
-    return TRUE;
-  else
-#endif
-    {
-      /* FIXME: We currently have an arbitrary limit of 4 texture
-       * coordinate attributes since our API means we have to add
-       * some boilerplate to the users GLSL program (for GLES2)
-       * before we actually know how many attributes are in use.
-       *
-       * 4 will probably be enough (or at least that limitation should
-       * be enough until we can replace this API with the pipeline
-       * snippets API) but if it isn't then the shader won't compile,
-       * through no fault of the user.
-       *
-       * To some extent this is just a symptom of bad API design; it
-       * was a mistake for Cogl to so thinly wrap the OpenGL shader
-       * API. Eventually we plan for this whole API will be deprecated
-       * by the pipeline snippets framework.
-       */
-      if (!shader->gl_handle)
-        _cogl_shader_compile_real (handle, 4);
+  return TRUE;
 
-      GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
-      if (status == GL_TRUE)
-        return TRUE;
-      else
-        return FALSE;
-    }
 #else
   return FALSE;
 #endif
diff --git a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
index bc57dd5..ef6f0c1 100644
--- a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
@@ -101,12 +101,6 @@ typedef struct
      again */
   LayerDataList layers;
 
-  /* Age of the user program that was current when the shader was
-     generated. We need to keep track of this because if the user
-     program changes then we may need to redecide whether to generate
-     a shader at all */
-  unsigned int user_program_age;
-
 } CoglPipelineShaderState;
 
 static CoglUserDataKey shader_state_key;
@@ -288,34 +282,28 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
         }
     }
 
-  if (shader_state->gl_shader)
-    {
-      /* If we already have a valid GLSL shader then we don't need to generate
-       * a new one. However if there's a user program and it has changed since
-       * the last link then we do need a new shader. */
-      if (user_program == NULL ||
-          shader_state->user_program_age == user_program->age)
-        return;
-
-      /* We need to recreate the shader so destroy the existing one */
-      GE( ctx, glDeleteShader (shader_state->gl_shader) );
-      shader_state->gl_shader = 0;
-    }
-
-  /* If we make it here then we have a glsl_shader_state struct
-     without a gl_shader either because this is the first time we've
-     encountered it or because the user program has changed */
-
   if (user_program)
     {
-      shader_state->user_program_age = user_program->age;
-
       /* If the user program contains a fragment shader then we don't need
          to generate one */
       if (_cogl_program_has_fragment_shader (user_program))
-        return;
+        {
+          if (shader_state->gl_shader)
+            {
+              GE( ctx, glDeleteShader (shader_state->gl_shader) );
+              shader_state->gl_shader = 0;
+            }
+          return;
+        }
     }
 
+  if (shader_state->gl_shader)
+    return;
+
+  /* If we make it here then we have a glsl_shader_state struct
+     without a gl_shader either because this is the first time we've
+     encountered it or because the user program has changed */
+
   /* We reuse two grow-only GStrings for code-gen. One string
      contains the uniform and attribute declarations while the
      other contains the main function. We need two strings
@@ -1017,12 +1005,7 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
               get_texture_target_string (texture_type, &target_string, NULL);
 
               g_string_append_printf (shader_state->header,
-                                      "varying vec4 _cogl_tex_coord%i;\n"
-                                      "#define cogl_tex_coord%i_in _cogl_tex_coord%i\n"
                                       "uniform sampler%s cogl_sampler%i;\n",
-                                      layer->index,
-                                      layer->index,
-                                      layer->index,
                                       target_string,
                                       layer->index);
             }
@@ -1077,6 +1060,7 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
       _cogl_glsl_shader_set_source_with_boilerplate (ctx,
                                                      version_string,
                                                      shader, GL_FRAGMENT_SHADER,
+                                                     pipeline,
                                                      2, /* count */
                                                      source_strings, lengths);
 
diff --git a/cogl/driver/gl/cogl-pipeline-progend-glsl.c b/cogl/driver/gl/cogl-pipeline-progend-glsl.c
index 6e9dec7..417e156 100644
--- a/cogl/driver/gl/cogl-pipeline-progend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-progend-glsl.c
@@ -377,7 +377,7 @@ get_uniform_cb (CoglPipeline *pipeline,
 
   g_string_set_size (ctx->codegen_source_buffer, 0);
   g_string_append_printf (ctx->codegen_source_buffer,
-                          "cogl_texture_matrix%i", layer_index);
+                          "cogl_texture_matrix[%i]", layer_index);
 
   GE_RET( uniform_location,
           ctx, glGetUniformLocation (state->gl_program,
@@ -725,7 +725,7 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
             {
               CoglShader *shader = l->data;
 
-              _cogl_shader_compile_real (shader, 4);
+              _cogl_shader_compile_real (shader, pipeline);
 
               g_assert (shader->language == COGL_SHADER_LANGUAGE_GLSL);
 
diff --git a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
index 61e3939..8aea1eb 100644
--- a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
@@ -54,12 +54,6 @@ typedef struct
   GLuint gl_shader;
   GString *header, *source;
 
-  /* Age of the user program that was current when the shader was
-     generated. We need to keep track of this because if the user
-     program changes then we may need to redecide whether to generate
-     a shader at all */
-  unsigned int user_program_age;
-
 } CoglPipelineShaderState;
 
 static CoglUserDataKey shader_state_key;
@@ -210,35 +204,28 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
         }
     }
 
-  if (shader_state->gl_shader)
-    {
-      /* If we already have a valid GLSL shader then we don't need to
-       * generate a new one. However if there's a user program and it
-       * has changed since the last link then we do need a new shader.
-       */
-      if (user_program == NULL ||
-          shader_state->user_program_age == user_program->age)
-        return;
-
-      /* We need to recreate the shader so destroy the existing one */
-      GE( ctx, glDeleteShader (shader_state->gl_shader) );
-      shader_state->gl_shader = 0;
-    }
-
-  /* If we make it here then we have a shader_state struct without a gl_shader
-     either because this is the first time we've encountered it or
-     because the user program has changed */
-
   if (user_program)
     {
-      shader_state->user_program_age = user_program->age;
-
       /* If the user program contains a vertex shader then we don't need
          to generate one */
       if (_cogl_program_has_vertex_shader (user_program))
-        return;
+        {
+          if (shader_state->gl_shader)
+            {
+              GE( ctx, glDeleteShader (shader_state->gl_shader) );
+              shader_state->gl_shader = 0;
+            }
+          return;
+        }
     }
 
+  if (shader_state->gl_shader)
+    return;
+
+  /* If we make it here then we have a shader_state struct without a gl_shader
+     either because this is the first time we've encountered it or
+     because the user program has changed */
+
   /* We reuse two grow-only GStrings for code-gen. One string
      contains the uniform and attribute declarations while the
      other contains the main function. We need two strings
@@ -279,17 +266,6 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline,
   if (shader_state->source == NULL)
     return TRUE;
 
-  g_string_append_printf (shader_state->header,
-                          "uniform mat4 cogl_texture_matrix%i;\n"
-                          "attribute vec4 cogl_tex_coord%i_in;\n"
-                          "varying vec4 _cogl_tex_coord%i;\n"
-                          "#define cogl_tex_coord%i_out _cogl_tex_coord%i\n",
-                          layer_index,
-                          layer_index,
-                          layer_index,
-                          layer_index,
-                          layer_index);
-
   /* Transform the texture coordinates by the layer's user matrix.
    *
    * FIXME: this should avoid doing the transform if there is no user
@@ -439,6 +415,7 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
       _cogl_glsl_shader_set_source_with_boilerplate (ctx,
                                                      NULL,
                                                      shader, GL_VERTEX_SHADER,
+                                                     pipeline,
                                                      2, /* count */
                                                      source_strings, lengths);
 



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