diff --git a/cogl/cogl-attribute-private.h b/cogl/cogl-attribute-private.h index a5d7d843e..beb5609b6 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 ad68ff638..edcfb83f0 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 7a79fd335..89b2c744a 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 012c78e92..1ec9762da 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 92bbe2a37..fc3c4f028 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 c762a0b2a..a16c227c8 100644 --- a/cogl/cogl-journal.c +++ b/cogl/cogl-journal.c @@ -465,6 +465,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... */ @@ -475,7 +536,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", @@ -494,49 +556,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; + create_attrib_state.current = 0; + create_attrib_state.flush_state = state; - /* 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); - } + cogl_pipeline_foreach_layer (batch_start->pipeline, + create_attribute_cb, + &create_attrib_state); batch_and_call (batch_start, batch_len, @@ -547,9 +572,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; @@ -646,7 +671,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 f3849a390..595444f62 100644 --- a/cogl/cogl-pipeline-private.h +++ b/cogl/cogl-pipeline-private.h @@ -489,8 +489,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); @@ -511,8 +510,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, @@ -534,8 +532,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); @@ -928,6 +925,10 @@ _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, CoglPipelineInternalLayerCallback callback, 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 6026ddbe3..f18b044fc 100644 --- a/cogl/cogl-pipeline.c +++ b/cogl/cogl-pipeline.c @@ -617,6 +617,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/cogl-shader.c b/cogl/cogl-shader.c index 3c2a0b77c..d28133a5f 100644 --- a/cogl/cogl-shader.c +++ b/cogl/cogl-shader.c @@ -253,7 +253,6 @@ _cogl_shader_compile_real (CoglHandle handle, version, shader->gl_handle, gl_type, - n_tex_coord_attribs, 1, (const char **) &shader->source, diff --git a/cogl/cogl.c b/cogl/cogl.c index 76ac7175a..8cd82a3a5 100644 --- a/cogl/cogl.c +++ b/cogl/cogl.c @@ -431,8 +431,7 @@ cogl_begin_gl (void) pipeline = cogl_get_source (); _cogl_pipeline_flush_gl_state (pipeline, cogl_get_draw_framebuffer (), - FALSE, - cogl_pipeline_get_n_layers (pipeline)); + FALSE); /* Disable any cached vertex arrays */ _cogl_gl_disable_all_attributes (ctx); diff --git a/cogl/driver/gl/cogl-attribute-gl.c b/cogl/driver/gl/cogl-attribute-gl.c index 312f0eaf2..ce90e4a3c 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 c81699428..a9034782e 100644 --- a/cogl/driver/gl/cogl-clip-stack-gl.c +++ b/cogl/driver/gl/cogl-clip-stack-gl.c @@ -286,7 +286,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 253c1ff15..4968e9062 100644 --- a/cogl/driver/gl/cogl-pipeline-fragend-fixed.c +++ b/cogl/driver/gl/cogl-pipeline-fragend-fixed.c @@ -92,8 +92,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 aeb50569c..bc57dd5b1 100644 --- a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c +++ b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c @@ -107,9 +107,6 @@ typedef struct a shader at all */ unsigned int user_program_age; - /* 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; @@ -219,8 +216,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; @@ -294,15 +290,11 @@ _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. Also if the number of tex coord attribs changes - then we need to regenerate the shader with a different boiler - plate */ - if ((user_program == NULL || - shader_state->user_program_age == user_program->age) - && shader_state->n_tex_coord_attribs == n_tex_coord_attribs) + /* 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 */ @@ -315,15 +307,14 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline, encountered it or because the user program has changed */ if (user_program) - shader_state->user_program_age = user_program->age; + { + shader_state->user_program_age = user_program->age; - shader_state->n_tex_coord_attribs = n_tex_coord_attribs; - - /* If the user program contains a fragment shader then we don't need - to generate one */ - if (user_program && - _cogl_program_has_fragment_shader (user_program)) - return; + /* 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; + } /* We reuse two grow-only GStrings for code-gen. One string contains the uniform and attribute declarations while the @@ -440,8 +431,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"); @@ -1026,7 +1017,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); } @@ -1081,8 +1077,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 c9f56fa92..294b611d2 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 f5bb4893e..4108d4d4d 100644 --- a/cogl/driver/gl/cogl-pipeline-opengl.c +++ b/cogl/driver/gl/cogl-pipeline-opengl.c @@ -1147,8 +1147,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; @@ -1203,16 +1202,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... * @@ -1266,8 +1255,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; @@ -1298,8 +1286,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, @@ -1319,7 +1306,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 4f27db2ca..6e9dec7e1 100644 --- a/cogl/driver/gl/cogl-pipeline-progend-glsl.c +++ b/cogl/driver/gl/cogl-pipeline-progend-glsl.c @@ -109,15 +109,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; - unsigned long dirty_builtin_uniforms; GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)]; @@ -244,7 +235,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; @@ -387,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]", state->unit); + "cogl_texture_matrix%i", layer_index); GE_RET( uniform_location, ctx, glGetUniformLocation (state->gl_program, @@ -644,8 +634,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; @@ -714,14 +703,9 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, } /* If the program has changed since the last link then we do - * need to relink - * - * Also 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 ((program_state->program && user_program && - user_program->age != program_state->user_program_age) || - n_tex_coord_attribs != program_state->n_tex_coord_attribs) + * need to relink */ + if (program_state->program && user_program && + user_program->age != program_state->user_program_age) { GE( ctx, glDeleteProgram (program_state->program) ); program_state->program = 0; @@ -741,7 +725,7 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, { CoglShader *shader = l->data; - _cogl_shader_compile_real (shader, n_tex_coord_attribs); + _cogl_shader_compile_real (shader, 4); g_assert (shader->language == COGL_SHADER_LANGUAGE_GLSL); @@ -761,8 +745,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 adb2ab039..487bb28bb 100644 --- a/cogl/driver/gl/cogl-pipeline-vertend-fixed.c +++ b/cogl/driver/gl/cogl-pipeline-vertend-fixed.c @@ -47,8 +47,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 f1b140741..61e393984 100644 --- a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c +++ b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c @@ -60,9 +60,6 @@ typedef struct a shader at all */ unsigned int user_program_age; - /* 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; @@ -152,8 +149,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; @@ -217,13 +213,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 there's a user program and it - has changed since the last link then we do need a new shader. - Also if the number of tex coord attribs changes then we need - to regenerate the shader with a different boiler plate */ - if ((user_program == NULL || - shader_state->user_program_age == user_program->age) - && shader_state->n_tex_coord_attribs == n_tex_coord_attribs) + * 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 */ @@ -236,15 +230,14 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline, because the user program has changed */ if (user_program) - shader_state->user_program_age = user_program->age; + { + shader_state->user_program_age = user_program->age; - shader_state->n_tex_coord_attribs = n_tex_coord_attribs; - - /* If the user program contains a vertex shader then we don't need - to generate one */ - if (user_program && - _cogl_program_has_vertex_shader (user_program)) - return; + /* 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; + } /* We reuse two grow-only GStrings for code-gen. One string contains the uniform and attribute declarations while the @@ -277,17 +270,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 @@ -306,18 +308,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; @@ -332,14 +334,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; } @@ -437,8 +439,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 52f3dccb6..fc2f9cbfc 100644 --- a/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c +++ b/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c @@ -158,8 +158,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;