summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChun-wei Fan <fanchunwei@src.gnome.org>2011-11-07 11:24:13 +0800
committerChun-wei Fan <fanchunwei@src.gnome.org>2011-11-07 11:24:13 +0800
commitca96da3ffd56aab654eca37835ff7e370767b6cf (patch)
tree5b58bd56fb4dd79a3da21a1dca84d5856883f2af
parent22e5bf9f2a0e3aa77ea74ce51f2d1735705fbc35 (diff)
parent4e59e567d431ba9599f1d6e9814e94a5b49e6265 (diff)
downloadcogl-ca96da3ffd56aab654eca37835ff7e370767b6cf.tar.gz
Merge branch 'cogl-1.8' into msvc-support-1.8
-rw-r--r--cogl/cogl-context.c4
-rw-r--r--cogl/cogl-pipeline-fragend-glsl.c30
-rw-r--r--cogl/cogl-pipeline-opengl.c13
-rw-r--r--cogl/cogl-pipeline-private.h3
-rw-r--r--cogl/cogl-pipeline-progend-glsl.c28
-rw-r--r--cogl/cogl-pipeline-vertend-fixed.c3
-rw-r--r--cogl/cogl-pipeline-vertend-glsl.c27
-rw-r--r--cogl/cogl-program.c1
-rw-r--r--cogl/cogl-shader.c10
9 files changed, 67 insertions, 52 deletions
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index d4bbc204..b44a748e 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -396,8 +396,6 @@ _cogl_context_free (CoglContext *context)
winsys->context_deinit (context);
- _cogl_destroy_texture_units ();
-
if (context->window_buffer)
{
cogl_object_unref (context->window_buffer);
@@ -474,6 +472,8 @@ _cogl_context_free (CoglContext *context)
cogl_pipeline_cache_free (context->pipeline_cache);
+ _cogl_destroy_texture_units ();
+
g_byte_array_free (context->buffer_map_fallback_array, TRUE);
cogl_object_unref (context->display);
diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c
index 48e523bd..6b3904e9 100644
--- a/cogl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/cogl-pipeline-fragend-glsl.c
@@ -101,6 +101,11 @@ typedef struct
program changes then we may need to redecide whether to generate
a shader at all */
unsigned int user_program_age;
+
+ /* The number of tex coord attributes that the shader was generated
+ for. If this changes on GLES2 then we need to regenerate the
+ shader */
+ int n_tex_coord_attribs;
} CoglPipelineShaderState;
static CoglUserDataKey shader_state_key;
@@ -266,9 +271,14 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
{
/* 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)
+ has changed since the last link then we do need a new
+ shader. If the number of tex coord attribs changes on GLES2
+ then we need to regenerate the shader with a different boiler
+ plate */
+ if ((user_program == NULL ||
+ shader_state->user_program_age == user_program->age)
+ && (ctx->driver != COGL_DRIVER_GLES2 ||
+ shader_state->n_tex_coord_attribs == n_tex_coord_attribs))
return TRUE;
/* We need to recreate the shader so destroy the existing one */
@@ -283,6 +293,8 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
if (user_program)
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 &&
@@ -871,8 +883,6 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
GLint lengths[2];
GLint compile_status;
GLuint shader;
- int n_tex_coord_attribs = 0;
- int i, n_layers;
COGL_STATIC_COUNTER (fragend_glsl_compile_counter,
"glsl fragment compile counter",
@@ -919,15 +929,9 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
lengths[1] = shader_state->source->len;
source_strings[1] = shader_state->source->str;
- /* Find the highest texture unit that is sampled to pass as the
- number of texture coordinate attributes */
- n_layers = cogl_pipeline_get_n_layers (pipeline);
- for (i = 0; i < n_layers; i++)
- if (shader_state->unit_state[i].sampled)
- n_tex_coord_attribs = i + 1;
-
_cogl_shader_set_source_with_boilerplate (shader, GL_FRAGMENT_SHADER,
- n_tex_coord_attribs,
+ shader_state
+ ->n_tex_coord_attribs,
2, /* count */
source_strings, lengths);
diff --git a/cogl/cogl-pipeline-opengl.c b/cogl/cogl-pipeline-opengl.c
index caede90d..8220c5e1 100644
--- a/cogl/cogl-pipeline-opengl.c
+++ b/cogl/cogl-pipeline-opengl.c
@@ -1199,6 +1199,16 @@ _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...
*
@@ -1299,7 +1309,8 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
* scratch buffers here... */
if (G_UNLIKELY (!vertend->start (pipeline,
n_layers,
- pipelines_difference)))
+ pipelines_difference,
+ n_tex_coord_attribs)))
continue;
state.vertend = vertend;
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
index 346026e8..2570c524 100644
--- a/cogl/cogl-pipeline-private.h
+++ b/cogl/cogl-pipeline-private.h
@@ -814,7 +814,8 @@ typedef struct _CoglPipelineVertend
{
gboolean (*start) (CoglPipeline *pipeline,
int n_layers,
- unsigned long pipelines_difference);
+ unsigned long pipelines_difference,
+ int n_tex_coord_attribs);
gboolean (*add_layer) (CoglPipeline *pipeline,
CoglPipelineLayer *layer,
unsigned long layers_difference);
diff --git a/cogl/cogl-pipeline-progend-glsl.c b/cogl/cogl-pipeline-progend-glsl.c
index bade8531..d26d3c20 100644
--- a/cogl/cogl-pipeline-progend-glsl.c
+++ b/cogl/cogl-pipeline-progend-glsl.c
@@ -104,7 +104,7 @@ typedef struct
* 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 increases. */
+ * if this changes. */
int n_tex_coord_attribs;
#ifdef HAVE_COGL_GLES2
@@ -618,11 +618,12 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
* need to relink
*
* Also if the number of texture coordinate attributes in use has
- * increased, then delete the program so we can prepend a new
+ * 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))
+ if ((program_state->program && user_program &&
+ user_program->age != program_state->user_program_age) ||
+ (ctx->driver == COGL_DRIVER_GLES2 &&
+ n_tex_coord_attribs != program_state->n_tex_coord_attribs))
{
GE( ctx, glDeleteProgram (program_state->program) );
program_state->program = 0;
@@ -638,23 +639,6 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
/* Attach all of the shader from the user program */
if (user_program)
{
- if (program_state->n_tex_coord_attribs > n_tex_coord_attribs)
- n_tex_coord_attribs = program_state->n_tex_coord_attribs;
-
-#ifdef HAVE_COGL_GLES2
- /* Find the largest count of texture coordinate attributes
- * associated with each of the shaders so we can ensure a consistent
- * _cogl_tex_coord[] array declaration across all of the shaders.*/
- if (ctx->driver == COGL_DRIVER_GLES2 &&
- user_program)
- for (l = user_program->attached_shaders; l; l = l->next)
- {
- CoglShader *shader = l->data;
- n_tex_coord_attribs = MAX (shader->n_tex_coord_attribs,
- n_tex_coord_attribs);
- }
-#endif
-
for (l = user_program->attached_shaders; l; l = l->next)
{
CoglShader *shader = l->data;
diff --git a/cogl/cogl-pipeline-vertend-fixed.c b/cogl/cogl-pipeline-vertend-fixed.c
index a3d3ae4f..a229c70f 100644
--- a/cogl/cogl-pipeline-vertend-fixed.c
+++ b/cogl/cogl-pipeline-vertend-fixed.c
@@ -45,7 +45,8 @@ const CoglPipelineVertend _cogl_pipeline_fixed_vertend;
static gboolean
_cogl_pipeline_vertend_fixed_start (CoglPipeline *pipeline,
int n_layers,
- unsigned long pipelines_difference)
+ unsigned long pipelines_difference,
+ int n_tex_coord_attribs)
{
CoglProgram *user_program;
diff --git a/cogl/cogl-pipeline-vertend-glsl.c b/cogl/cogl-pipeline-vertend-glsl.c
index b8a4535b..9fd5c904 100644
--- a/cogl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/cogl-pipeline-vertend-glsl.c
@@ -55,6 +55,11 @@ typedef struct
program changes then we may need to redecide whether to generate
a shader at all */
unsigned int user_program_age;
+
+ /* The number of tex coord attributes that the shader was generated
+ for. If this changes on GLES2 then we need to regenerate the
+ shader */
+ int n_tex_coord_attribs;
} CoglPipelineShaderState;
static CoglUserDataKey shader_state_key;
@@ -125,7 +130,8 @@ _cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline)
static gboolean
_cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
int n_layers,
- unsigned long pipelines_difference)
+ unsigned long pipelines_difference,
+ int n_tex_coord_attribs)
{
CoglPipelineShaderState *shader_state;
CoglPipeline *template_pipeline = NULL;
@@ -202,9 +208,14 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
{
/* 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)
+ has changed since the last link then we do need a new
+ shader. If the number of tex coord attribs changes on GLES2
+ then we need to regenerate the shader with a different boiler
+ plate */
+ if ((user_program == NULL ||
+ shader_state->user_program_age == user_program->age)
+ && (ctx->driver != COGL_DRIVER_GLES2 ||
+ shader_state->n_tex_coord_attribs == n_tex_coord_attribs))
return TRUE;
/* We need to recreate the shader so destroy the existing one */
@@ -219,6 +230,8 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
if (user_program)
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 &&
@@ -335,7 +348,6 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
GLint lengths[2];
GLint compile_status;
GLuint shader;
- int n_layers;
COGL_STATIC_COUNTER (vertend_glsl_compile_counter,
"glsl vertex compile counter",
@@ -358,10 +370,9 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
lengths[1] = shader_state->source->len;
source_strings[1] = shader_state->source->str;
- n_layers = cogl_pipeline_get_n_layers (pipeline);
-
_cogl_shader_set_source_with_boilerplate (shader, GL_VERTEX_SHADER,
- n_layers,
+ shader_state
+ ->n_tex_coord_attribs,
2, /* count */
source_strings, lengths);
diff --git a/cogl/cogl-program.c b/cogl/cogl-program.c
index 044c284c..adcbd6f9 100644
--- a/cogl/cogl-program.c
+++ b/cogl/cogl-program.c
@@ -240,6 +240,7 @@ cogl_program_uniform_x (CoglHandle handle,
uniform->value.type = type;
uniform->value.size = size;
uniform->value.count = count;
+ uniform->value.transpose = transpose;
uniform->dirty = TRUE;
}
}
diff --git a/cogl/cogl-shader.c b/cogl/cogl-shader.c
index 4d662ab3..cb70976c 100644
--- a/cogl/cogl-shader.c
+++ b/cogl/cogl-shader.c
@@ -342,7 +342,7 @@ _cogl_shader_compile_real (CoglHandle handle,
#ifdef HAVE_COGL_GLES2
&&
(ctx->driver != COGL_DRIVER_GLES2 ||
- shader->n_tex_coord_attribs >= n_tex_coord_attribs)
+ shader->n_tex_coord_attribs == n_tex_coord_attribs)
#endif
)
return;
@@ -424,9 +424,11 @@ cogl_shader_get_info_log (CoglHandle handle)
* 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 (normally less than 4) since that
- * affects the boilerplate.
- */
+ * 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);