[Cogl] [PATCH] Remove the varying array for tex_coords

Robert Bragg robert at sixbynine.org
Fri Sep 28 07:57:17 PDT 2012


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

This removes the need to maintain an array of tex_coord varyings and
instead we now just emit a varying per-layer uniquely named using a
layer_number infix like cogl_tex_coord0_out and cogl_tex_coord0_in.

Notable this patch also had to change the journal flushing code to use
pipeline layer numbers to determine the name of texture coordinate
attributes.

We now also break batches by using a deeper comparison of layers so
such that two pipelines with the same number of layers can now cause a
batch break if they use different layer numbers.

This adds an internal _cogl_pipeline_layer_numbers_equal() function that
takes two pipelines and returns TRUE if they have the same number of
layers and all the layer numbers are the same too, otherwise it returns
FALSE.

Where we used to break batches based on changes to the number of layers
we now break according to the status of
_cogl_pipeline_layer_numbers_equal
---
 cogl/cogl-attribute-private.h                   |    2 +-
 cogl/cogl-attribute.c                           |   10 +-
 cogl/cogl-glsl-shader-boilerplate.h             |    2 -
 cogl/cogl-glsl-shader-private.h                 |    1 -
 cogl/cogl-glsl-shader.c                         |   28 ------
 cogl/cogl-journal.c                             |  119 ++++++++++++++---------
 cogl/cogl-pipeline-private.h                    |   13 ++-
 cogl/cogl-pipeline.c                            |   29 ++++++
 cogl/driver/gl/cogl-attribute-gl.c              |   19 ++--
 cogl/driver/gl/cogl-clip-stack-gl.c             |    2 +-
 cogl/driver/gl/cogl-pipeline-fragend-fixed.c    |    3 +-
 cogl/driver/gl/cogl-pipeline-fragend-glsl.c     |   33 ++-----
 cogl/driver/gl/cogl-pipeline-opengl-private.h   |    3 +-
 cogl/driver/gl/cogl-pipeline-opengl.c           |   21 +---
 cogl/driver/gl/cogl-pipeline-progend-glsl.c     |   26 +-----
 cogl/driver/gl/cogl-pipeline-vertend-fixed.c    |    3 +-
 cogl/driver/gl/cogl-pipeline-vertend-glsl.c     |   58 +++++-------
 cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c |    3 +-
 tests/conform/test-just-vertex-shader.c         |    2 +-
 19 files changed, 167 insertions(+), 210 deletions(-)

diff --git a/cogl/cogl-attribute-private.h b/cogl/cogl-attribute-private.h
index b4adaa8..8aeee23 100644
--- a/cogl/cogl-attribute-private.h
+++ b/cogl/cogl-attribute-private.h
@@ -48,7 +48,7 @@ typedef struct _CoglAttributeNameState
   CoglAttributeNameID name_id;
   int name_index;
   CoglBool normalized_default;
-  int texture_unit;
+  int layer_number;
 } CoglAttributeNameState;
 
 struct _CoglAttribute
diff --git a/cogl/cogl-attribute.c b/cogl/cogl-attribute.c
index 6e40f54..8f3fd1e 100644
--- a/cogl/cogl-attribute.c
+++ b/cogl/cogl-attribute.c
@@ -64,12 +64,12 @@ validate_cogl_attribute_name (const char *name,
                               char **real_attribute_name,
                               CoglAttributeNameID *name_id,
                               CoglBool *normalized,
-                              int *texture_unit)
+                              int *layer_number)
 {
   name = name + 5; /* skip "cogl_" */
 
   *normalized = FALSE;
-  *texture_unit = 0;
+  *layer_number = 0;
 
   if (strcmp (name, "position_in") == 0)
     *name_id = COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY;
@@ -86,7 +86,7 @@ validate_cogl_attribute_name (const char *name,
   else if (strncmp (name, "tex_coord", strlen ("tex_coord")) == 0)
     {
       char *endptr;
-      *texture_unit = strtoul (name + 9, &endptr, 10);
+      *layer_number = strtoul (name + 9, &endptr, 10);
       if (strcmp (endptr, "_in") != 0)
 	{
 	  g_warning ("Texture coordinate attributes should either be named "
@@ -126,14 +126,14 @@ _cogl_attribute_register_attribute_name (CoglContext *context,
                                          &name_state->name,
                                          &name_state->name_id,
                                          &name_state->normalized_default,
-                                         &name_state->texture_unit))
+                                         &name_state->layer_number))
         goto error;
     }
   else
     {
       name_state->name_id = COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY;
       name_state->normalized_default = FALSE;
-      name_state->texture_unit = 0;
+      name_state->layer_number = 0;
     }
 
   if (name_state->name == NULL)
diff --git a/cogl/cogl-glsl-shader-boilerplate.h b/cogl/cogl-glsl-shader-boilerplate.h
index 7a79fd3..89b2c74 100644
--- a/cogl/cogl-glsl-shader-boilerplate.h
+++ b/cogl/cogl-glsl-shader-boilerplate.h
@@ -44,7 +44,6 @@
   _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" \
@@ -62,7 +61,6 @@
   "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 012c78e..1ec9762 100644
--- a/cogl/cogl-glsl-shader-private.h
+++ b/cogl/cogl-glsl-shader-private.h
@@ -28,7 +28,6 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
                                                const char *version_string,
                                                GLuint shader_gl_handle,
                                                GLenum shader_gl_type,
-                                               int n_tex_coord_attribs,
                                                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 92bbe2a..fc3c4f0 100644
--- a/cogl/cogl-glsl-shader.c
+++ b/cogl/cogl-glsl-shader.c
@@ -44,7 +44,6 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
                                                const char *version_string,
                                                GLuint shader_gl_handle,
                                                GLenum shader_gl_type,
-                                               int n_tex_coord_attribs,
                                                GLsizei count_in,
                                                const char **strings_in,
                                                const GLint *lengths_in)
@@ -86,33 +85,6 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
       lengths[count++] = strlen (fragment_boilerplate);
     }
 
-  if (n_tex_coord_attribs)
-    {
-      GString *declarations = g_string_new (NULL);
-
-      g_string_append_printf (declarations,
-                              "varying vec4 _cogl_tex_coord[%d];\n",
-                              n_tex_coord_attribs);
-
-      if (shader_gl_type == GL_VERTEX_SHADER)
-        {
-          int i;
-
-          g_string_append_printf (declarations,
-                                  "uniform mat4 cogl_texture_matrix[%d];\n",
-                                  n_tex_coord_attribs);
-
-          for (i = 0; i < n_tex_coord_attribs; i++)
-            g_string_append_printf (declarations,
-                                    "attribute vec4 cogl_tex_coord%d_in;\n",
-                                    i);
-        }
-
-      tex_coord_declarations = g_string_free (declarations, FALSE);
-      strings[count] = tex_coord_declarations;
-      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);
diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c
index 52cab98..a467c33 100644
--- a/cogl/cogl-journal.c
+++ b/cogl/cogl-journal.c
@@ -464,6 +464,67 @@ compare_entry_pipelines (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
     return FALSE;
 }
 
+typedef struct _CreateAttributeState
+{
+  int current;
+  CoglJournalFlushState *flush_state;
+} CreateAttributeState;
+
+static CoglBool
+create_attribute_cb (CoglPipeline *pipeline,
+                     int layer_number,
+                     void *user_data)
+{
+  CreateAttributeState *state = user_data;
+  CoglJournalFlushState *flush_state = state->flush_state;
+  CoglAttribute **attribute_entry =
+    &g_array_index (flush_state->attributes,
+                    CoglAttribute *,
+                    state->current + 2);
+  const char *names[] = {
+      "cogl_tex_coord0_in",
+      "cogl_tex_coord1_in",
+      "cogl_tex_coord2_in",
+      "cogl_tex_coord3_in",
+      "cogl_tex_coord4_in",
+      "cogl_tex_coord5_in",
+      "cogl_tex_coord6_in",
+      "cogl_tex_coord7_in"
+  };
+  char *name;
+
+  /* XXX NB:
+   * Our journal's vertex data is arranged as follows:
+   * 4 vertices per quad:
+   *    2 or 3 floats per position (3 when doing software transforms)
+   *    4 RGBA bytes,
+   *    2 floats per tex coord * n_layers
+   * (though n_layers may be padded; see definition of
+   *  GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details)
+   */
+  name = layer_number < 8 ? (char *)names[layer_number] :
+    g_strdup_printf ("cogl_tex_coord%d_in", layer_number);
+
+  /* XXX: it may be worth having some form of static initializer for
+   * attributes... */
+  *attribute_entry =
+    cogl_attribute_new (flush_state->attribute_buffer,
+                        name,
+                        flush_state->stride,
+                        flush_state->array_offset +
+                        (POS_STRIDE + COLOR_STRIDE) * 4 +
+                        TEX_STRIDE * 4 * state->current,
+                        2,
+                        COGL_ATTRIBUTE_TYPE_FLOAT);
+
+  if (layer_number >= 8)
+    g_free (name);
+
+  state->current++;
+
+  return TRUE;
+}
+
 /* Since the stride may not reflect the number of texture layers in use
  * (due to padding) we deal with texture coordinate offsets separately
  * from vertex and color offsets... */
@@ -474,7 +535,8 @@ _cogl_journal_flush_texcoord_vbo_offsets_and_entries (
                                           void             *data)
 {
   CoglJournalFlushState *state = data;
-  int                    i;
+  CreateAttributeState create_attrib_state;
+  int i;
   COGL_STATIC_TIMER (time_flush_texcoord_pipeline_entries,
                      "flush: vbo+texcoords+pipeline+entries", /* parent */
                      "flush: texcoords+pipeline+entries",
@@ -493,49 +555,12 @@ _cogl_journal_flush_texcoord_vbo_offsets_and_entries (
 
   g_array_set_size (state->attributes, batch_start->n_layers + 2);
 
-  for (i = 0; i < batch_start->n_layers; i++)
-    {
-      CoglAttribute **attribute_entry =
-        &g_array_index (state->attributes, CoglAttribute *, i + 2);
-      const char *names[] = {
-          "cogl_tex_coord0_in",
-          "cogl_tex_coord1_in",
-          "cogl_tex_coord2_in",
-          "cogl_tex_coord3_in",
-          "cogl_tex_coord4_in",
-          "cogl_tex_coord5_in",
-          "cogl_tex_coord6_in",
-          "cogl_tex_coord7_in"
-      };
-      char *name;
-
-      /* XXX NB:
-       * Our journal's vertex data is arranged as follows:
-       * 4 vertices per quad:
-       *    2 or 3 floats per position (3 when doing software transforms)
-       *    4 RGBA bytes,
-       *    2 floats per tex coord * n_layers
-       * (though n_layers may be padded; see definition of
-       *  GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details)
-       */
-      name = i < 8 ? (char *)names[i] :
-        g_strdup_printf ("cogl_tex_coord%d_in", i);
-
-      /* XXX: it may be worth having some form of static initializer for
-       * attributes... */
-      *attribute_entry =
-        cogl_attribute_new (state->attribute_buffer,
-                            name,
-                            state->stride,
-                            state->array_offset +
-                            (POS_STRIDE + COLOR_STRIDE) * 4 +
-                            TEX_STRIDE * 4 * i,
-                            2,
-                            COGL_ATTRIBUTE_TYPE_FLOAT);
-
-      if (i >= 8)
-        g_free (name);
-    }
+  create_attrib_state.current = 0;
+  create_attrib_state.flush_state = state;
+
+  cogl_pipeline_foreach_layer (batch_start->pipeline,
+                               create_attribute_cb,
+                               &create_attrib_state);
 
   batch_and_call (batch_start,
                   batch_len,
@@ -546,9 +571,9 @@ _cogl_journal_flush_texcoord_vbo_offsets_and_entries (
 }
 
 static CoglBool
-compare_entry_n_layers (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
+compare_entry_layer_numbers (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
 {
-  if (entry0->n_layers == entry1->n_layers)
+  if (_cogl_pipeline_layer_numbers_equal (entry0->pipeline, entry1->pipeline))
     return TRUE;
   else
     return FALSE;
@@ -645,7 +670,7 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
 
   batch_and_call (batch_start,
                   batch_len,
-                  compare_entry_n_layers,
+                  compare_entry_layer_numbers,
                   _cogl_journal_flush_texcoord_vbo_offsets_and_entries,
                   data);
 
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
index 9dfd0b1..71e43e0 100644
--- a/cogl/cogl-pipeline-private.h
+++ b/cogl/cogl-pipeline-private.h
@@ -435,8 +435,7 @@ typedef struct _CoglPipelineFragend
 {
   void (*start) (CoglPipeline *pipeline,
                  int n_layers,
-                 unsigned long pipelines_difference,
-                 int n_tex_coord_attribs);
+                 unsigned long pipelines_difference);
   CoglBool (*add_layer) (CoglPipeline *pipeline,
                          CoglPipelineLayer *layer,
                          unsigned long layers_difference);
@@ -457,8 +456,7 @@ typedef struct _CoglPipelineVertend
 {
   void (*start) (CoglPipeline *pipeline,
                  int n_layers,
-                 unsigned long pipelines_difference,
-                 int n_tex_coord_attribs);
+                 unsigned long pipelines_difference);
   CoglBool (*add_layer) (CoglPipeline *pipeline,
                          CoglPipelineLayer *layer,
                          unsigned long layers_difference,
@@ -480,8 +478,7 @@ typedef struct
   int fragend;
   CoglBool (*start) (CoglPipeline *pipeline);
   void (*end) (CoglPipeline *pipeline,
-               unsigned long pipelines_difference,
-               int n_tex_coord_attribs);
+               unsigned long pipelines_difference);
   void (*pipeline_pre_change_notify) (CoglPipeline *pipeline,
                                       CoglPipelineState change,
                                       const CoglColor *new_color);
@@ -862,6 +859,10 @@ _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline,
                                        void *user_data);
 
 CoglBool
+_cogl_pipeline_layer_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 1b38442..ad573eb 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -583,6 +583,35 @@ _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline,
     }
 }
 
+CoglBool
+_cogl_pipeline_layer_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];
+
+      if (layer0->index != layer1->index)
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
 typedef struct
 {
   int i;
diff --git a/cogl/driver/gl/cogl-attribute-gl.c b/cogl/driver/gl/cogl-attribute-gl.c
index 0c21d12..34a4499 100644
--- a/cogl/driver/gl/cogl-attribute-gl.c
+++ b/cogl/driver/gl/cogl-attribute-gl.c
@@ -218,7 +218,6 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
   int i;
   CoglBool skip_gl_color = FALSE;
   CoglPipeline *copy = NULL;
-  int n_tex_coord_attribs = 0;
 
   /* Iterate the attributes to work out whether blending needs to be
      enabled and how many texture coords there are. We need to do this
@@ -239,10 +238,6 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
         skip_gl_color = TRUE;
         break;
 
-      case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
-        n_tex_coord_attribs++;
-        break;
-
       default:
         break;
       }
@@ -293,8 +288,7 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
 
   _cogl_pipeline_flush_gl_state (pipeline,
                                  framebuffer,
-                                 skip_gl_color,
-                                 n_tex_coord_attribs);
+                                 skip_gl_color);
 
   _cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp);
   _cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp);
@@ -353,11 +347,14 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
           else
 #endif
             {
+              int layer_number = attribute->name_state->layer_number;
+              CoglPipelineLayer *layer =
+                _cogl_pipeline_get_layer (pipeline, layer_number);
+              int unit = _cogl_pipeline_layer_get_unit_index (layer);
+
               _cogl_bitmask_set (&ctx->enable_texcoord_attributes_tmp,
-                                 attribute->name_state->texture_unit, TRUE);
-              GE (ctx,
-                  glClientActiveTexture (GL_TEXTURE0 +
-                                         attribute->name_state->texture_unit));
+                                 unit, TRUE);
+              GE (ctx, glClientActiveTexture (GL_TEXTURE0 + unit));
               GE (ctx, glTexCoordPointer (attribute->n_components,
                                           attribute->type,
                                           attribute->stride,
diff --git a/cogl/driver/gl/cogl-clip-stack-gl.c b/cogl/driver/gl/cogl-clip-stack-gl.c
index 2547fc9..933b943 100644
--- a/cogl/driver/gl/cogl-clip-stack-gl.c
+++ b/cogl/driver/gl/cogl-clip-stack-gl.c
@@ -285,7 +285,7 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
                                               projection_stack->last_entry);
   _cogl_context_set_current_modelview_entry (ctx, modelview_entry);
 
-  _cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, framebuffer, FALSE, 0);
+  _cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, framebuffer, FALSE);
 
   GE( ctx, glEnable (GL_STENCIL_TEST) );
 
diff --git a/cogl/driver/gl/cogl-pipeline-fragend-fixed.c b/cogl/driver/gl/cogl-pipeline-fragend-fixed.c
index 8e6fa42..7f58eec 100644
--- a/cogl/driver/gl/cogl-pipeline-fragend-fixed.c
+++ b/cogl/driver/gl/cogl-pipeline-fragend-fixed.c
@@ -91,8 +91,7 @@ get_max_texture_units (void)
 static void
 _cogl_pipeline_fragend_fixed_start (CoglPipeline *pipeline,
                                     int n_layers,
-                                    unsigned long pipelines_difference,
-                                    int n_tex_coord_attribs)
+                                    unsigned long pipelines_difference)
 {
   _cogl_use_fragment_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED);
 }
diff --git a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
index 0d0395e..6d743b1 100644
--- a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
@@ -98,10 +98,6 @@ typedef struct
      layer we'll remove it from the list so we don't generate it
      again */
   LayerDataList layers;
-
-  /* The number of tex coord attributes that the shader was generated
-   * for. If this changes then we need to regenerate the shader */
-  int n_tex_coord_attribs;
 } CoglPipelineShaderState;
 
 static CoglUserDataKey shader_state_key;
@@ -211,8 +207,7 @@ has_replace_hook (CoglPipelineLayer *layer,
 static void
 _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
                                    int n_layers,
-                                   unsigned long pipelines_difference,
-                                   int n_tex_coord_attribs)
+                                   unsigned long pipelines_difference)
 {
   CoglPipelineShaderState *shader_state;
   CoglPipeline *authority;
@@ -284,25 +279,12 @@ _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 the number of tex coord
-       * attribs changes then we need to regenerate the shader with a
-       * different boiler plate */
-      if (shader_state->n_tex_coord_attribs == n_tex_coord_attribs)
-        return;
-
-      /* We need to recreate the shader so destroy the existing one */
-      GE( ctx, glDeleteShader (shader_state->gl_shader) );
-      shader_state->gl_shader = 0;
-    }
+    return;
 
   /* If we make it here then we have a glsl_shader_state struct
      without a gl_shader because this is the first time we've
      encountered it. */
 
-  shader_state->n_tex_coord_attribs = n_tex_coord_attribs;
-
   /* 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
@@ -418,8 +400,8 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
     }
   else
     g_string_append_printf (shader_state->source,
-                            "cogl_tex_coord_in[%d]",
-                            unit_index);
+                            "cogl_tex_coord%i_in",
+                            layer->index);
 
   g_string_append (shader_state->source, ");\n");
 
@@ -1004,7 +986,12 @@ _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);
             }
@@ -1060,8 +1047,6 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
       _cogl_glsl_shader_set_source_with_boilerplate (ctx,
                                                      version_string,
                                                      shader, GL_FRAGMENT_SHADER,
-                                                     shader_state
-                                                     ->n_tex_coord_attribs,
                                                      2, /* count */
                                                      source_strings, lengths);
 
diff --git a/cogl/driver/gl/cogl-pipeline-opengl-private.h b/cogl/driver/gl/cogl-pipeline-opengl-private.h
index c9f56fa..294b611 100644
--- a/cogl/driver/gl/cogl-pipeline-opengl-private.h
+++ b/cogl/driver/gl/cogl-pipeline-opengl-private.h
@@ -144,8 +144,7 @@ _cogl_delete_gl_texture (GLuint gl_texture);
 void
 _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
                                CoglFramebuffer *framebuffer,
-                               CoglBool skip_gl_state,
-                               int n_tex_coord_attribs);
+                               CoglBool skip_gl_state);
 
 #endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
 
diff --git a/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/driver/gl/cogl-pipeline-opengl.c
index 9af4996..83dc197 100644
--- a/cogl/driver/gl/cogl-pipeline-opengl.c
+++ b/cogl/driver/gl/cogl-pipeline-opengl.c
@@ -1127,8 +1127,7 @@ fragend_add_layer_cb (CoglPipelineLayer *layer,
 void
 _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
                                CoglFramebuffer *framebuffer,
-                               CoglBool skip_gl_color,
-                               int n_tex_coord_attribs)
+                               CoglBool skip_gl_color)
 {
   unsigned long pipelines_difference;
   int n_layers;
@@ -1183,16 +1182,6 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
   else
     layer_differences = NULL;
 
-  /* Make sure we generate the texture coordinate array to be at least
-     the number of layers. This is important because the vertend will
-     try to pass along the corresponding varying for each layer
-     regardless of whether the fragment shader is actually using
-     it. Also it is possible that the application is assuming that if
-     the attribute isn't passed then it will default to 0,0. This is
-     what test-cogl-primitive does */
-  if (n_layers > n_tex_coord_attribs)
-    n_tex_coord_attribs = n_layers;
-
   /* First flush everything that's the same regardless of which
    * pipeline backend is being used...
    *
@@ -1246,8 +1235,7 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
 
       vertend->start (pipeline,
                       n_layers,
-                      pipelines_difference,
-                      n_tex_coord_attribs);
+                      pipelines_difference);
 
       state.framebuffer = framebuffer;
       state.vertend = vertend;
@@ -1278,8 +1266,7 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
 
       fragend->start (pipeline,
                       n_layers,
-                      pipelines_difference,
-                      n_tex_coord_attribs);
+                      pipelines_difference);
 
       _cogl_pipeline_foreach_layer_internal (pipeline,
                                              fragend_add_layer_cb,
@@ -1299,7 +1286,7 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
         continue;
 
       if (progend->end)
-        progend->end (pipeline, pipelines_difference, n_tex_coord_attribs);
+        progend->end (pipeline, pipelines_difference);
       break;
     }
 
diff --git a/cogl/driver/gl/cogl-pipeline-progend-glsl.c b/cogl/driver/gl/cogl-pipeline-progend-glsl.c
index ff90d3c..a7e0138 100644
--- a/cogl/driver/gl/cogl-pipeline-progend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-progend-glsl.c
@@ -101,15 +101,6 @@ typedef struct
 
   GLuint program;
 
-  /* To allow writing shaders that are portable between GLES 2 and
-   * OpenGL Cogl prepends a number of boilerplate #defines and
-   * declarations to user shaders. One of those declarations is an
-   * array of texture coordinate varyings, but to know how to emit the
-   * declaration we need to know how many texture coordinate
-   * attributes are in use.  The boilerplate also needs to be changed
-   * if this changes. */
-  int n_tex_coord_attribs;
-
 #ifdef HAVE_COGL_GLES2
   unsigned long dirty_builtin_uniforms;
   GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)];
@@ -238,7 +229,6 @@ program_state_new (int n_layers)
   program_state = g_slice_new (CoglPipelineProgramState);
   program_state->ref_count = 1;
   program_state->program = 0;
-  program_state->n_tex_coord_attribs = 0;
   program_state->unit_state = g_new (UnitState, n_layers);
   program_state->uniform_locations = NULL;
   program_state->attribute_locations = NULL;
@@ -381,7 +371,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]", state->unit);
+                          "cogl_texture_matrix%i", state->unit);
 
   GE_RET( uniform_location,
           ctx, glGetUniformLocation (state->gl_program,
@@ -632,8 +622,7 @@ _cogl_pipeline_progend_glsl_start (CoglPipeline *pipeline)
 
 static void
 _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
-                                 unsigned long pipelines_difference,
-                                 int n_tex_coord_attribs)
+                                 unsigned long pipelines_difference)
 {
   CoglPipelineProgramState *program_state;
   GLuint gl_program;
@@ -698,15 +687,6 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
         }
     }
 
-  /* If the number of texture coordinate attributes in use has
-   * changed, then delete the program so we can prepend a new
-   * _cogl_tex_coord[] varying array declaration. */
-  if (n_tex_coord_attribs != program_state->n_tex_coord_attribs)
-    {
-      GE( ctx, glDeleteProgram (program_state->program) );
-      program_state->program = 0;
-    }
-
   if (program_state->program == 0)
     {
       GLuint backend_shader;
@@ -722,8 +702,6 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
       link_program (program_state->program);
 
       program_changed = TRUE;
-
-      program_state->n_tex_coord_attribs = n_tex_coord_attribs;
     }
 
   gl_program = program_state->program;
diff --git a/cogl/driver/gl/cogl-pipeline-vertend-fixed.c b/cogl/driver/gl/cogl-pipeline-vertend-fixed.c
index 0a0cca8..606cb41 100644
--- a/cogl/driver/gl/cogl-pipeline-vertend-fixed.c
+++ b/cogl/driver/gl/cogl-pipeline-vertend-fixed.c
@@ -46,8 +46,7 @@ const CoglPipelineVertend _cogl_pipeline_fixed_vertend;
 static void
 _cogl_pipeline_vertend_fixed_start (CoglPipeline *pipeline,
                                     int n_layers,
-                                    unsigned long pipelines_difference,
-                                    int n_tex_coord_attribs)
+                                    unsigned long pipelines_difference)
 {
   _cogl_use_vertex_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED);
 }
diff --git a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
index 84644c6..e702e22 100644
--- a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
@@ -53,9 +53,6 @@ typedef struct
   GLuint gl_shader;
   GString *header, *source;
 
-  /* The number of tex coord attributes that the shader was generated
-   * for. If this changes then we need to regenerate the shader */
-  int n_tex_coord_attribs;
 } CoglPipelineShaderState;
 
 static CoglUserDataKey shader_state_key;
@@ -145,8 +142,7 @@ get_layer_vertex_snippets (CoglPipelineLayer *layer)
 static void
 _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
                                    int n_layers,
-                                   unsigned long pipelines_difference,
-                                   int n_tex_coord_attribs)
+                                   unsigned long pipelines_difference)
 {
   CoglPipelineShaderState *shader_state;
   CoglPipeline *template_pipeline = NULL;
@@ -207,24 +203,11 @@ _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 the number of tex coord
-       * attribs changes then we need to regenerate the shader with a
-       * different boiler plate */
-      if (shader_state->n_tex_coord_attribs == n_tex_coord_attribs)
-        return;
-
-      /* We need to recreate the shader so destroy the existing one */
-      GE( ctx, glDeleteShader (shader_state->gl_shader) );
-      shader_state->gl_shader = 0;
-    }
+    return;
 
   /* If we make it here then we have a shader_state struct without a gl_shader
      because this is the first time we've encountered it */
 
-  shader_state->n_tex_coord_attribs = n_tex_coord_attribs;
-
   /* 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
@@ -255,17 +238,26 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline,
 {
   CoglPipelineShaderState *shader_state;
   CoglPipelineSnippetData snippet_data;
-  int unit_index;
+  int layer_index = layer->index;
 
   _COGL_GET_CONTEXT (ctx, FALSE);
 
   shader_state = get_shader_state (pipeline);
 
-  unit_index = _cogl_pipeline_layer_get_unit_index (layer);
-
   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
@@ -284,18 +276,18 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline,
                           "{\n"
                           "  return matrix * tex_coord;\n"
                           "}\n",
-                          unit_index);
+                          layer_index);
 
   /* Wrap the layer code in any snippets that have been hooked */
   memset (&snippet_data, 0, sizeof (snippet_data));
   snippet_data.snippets = get_layer_vertex_snippets (layer);
   snippet_data.hook = COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM;
   snippet_data.chain_function = g_strdup_printf ("cogl_real_transform_layer%i",
-                                                 unit_index);
+                                                 layer_index);
   snippet_data.final_name = g_strdup_printf ("cogl_transform_layer%i",
-                                             unit_index);
+                                             layer_index);
   snippet_data.function_prefix = g_strdup_printf ("cogl_transform_layer%i",
-                                                  unit_index);
+                                                  layer_index);
   snippet_data.return_type = "vec4";
   snippet_data.return_variable = "cogl_tex_coord";
   snippet_data.return_variable_is_argument = TRUE;
@@ -310,14 +302,14 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline,
   g_free ((char *) snippet_data.function_prefix);
 
   g_string_append_printf (shader_state->source,
-                          "  cogl_tex_coord_out[%i] = "
-                          "cogl_transform_layer%i (cogl_texture_matrix[%i],\n"
+                          "  cogl_tex_coord%i_out = "
+                          "cogl_transform_layer%i (cogl_texture_matrix%i,\n"
                           "                           "
                           "                        cogl_tex_coord%i_in);\n",
-                          unit_index,
-                          unit_index,
-                          unit_index,
-                          unit_index);
+                          layer_index,
+                          layer_index,
+                          layer_index,
+                          layer_index);
 
   return TRUE;
 }
@@ -415,8 +407,6 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
       _cogl_glsl_shader_set_source_with_boilerplate (ctx,
                                                      NULL,
                                                      shader, GL_VERTEX_SHADER,
-                                                     shader_state
-                                                     ->n_tex_coord_attribs,
                                                      2, /* count */
                                                      source_strings, lengths);
 
diff --git a/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c b/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c
index 4ca8d49..66e23cd 100644
--- a/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c
+++ b/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c
@@ -152,8 +152,7 @@ dirty_shader_state (CoglPipeline *pipeline)
 static void
 _cogl_pipeline_fragend_arbfp_start (CoglPipeline *pipeline,
                                     int n_layers,
-                                    unsigned long pipelines_difference,
-                                    int n_tex_coord_attribs)
+                                    unsigned long pipelines_difference)
 {
   CoglPipelineShaderState *shader_state;
   CoglPipeline *authority;
diff --git a/tests/conform/test-just-vertex-shader.c b/tests/conform/test-just-vertex-shader.c
index 090bf27..a87b4cf 100644
--- a/tests/conform/test-just-vertex-shader.c
+++ b/tests/conform/test-just-vertex-shader.c
@@ -60,7 +60,7 @@ paint (TestState *state)
                             "cogl_modelview_projection_matrix * "
                             "cogl_position_in;\n"
                             "  cogl_color_out = cogl_color_in;\n"
-                            "  cogl_tex_coord_out[0] = cogl_tex_coord_in;\n");
+                            "  cogl_tex_coord0_out = cogl_tex_coord_in;\n");
 
   /* Draw something without the snippet */
   cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, 50, 50);
-- 
1.7.7.6



More information about the Cogl mailing list