mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
Unify a lot of gles2 vs gl glsl code
Since we used to support hybrid fixed-function + glsl pipelines when running with OpenGL there were numerous differences in how we handled codegen and uniform updates between GLES2 and full OpenGL. Now that we only support end-to-end glsl pipelines this patch can largely unify how we handle GLES2 and OpenGL. Most notably we now never use the builtin attribute names. This should also make it easy for us to support creating strict OpenGL 3.1 contexts where the builtin names have been removed. Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit 2701b93f159bf2d3387cedf2d06fe921ad5641f3)
This commit is contained in:
parent
62b472f4f5
commit
01937201e4
@ -27,40 +27,42 @@
|
|||||||
#ifndef __COGL_SHADER_BOILERPLATE_H
|
#ifndef __COGL_SHADER_BOILERPLATE_H
|
||||||
#define __COGL_SHADER_BOILERPLATE_H
|
#define __COGL_SHADER_BOILERPLATE_H
|
||||||
|
|
||||||
|
#define _COGL_COMMON_SHADER_BOILERPLATE \
|
||||||
#define _COGL_COMMON_SHADER_BOILERPLATE_GL \
|
|
||||||
"#define COGL_VERSION 100\n" \
|
"#define COGL_VERSION 100\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
"#define cogl_modelview_matrix gl_ModelViewMatrix\n" \
|
"uniform mat4 cogl_modelview_matrix;\n" \
|
||||||
"#define cogl_modelview_projection_matrix gl_ModelViewProjectionMatrix\n" \
|
"uniform mat4 cogl_modelview_projection_matrix;\n" \
|
||||||
"#define cogl_projection_matrix gl_ProjectionMatrix\n" \
|
"uniform mat4 cogl_projection_matrix;\n" \
|
||||||
"#define cogl_texture_matrix gl_TextureMatrix\n" \
|
"uniform float cogl_point_size_in;\n"
|
||||||
"\n"
|
|
||||||
|
|
||||||
#define _COGL_VERTEX_SHADER_BOILERPLATE_GL \
|
/* This declares all of the variables that we might need. This is
|
||||||
_COGL_COMMON_SHADER_BOILERPLATE_GL \
|
* working on the assumption that the compiler will optimise them out
|
||||||
"#define cogl_position_in gl_Vertex\n" \
|
* if they are not actually used. The GLSL spec at least implies that
|
||||||
"#define cogl_color_in gl_Color\n" \
|
* this will happen for varyings but it doesn't explicitly so for
|
||||||
"#define cogl_tex_coord_in gl_MultiTexCoord0\n" \
|
* attributes */
|
||||||
"#define cogl_tex_coord0_in gl_MultiTexCoord0\n" \
|
#define _COGL_VERTEX_SHADER_BOILERPLATE \
|
||||||
"#define cogl_tex_coord1_in gl_MultiTexCoord1\n" \
|
_COGL_COMMON_SHADER_BOILERPLATE \
|
||||||
"#define cogl_tex_coord2_in gl_MultiTexCoord2\n" \
|
"#define cogl_color_out _cogl_color\n" \
|
||||||
"#define cogl_tex_coord3_in gl_MultiTexCoord3\n" \
|
"varying vec4 _cogl_color;\n" \
|
||||||
"#define cogl_tex_coord4_in gl_MultiTexCoord4\n" \
|
"#define cogl_tex_coord_out _cogl_tex_coord\n" \
|
||||||
"#define cogl_tex_coord5_in gl_MultiTexCoord5\n" \
|
|
||||||
"#define cogl_tex_coord6_in gl_MultiTexCoord6\n" \
|
|
||||||
"#define cogl_tex_coord7_in gl_MultiTexCoord7\n" \
|
|
||||||
"#define cogl_normal_in gl_Normal\n" \
|
|
||||||
"\n" \
|
|
||||||
"#define cogl_position_out gl_Position\n" \
|
"#define cogl_position_out gl_Position\n" \
|
||||||
"#define cogl_point_size_out gl_PointSize\n" \
|
"#define cogl_point_size_out gl_PointSize\n" \
|
||||||
"#define cogl_color_out gl_FrontColor\n" \
|
"\n" \
|
||||||
"#define cogl_tex_coord_out gl_TexCoord\n"
|
"attribute vec4 cogl_color_in;\n" \
|
||||||
|
"attribute vec4 cogl_position_in;\n" \
|
||||||
|
"#define cogl_tex_coord_in cogl_tex_coord0_in;\n" \
|
||||||
|
"attribute vec3 cogl_normal_in;\n"
|
||||||
|
|
||||||
#define _COGL_FRAGMENT_SHADER_BOILERPLATE_GL \
|
#define _COGL_FRAGMENT_SHADER_BOILERPLATE \
|
||||||
_COGL_COMMON_SHADER_BOILERPLATE_GL \
|
"#if __VERSION__ == 100\n" \
|
||||||
"#define cogl_color_in gl_Color\n" \
|
"precision highp float;\n" \
|
||||||
"#define cogl_tex_coord_in gl_TexCoord\n" \
|
"#endif\n" \
|
||||||
|
_COGL_COMMON_SHADER_BOILERPLATE \
|
||||||
|
"\n" \
|
||||||
|
"varying vec4 _cogl_color;\n" \
|
||||||
|
"\n" \
|
||||||
|
"#define cogl_color_in _cogl_color\n" \
|
||||||
|
"#define cogl_tex_coord_in _cogl_tex_coord\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
"#define cogl_color_out gl_FragColor\n" \
|
"#define cogl_color_out gl_FragColor\n" \
|
||||||
"#define cogl_depth_out gl_FragDepth\n" \
|
"#define cogl_depth_out gl_FragDepth\n" \
|
||||||
@ -73,47 +75,5 @@
|
|||||||
"#define coglFragCoord gl_FragCoord\n"
|
"#define coglFragCoord gl_FragCoord\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _COGL_COMMON_SHADER_BOILERPLATE_GLES2 \
|
|
||||||
"#define COGL_VERSION 100\n" \
|
|
||||||
"\n" \
|
|
||||||
"uniform mat4 cogl_modelview_matrix;\n" \
|
|
||||||
"uniform mat4 cogl_modelview_projection_matrix;\n" \
|
|
||||||
"uniform mat4 cogl_projection_matrix;\n" \
|
|
||||||
"uniform float cogl_point_size_in;\n"
|
|
||||||
|
|
||||||
/* This declares all of the variables that we might need. This is
|
|
||||||
working on the assumption that the compiler will optimise them out
|
|
||||||
if they are not actually used. The GLSL spec for GLES at least
|
|
||||||
implies that this will happen for varyings but it doesn't
|
|
||||||
explicitly so for attributes */
|
|
||||||
#define _COGL_VERTEX_SHADER_BOILERPLATE_GLES2 \
|
|
||||||
_COGL_COMMON_SHADER_BOILERPLATE_GLES2 \
|
|
||||||
"#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" \
|
|
||||||
"attribute vec4 cogl_color_in;\n" \
|
|
||||||
"attribute vec4 cogl_position_in;\n" \
|
|
||||||
"#define cogl_tex_coord_in cogl_tex_coord0_in;\n" \
|
|
||||||
"attribute vec3 cogl_normal_in;\n"
|
|
||||||
|
|
||||||
#define _COGL_FRAGMENT_SHADER_BOILERPLATE_GLES2 \
|
|
||||||
"#if __VERSION__ == 100\n" \
|
|
||||||
"precision highp float;\n" \
|
|
||||||
"#endif\n" \
|
|
||||||
_COGL_COMMON_SHADER_BOILERPLATE_GLES2 \
|
|
||||||
"\n" \
|
|
||||||
"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" \
|
|
||||||
"\n" \
|
|
||||||
"#define cogl_front_facing gl_FrontFacing\n"
|
|
||||||
|
|
||||||
#endif /* __COGL_SHADER_BOILERPLATE_H */
|
#endif /* __COGL_SHADER_BOILERPLATE_H */
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
void
|
void
|
||||||
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||||
|
const char *version_string,
|
||||||
GLuint shader_gl_handle,
|
GLuint shader_gl_handle,
|
||||||
GLenum shader_gl_type,
|
GLenum shader_gl_type,
|
||||||
int n_tex_coord_attribs,
|
int n_tex_coord_attribs,
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
void
|
void
|
||||||
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||||
|
const char *version_string,
|
||||||
GLuint shader_gl_handle,
|
GLuint shader_gl_handle,
|
||||||
GLenum shader_gl_type,
|
GLenum shader_gl_type,
|
||||||
int n_tex_coord_attribs,
|
int n_tex_coord_attribs,
|
||||||
@ -51,20 +52,18 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
|||||||
const char *vertex_boilerplate;
|
const char *vertex_boilerplate;
|
||||||
const char *fragment_boilerplate;
|
const char *fragment_boilerplate;
|
||||||
|
|
||||||
const char **strings = g_alloca (sizeof (char *) * (count_in + 3));
|
const char **strings = g_alloca (sizeof (char *) * (count_in + 4));
|
||||||
GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 3));
|
GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4));
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char *tex_coord_declarations = NULL;
|
char *tex_coord_declarations = NULL;
|
||||||
|
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE;
|
||||||
|
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE;
|
||||||
|
|
||||||
|
if (version_string)
|
||||||
{
|
{
|
||||||
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE_GLES2;
|
strings[count] = version_string;
|
||||||
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE_GLES2;
|
lengths[count++] = -1;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE_GL;
|
|
||||||
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE_GL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2 &&
|
if (ctx->driver == COGL_DRIVER_GLES2 &&
|
||||||
@ -87,8 +86,7 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
|||||||
lengths[count++] = strlen (fragment_boilerplate);
|
lengths[count++] = strlen (fragment_boilerplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2 &&
|
if (n_tex_coord_attribs)
|
||||||
n_tex_coord_attribs)
|
|
||||||
{
|
{
|
||||||
GString *declarations = g_string_new (NULL);
|
GString *declarations = g_string_new (NULL);
|
||||||
|
|
||||||
|
@ -2877,7 +2877,8 @@ _cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context)
|
|||||||
COGL_PIPELINE_LAYER_STATE_UNIT |
|
COGL_PIPELINE_LAYER_STATE_UNIT |
|
||||||
COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS);
|
COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS);
|
||||||
|
|
||||||
if (context->driver == COGL_DRIVER_GLES2)
|
if (context->driver == COGL_DRIVER_GL ||
|
||||||
|
context->driver == COGL_DRIVER_GLES2)
|
||||||
state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
|
state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
@ -90,9 +90,7 @@ cogl_create_shader (CoglShaderType type)
|
|||||||
shader = g_slice_new (CoglShader);
|
shader = g_slice_new (CoglShader);
|
||||||
shader->language = COGL_SHADER_LANGUAGE_GLSL;
|
shader->language = COGL_SHADER_LANGUAGE_GLSL;
|
||||||
shader->gl_handle = 0;
|
shader->gl_handle = 0;
|
||||||
#ifdef HAVE_COGL_GLES2
|
|
||||||
shader->n_tex_coord_attribs = 0;
|
shader->n_tex_coord_attribs = 0;
|
||||||
#endif
|
|
||||||
shader->type = type;
|
shader->type = type;
|
||||||
|
|
||||||
return _cogl_shader_handle_new (shader);
|
return _cogl_shader_handle_new (shader);
|
||||||
@ -153,19 +151,14 @@ cogl_shader_source (CoglHandle handle,
|
|||||||
void
|
void
|
||||||
cogl_shader_compile (CoglHandle handle)
|
cogl_shader_compile (CoglHandle handle)
|
||||||
{
|
{
|
||||||
CoglShader *shader = handle;
|
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
if (!cogl_is_shader (handle))
|
if (!cogl_is_shader (handle))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ctx->driver == COGL_DRIVER_GL)
|
/* XXX: We don't actually compile anything until the shader gets
|
||||||
_cogl_shader_compile_real (shader, 0 /* ignored */);
|
* used so we have an opportunity to add some boilerplate to the
|
||||||
|
* shader.
|
||||||
/* XXX: For GLES2 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
|
* 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
|
* given that we are having to lie to the user. It was a mistake to
|
||||||
@ -178,6 +171,7 @@ _cogl_shader_compile_real (CoglHandle handle,
|
|||||||
int n_tex_coord_attribs)
|
int n_tex_coord_attribs)
|
||||||
{
|
{
|
||||||
CoglShader *shader = handle;
|
CoglShader *shader = handle;
|
||||||
|
const char *version;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -223,13 +217,8 @@ _cogl_shader_compile_real (CoglHandle handle,
|
|||||||
{
|
{
|
||||||
GLenum gl_type;
|
GLenum gl_type;
|
||||||
|
|
||||||
if (shader->gl_handle
|
if (shader->gl_handle &&
|
||||||
#ifdef HAVE_COGL_GLES2
|
shader->n_tex_coord_attribs == n_tex_coord_attribs)
|
||||||
&&
|
|
||||||
(ctx->driver != COGL_DRIVER_GLES2 ||
|
|
||||||
shader->n_tex_coord_attribs == n_tex_coord_attribs)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (shader->gl_handle)
|
if (shader->gl_handle)
|
||||||
@ -250,7 +239,17 @@ _cogl_shader_compile_real (CoglHandle handle,
|
|||||||
|
|
||||||
shader->gl_handle = ctx->glCreateShader (gl_type);
|
shader->gl_handle = ctx->glCreateShader (gl_type);
|
||||||
|
|
||||||
|
if (ctx->driver == COGL_DRIVER_GL &&
|
||||||
|
ctx->glsl_major == 1 &&
|
||||||
|
ctx->glsl_minor >= 2)
|
||||||
|
{
|
||||||
|
version = "#version 120\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
version = NULL;
|
||||||
|
|
||||||
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
||||||
|
version,
|
||||||
shader->gl_handle,
|
shader->gl_handle,
|
||||||
gl_type,
|
gl_type,
|
||||||
n_tex_coord_attribs,
|
n_tex_coord_attribs,
|
||||||
@ -261,9 +260,7 @@ _cogl_shader_compile_real (CoglHandle handle,
|
|||||||
|
|
||||||
GE (ctx, glCompileShader (shader->gl_handle));
|
GE (ctx, glCompileShader (shader->gl_handle));
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
|
||||||
shader->n_tex_coord_attribs = n_tex_coord_attribs;
|
shader->n_tex_coord_attribs = n_tex_coord_attribs;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COGL_GL_DEBUG
|
#ifdef COGL_GL_DEBUG
|
||||||
if (!cogl_shader_is_compiled (handle))
|
if (!cogl_shader_is_compiled (handle))
|
||||||
|
@ -318,8 +318,8 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
switch (attribute->name_state->name_id)
|
switch (attribute->name_state->name_id)
|
||||||
{
|
{
|
||||||
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
||||||
#ifdef HAVE_COGL_GLES2
|
#ifdef COGL_PIPELINE_PROGEND_GLSL
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
|
||||||
setup_generic_attribute (ctx, pipeline, attribute, base);
|
setup_generic_attribute (ctx, pipeline, attribute, base);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -333,8 +333,8 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
|
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
|
||||||
#ifdef HAVE_COGL_GLES2
|
#ifdef COGL_PIPELINE_PROGEND_GLSL
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
|
||||||
setup_generic_attribute (ctx, pipeline, attribute, base);
|
setup_generic_attribute (ctx, pipeline, attribute, base);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -347,8 +347,8 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
|
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
|
||||||
#ifdef HAVE_COGL_GLES2
|
#ifdef COGL_PIPELINE_PROGEND_GLSL
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
|
||||||
setup_generic_attribute (ctx, pipeline, attribute, base);
|
setup_generic_attribute (ctx, pipeline, attribute, base);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -365,8 +365,8 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
|
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
|
||||||
#ifdef HAVE_COGL_GLES2
|
#ifdef COGL_PIPELINE_PROGEND_GLSL
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
|
||||||
setup_generic_attribute (ctx, pipeline, attribute, base);
|
setup_generic_attribute (ctx, pipeline, attribute, base);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -381,7 +381,7 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
break;
|
break;
|
||||||
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
|
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
|
||||||
#ifdef COGL_PIPELINE_PROGEND_GLSL
|
#ifdef COGL_PIPELINE_PROGEND_GLSL
|
||||||
if (ctx->driver != COGL_DRIVER_GLES1)
|
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
|
||||||
setup_generic_attribute (ctx, pipeline, attribute, base);
|
setup_generic_attribute (ctx, pipeline, attribute, base);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
@ -93,6 +93,8 @@ typedef struct
|
|||||||
GString *header, *source;
|
GString *header, *source;
|
||||||
UnitState *unit_state;
|
UnitState *unit_state;
|
||||||
|
|
||||||
|
CoglBool ref_point_coord;
|
||||||
|
|
||||||
/* List of layers that we haven't generated code for yet. These are
|
/* List of layers that we haven't generated code for yet. These are
|
||||||
in reverse order. As soon as we're about to generate code for
|
in reverse order. As soon as we're about to generate code for
|
||||||
layer we'll remove it from the list so we don't generate it
|
layer we'll remove it from the list so we don't generate it
|
||||||
@ -106,8 +108,7 @@ typedef struct
|
|||||||
unsigned int user_program_age;
|
unsigned int user_program_age;
|
||||||
|
|
||||||
/* The number of tex coord attributes that the shader was generated
|
/* The number of tex coord attributes that the shader was generated
|
||||||
for. If this changes on GLES2 then we need to regenerate the
|
* for. If this changes then we need to regenerate the shader */
|
||||||
shader */
|
|
||||||
int n_tex_coord_attribs;
|
int n_tex_coord_attribs;
|
||||||
} CoglPipelineShaderState;
|
} CoglPipelineShaderState;
|
||||||
|
|
||||||
@ -125,6 +126,7 @@ shader_state_new (int n_layers)
|
|||||||
shader_state = g_slice_new0 (CoglPipelineShaderState);
|
shader_state = g_slice_new0 (CoglPipelineShaderState);
|
||||||
shader_state->ref_count = 1;
|
shader_state->ref_count = 1;
|
||||||
shader_state->unit_state = g_new0 (UnitState, n_layers);
|
shader_state->unit_state = g_new0 (UnitState, n_layers);
|
||||||
|
shader_state->ref_point_coord = FALSE;
|
||||||
|
|
||||||
return shader_state;
|
return shader_state;
|
||||||
}
|
}
|
||||||
@ -295,13 +297,12 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
|
|||||||
/* If we already have a valid GLSL shader then we don't need to
|
/* 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
|
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
|
has changed since the last link then we do need a new
|
||||||
shader. If the number of tex coord attribs changes on GLES2
|
shader. Also if the number of tex coord attribs changes
|
||||||
then we need to regenerate the shader with a different boiler
|
then we need to regenerate the shader with a different boiler
|
||||||
plate */
|
plate */
|
||||||
if ((user_program == NULL ||
|
if ((user_program == NULL ||
|
||||||
shader_state->user_program_age == user_program->age)
|
shader_state->user_program_age == user_program->age)
|
||||||
&& (ctx->driver != COGL_DRIVER_GLES2 ||
|
&& shader_state->n_tex_coord_attribs == n_tex_coord_attribs)
|
||||||
shader_state->n_tex_coord_attribs == n_tex_coord_attribs))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* We need to recreate the shader so destroy the existing one */
|
/* We need to recreate the shader so destroy the existing one */
|
||||||
@ -430,19 +431,13 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
|
|||||||
layer->index,
|
layer->index,
|
||||||
layer->index);
|
layer->index);
|
||||||
|
|
||||||
/* If point sprite coord generation is being used then divert to the
|
if (cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline,
|
||||||
built-in varying var for that instead of the texture
|
|
||||||
coordinates. We don't want to do this under GL because in that
|
|
||||||
case we will instead use glTexEnv(GL_COORD_REPLACE) to replace
|
|
||||||
the texture coords with the point sprite coords. Although GL also
|
|
||||||
supports the gl_PointCoord variable, it requires GLSL 1.2 which
|
|
||||||
would mean we would have to declare the GLSL version and check
|
|
||||||
for it */
|
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2 &&
|
|
||||||
cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline,
|
|
||||||
layer->index))
|
layer->index))
|
||||||
g_string_append_printf (shader_state->source,
|
{
|
||||||
"vec4 (gl_PointCoord, 0.0, 1.0)");
|
shader_state->ref_point_coord = TRUE;
|
||||||
|
g_string_append_printf (shader_state->source,
|
||||||
|
"vec4 (gl_PointCoord, 0.0, 1.0)");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
g_string_append_printf (shader_state->source,
|
g_string_append_printf (shader_state->source,
|
||||||
"cogl_tex_coord_in[%d]",
|
"cogl_tex_coord_in[%d]",
|
||||||
@ -1000,6 +995,7 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
|
|||||||
GLint compile_status;
|
GLint compile_status;
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
CoglPipelineSnippetData snippet_data;
|
CoglPipelineSnippetData snippet_data;
|
||||||
|
const char *version_string;
|
||||||
|
|
||||||
COGL_STATIC_COUNTER (fragend_glsl_compile_counter,
|
COGL_STATIC_COUNTER (fragend_glsl_compile_counter,
|
||||||
"glsl fragment compile counter",
|
"glsl fragment compile counter",
|
||||||
@ -1075,7 +1071,16 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
|
|||||||
lengths[1] = shader_state->source->len;
|
lengths[1] = shader_state->source->len;
|
||||||
source_strings[1] = shader_state->source->str;
|
source_strings[1] = shader_state->source->str;
|
||||||
|
|
||||||
|
if (shader_state->ref_point_coord &&
|
||||||
|
ctx->driver == COGL_DRIVER_GL)
|
||||||
|
{
|
||||||
|
version_string = "#version 120\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
version_string = NULL;
|
||||||
|
|
||||||
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
||||||
|
version_string,
|
||||||
shader, GL_FRAGMENT_SHADER,
|
shader, GL_FRAGMENT_SHADER,
|
||||||
shader_state
|
shader_state
|
||||||
->n_tex_coord_attribs,
|
->n_tex_coord_attribs,
|
||||||
|
@ -850,8 +850,11 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
|
|||||||
GE( ctx, glBindSampler (unit_index, sampler_state->sampler_object) );
|
GE( ctx, glBindSampler (unit_index, sampler_state->sampler_object) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Under GLES2 the fragment shader will use gl_PointCoord instead of
|
/* FIXME: If using GLSL the progend we will use gl_PointCoord
|
||||||
replacing the texture coordinates */
|
* instead of us needing to replace the texture coordinates but at
|
||||||
|
* this point we can't currently tell if we are using the fixed or
|
||||||
|
* glsl progend.
|
||||||
|
*/
|
||||||
#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GL)
|
#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GL)
|
||||||
if (ctx->driver != COGL_DRIVER_GLES2 &&
|
if (ctx->driver != COGL_DRIVER_GLES2 &&
|
||||||
(layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS))
|
(layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS))
|
||||||
@ -1342,12 +1345,11 @@ done:
|
|||||||
|
|
||||||
progend = _cogl_pipeline_progends[pipeline->progend];
|
progend = _cogl_pipeline_progends[pipeline->progend];
|
||||||
|
|
||||||
/* We can't assume the color will be retained between flushes on
|
/* We can't assume the color will be retained between flushes when
|
||||||
GLES2 because the generic attribute values are not stored as part
|
* using the glsl progend because the generic attribute values are
|
||||||
of the program object so they could be overridden by any
|
* not stored as part of the program object so they could be
|
||||||
attribute changes in another program */
|
* overridden by any attribute changes in another program */
|
||||||
#ifdef HAVE_COGL_GLES2
|
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL && !skip_gl_color)
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2 && !skip_gl_color)
|
|
||||||
{
|
{
|
||||||
int attribute;
|
int attribute;
|
||||||
CoglPipeline *authority =
|
CoglPipeline *authority =
|
||||||
@ -1364,7 +1366,6 @@ done:
|
|||||||
cogl_color_get_blue_float (&authority->color),
|
cogl_color_get_blue_float (&authority->color),
|
||||||
cogl_color_get_alpha_float (&authority->color)));
|
cogl_color_get_alpha_float (&authority->color)));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Give the progend a chance to update any uniforms that might not
|
/* Give the progend a chance to update any uniforms that might not
|
||||||
* depend on the material state. This is used on GLES2 to update the
|
* depend on the material state. This is used on GLES2 to update the
|
||||||
|
@ -118,6 +118,7 @@ typedef struct
|
|||||||
#ifdef HAVE_COGL_GLES2
|
#ifdef HAVE_COGL_GLES2
|
||||||
unsigned long dirty_builtin_uniforms;
|
unsigned long dirty_builtin_uniforms;
|
||||||
GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)];
|
GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)];
|
||||||
|
#endif
|
||||||
|
|
||||||
GLint modelview_uniform;
|
GLint modelview_uniform;
|
||||||
GLint projection_uniform;
|
GLint projection_uniform;
|
||||||
@ -125,7 +126,6 @@ typedef struct
|
|||||||
|
|
||||||
CoglMatrixEntryCache projection_cache;
|
CoglMatrixEntryCache projection_cache;
|
||||||
CoglMatrixEntryCache modelview_cache;
|
CoglMatrixEntryCache modelview_cache;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We need to track the last pipeline that the program was used with
|
/* We need to track the last pipeline that the program was used with
|
||||||
* so know if we need to update all of the uniforms */
|
* so know if we need to update all of the uniforms */
|
||||||
@ -226,8 +226,6 @@ clear_attribute_cache (CoglPipelineProgramState *program_state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_flushed_matrix_stacks (CoglPipelineProgramState *program_state)
|
clear_flushed_matrix_stacks (CoglPipelineProgramState *program_state)
|
||||||
{
|
{
|
||||||
@ -237,8 +235,6 @@ clear_flushed_matrix_stacks (CoglPipelineProgramState *program_state)
|
|||||||
_cogl_matrix_entry_cache_init (&program_state->modelview_cache);
|
_cogl_matrix_entry_cache_init (&program_state->modelview_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_COGL_GLES2 */
|
|
||||||
|
|
||||||
static CoglPipelineProgramState *
|
static CoglPipelineProgramState *
|
||||||
program_state_new (int n_layers)
|
program_state_new (int n_layers)
|
||||||
{
|
{
|
||||||
@ -251,10 +247,8 @@ program_state_new (int n_layers)
|
|||||||
program_state->unit_state = g_new (UnitState, n_layers);
|
program_state->unit_state = g_new (UnitState, n_layers);
|
||||||
program_state->uniform_locations = NULL;
|
program_state->uniform_locations = NULL;
|
||||||
program_state->attribute_locations = NULL;
|
program_state->attribute_locations = NULL;
|
||||||
#ifdef HAVE_COGL_GLES2
|
|
||||||
_cogl_matrix_entry_cache_init (&program_state->modelview_cache);
|
_cogl_matrix_entry_cache_init (&program_state->modelview_cache);
|
||||||
_cogl_matrix_entry_cache_init (&program_state->projection_cache);
|
_cogl_matrix_entry_cache_init (&program_state->projection_cache);
|
||||||
#endif
|
|
||||||
|
|
||||||
return program_state;
|
return program_state;
|
||||||
}
|
}
|
||||||
@ -278,13 +272,8 @@ destroy_program_state (void *user_data,
|
|||||||
{
|
{
|
||||||
clear_attribute_cache (program_state);
|
clear_attribute_cache (program_state);
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
_cogl_matrix_entry_cache_destroy (&program_state->projection_cache);
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
_cogl_matrix_entry_cache_destroy (&program_state->modelview_cache);
|
||||||
{
|
|
||||||
_cogl_matrix_entry_cache_destroy (&program_state->projection_cache);
|
|
||||||
_cogl_matrix_entry_cache_destroy (&program_state->modelview_cache);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (program_state->program)
|
if (program_state->program)
|
||||||
GE( ctx, glDeleteProgram (program_state->program) );
|
GE( ctx, glDeleteProgram (program_state->program) );
|
||||||
@ -395,20 +384,15 @@ get_uniform_cb (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
unit_state->combine_constant_uniform = uniform_location;
|
unit_state->combine_constant_uniform = uniform_location;
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
g_string_set_size (ctx->codegen_source_buffer, 0);
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
g_string_append_printf (ctx->codegen_source_buffer,
|
||||||
{
|
"cogl_texture_matrix[%i]", state->unit);
|
||||||
g_string_set_size (ctx->codegen_source_buffer, 0);
|
|
||||||
g_string_append_printf (ctx->codegen_source_buffer,
|
|
||||||
"cogl_texture_matrix[%i]", state->unit);
|
|
||||||
|
|
||||||
GE_RET( uniform_location,
|
GE_RET( uniform_location,
|
||||||
ctx, glGetUniformLocation (state->gl_program,
|
ctx, glGetUniformLocation (state->gl_program,
|
||||||
ctx->codegen_source_buffer->str) );
|
ctx->codegen_source_buffer->str) );
|
||||||
|
|
||||||
unit_state->texture_matrix_uniform = uniform_location;
|
unit_state->texture_matrix_uniform = uniform_location;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
state->unit++;
|
state->unit++;
|
||||||
|
|
||||||
@ -438,10 +422,7 @@ update_constants_cb (CoglPipeline *pipeline,
|
|||||||
unit_state->dirty_combine_constant = FALSE;
|
unit_state->dirty_combine_constant = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
if (unit_state->texture_matrix_uniform != -1 &&
|
||||||
|
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2 &&
|
|
||||||
unit_state->texture_matrix_uniform != -1 &&
|
|
||||||
(state->update_all || unit_state->dirty_texture_matrix))
|
(state->update_all || unit_state->dirty_texture_matrix))
|
||||||
{
|
{
|
||||||
const CoglMatrix *matrix;
|
const CoglMatrix *matrix;
|
||||||
@ -454,8 +435,6 @@ update_constants_cb (CoglPipeline *pipeline,
|
|||||||
unit_state->dirty_texture_matrix = FALSE;
|
unit_state->dirty_texture_matrix = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_COGL_GLES2 */
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,8 +721,7 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
|
|||||||
* _cogl_tex_coord[] varying array declaration. */
|
* _cogl_tex_coord[] varying array declaration. */
|
||||||
if ((program_state->program && user_program &&
|
if ((program_state->program && user_program &&
|
||||||
user_program->age != program_state->user_program_age) ||
|
user_program->age != program_state->user_program_age) ||
|
||||||
(ctx->driver == COGL_DRIVER_GLES2 &&
|
n_tex_coord_attribs != program_state->n_tex_coord_attribs)
|
||||||
n_tex_coord_attribs != program_state->n_tex_coord_attribs))
|
|
||||||
{
|
{
|
||||||
GE( ctx, glDeleteProgram (program_state->program) );
|
GE( ctx, glDeleteProgram (program_state->program) );
|
||||||
program_state->program = 0;
|
program_state->program = 0;
|
||||||
@ -816,38 +794,36 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
|
|||||||
update_constants_cb,
|
update_constants_cb,
|
||||||
&state);
|
&state);
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
if (program_changed)
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
|
||||||
{
|
{
|
||||||
if (program_changed)
|
int i;
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
clear_flushed_matrix_stacks (program_state);
|
clear_flushed_matrix_stacks (program_state);
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
|
for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
|
||||||
GE_RET( program_state->builtin_uniform_locations[i], ctx,
|
GE_RET( program_state->builtin_uniform_locations[i], ctx,
|
||||||
glGetUniformLocation (gl_program,
|
glGetUniformLocation (gl_program,
|
||||||
builtin_uniforms[i].uniform_name) );
|
builtin_uniforms[i].uniform_name) );
|
||||||
|
|
||||||
GE_RET( program_state->modelview_uniform, ctx,
|
GE_RET( program_state->modelview_uniform, ctx,
|
||||||
glGetUniformLocation (gl_program,
|
glGetUniformLocation (gl_program,
|
||||||
"cogl_modelview_matrix") );
|
"cogl_modelview_matrix") );
|
||||||
|
|
||||||
GE_RET( program_state->projection_uniform, ctx,
|
GE_RET( program_state->projection_uniform, ctx,
|
||||||
glGetUniformLocation (gl_program,
|
glGetUniformLocation (gl_program,
|
||||||
"cogl_projection_matrix") );
|
"cogl_projection_matrix") );
|
||||||
|
|
||||||
GE_RET( program_state->mvp_uniform, ctx,
|
GE_RET( program_state->mvp_uniform, ctx,
|
||||||
glGetUniformLocation (gl_program,
|
glGetUniformLocation (gl_program,
|
||||||
"cogl_modelview_projection_matrix") );
|
"cogl_modelview_projection_matrix") );
|
||||||
}
|
|
||||||
if (program_changed ||
|
|
||||||
program_state->last_used_for_pipeline != pipeline)
|
|
||||||
program_state->dirty_builtin_uniforms = ~(unsigned long) 0;
|
|
||||||
|
|
||||||
update_builtin_uniforms (pipeline, gl_program, program_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
if (program_changed ||
|
||||||
|
program_state->last_used_for_pipeline != pipeline)
|
||||||
|
program_state->dirty_builtin_uniforms = ~(unsigned long) 0;
|
||||||
|
|
||||||
|
update_builtin_uniforms (pipeline, gl_program, program_state);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_cogl_pipeline_progend_glsl_flush_uniforms (pipeline,
|
_cogl_pipeline_progend_glsl_flush_uniforms (pipeline,
|
||||||
@ -944,6 +920,11 @@ _cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline,
|
|||||||
CoglMatrixEntry *projection_entry;
|
CoglMatrixEntry *projection_entry;
|
||||||
CoglMatrixEntry *modelview_entry;
|
CoglMatrixEntry *modelview_entry;
|
||||||
CoglPipelineProgramState *program_state;
|
CoglPipelineProgramState *program_state;
|
||||||
|
CoglBool modelview_changed;
|
||||||
|
CoglBool projection_changed;
|
||||||
|
CoglBool need_modelview;
|
||||||
|
CoglBool need_projection;
|
||||||
|
CoglMatrix modelview, projection;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -960,117 +941,87 @@ _cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
needs_flip = cogl_is_offscreen (ctx->current_draw_buffer);
|
needs_flip = cogl_is_offscreen (ctx->current_draw_buffer);
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
projection_changed =
|
||||||
if (ctx->driver == COGL_DRIVER_GLES2)
|
_cogl_matrix_entry_cache_maybe_update (&program_state->projection_cache,
|
||||||
|
projection_entry,
|
||||||
|
(needs_flip &&
|
||||||
|
program_state->flip_uniform ==
|
||||||
|
-1));
|
||||||
|
|
||||||
|
modelview_changed =
|
||||||
|
_cogl_matrix_entry_cache_maybe_update (&program_state->modelview_cache,
|
||||||
|
modelview_entry,
|
||||||
|
/* never flip modelview */
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
if (modelview_changed || projection_changed)
|
||||||
{
|
{
|
||||||
CoglBool modelview_changed;
|
if (program_state->mvp_uniform != -1)
|
||||||
CoglBool projection_changed;
|
need_modelview = need_projection = TRUE;
|
||||||
CoglBool need_modelview;
|
else
|
||||||
CoglBool need_projection;
|
|
||||||
CoglMatrix modelview, projection;
|
|
||||||
|
|
||||||
projection_changed =
|
|
||||||
_cogl_matrix_entry_cache_maybe_update (&program_state->projection_cache,
|
|
||||||
projection_entry,
|
|
||||||
(needs_flip &&
|
|
||||||
program_state->flip_uniform ==
|
|
||||||
-1));
|
|
||||||
|
|
||||||
modelview_changed =
|
|
||||||
_cogl_matrix_entry_cache_maybe_update (&program_state->modelview_cache,
|
|
||||||
modelview_entry,
|
|
||||||
/* never flip modelview */
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
if (modelview_changed || projection_changed)
|
|
||||||
{
|
{
|
||||||
if (program_state->mvp_uniform != -1)
|
need_projection = (program_state->projection_uniform != -1 &&
|
||||||
need_modelview = need_projection = TRUE;
|
projection_changed);
|
||||||
|
need_modelview = (program_state->modelview_uniform != -1 &&
|
||||||
|
modelview_changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_modelview)
|
||||||
|
_cogl_matrix_entry_get (modelview_entry, &modelview);
|
||||||
|
if (need_projection)
|
||||||
|
{
|
||||||
|
if (needs_flip && program_state->flip_uniform == -1)
|
||||||
|
{
|
||||||
|
CoglMatrix tmp_matrix;
|
||||||
|
_cogl_matrix_entry_get (projection_entry, &tmp_matrix);
|
||||||
|
cogl_matrix_multiply (&projection,
|
||||||
|
&ctx->y_flip_matrix,
|
||||||
|
&tmp_matrix);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_cogl_matrix_entry_get (projection_entry, &projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (projection_changed && program_state->projection_uniform != -1)
|
||||||
|
GE (ctx, glUniformMatrix4fv (program_state->projection_uniform,
|
||||||
|
1, /* count */
|
||||||
|
FALSE, /* transpose */
|
||||||
|
cogl_matrix_get_array (&projection)));
|
||||||
|
|
||||||
|
if (modelview_changed && program_state->modelview_uniform != -1)
|
||||||
|
GE (ctx, glUniformMatrix4fv (program_state->modelview_uniform,
|
||||||
|
1, /* count */
|
||||||
|
FALSE, /* transpose */
|
||||||
|
cogl_matrix_get_array (&modelview)));
|
||||||
|
|
||||||
|
if (program_state->mvp_uniform != -1)
|
||||||
|
{
|
||||||
|
/* The journal usually uses an identity matrix for the
|
||||||
|
modelview so we can optimise this common case by
|
||||||
|
avoiding the matrix multiplication */
|
||||||
|
if (_cogl_matrix_entry_has_identity_flag (modelview_entry))
|
||||||
|
{
|
||||||
|
GE (ctx,
|
||||||
|
glUniformMatrix4fv (program_state->mvp_uniform,
|
||||||
|
1, /* count */
|
||||||
|
FALSE, /* transpose */
|
||||||
|
cogl_matrix_get_array (&projection)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
need_projection = (program_state->projection_uniform != -1 &&
|
CoglMatrix combined;
|
||||||
projection_changed);
|
|
||||||
need_modelview = (program_state->modelview_uniform != -1 &&
|
|
||||||
modelview_changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_modelview)
|
cogl_matrix_multiply (&combined,
|
||||||
_cogl_matrix_entry_get (modelview_entry, &modelview);
|
&projection,
|
||||||
if (need_projection)
|
&modelview);
|
||||||
{
|
GE (ctx,
|
||||||
if (needs_flip && program_state->flip_uniform == -1)
|
glUniformMatrix4fv (program_state->mvp_uniform,
|
||||||
{
|
1, /* count */
|
||||||
CoglMatrix tmp_matrix;
|
FALSE, /* transpose */
|
||||||
_cogl_matrix_entry_get (projection_entry, &tmp_matrix);
|
cogl_matrix_get_array (&combined)));
|
||||||
cogl_matrix_multiply (&projection,
|
|
||||||
&ctx->y_flip_matrix,
|
|
||||||
&tmp_matrix);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_cogl_matrix_entry_get (projection_entry, &projection);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (projection_changed && program_state->projection_uniform != -1)
|
|
||||||
GE (ctx, glUniformMatrix4fv (program_state->projection_uniform,
|
|
||||||
1, /* count */
|
|
||||||
FALSE, /* transpose */
|
|
||||||
cogl_matrix_get_array (&projection)));
|
|
||||||
|
|
||||||
if (modelview_changed && program_state->modelview_uniform != -1)
|
|
||||||
GE (ctx, glUniformMatrix4fv (program_state->modelview_uniform,
|
|
||||||
1, /* count */
|
|
||||||
FALSE, /* transpose */
|
|
||||||
cogl_matrix_get_array (&modelview)));
|
|
||||||
|
|
||||||
if (program_state->mvp_uniform != -1)
|
|
||||||
{
|
|
||||||
/* The journal usually uses an identity matrix for the
|
|
||||||
modelview so we can optimise this common case by
|
|
||||||
avoiding the matrix multiplication */
|
|
||||||
if (_cogl_matrix_entry_has_identity_flag (modelview_entry))
|
|
||||||
{
|
|
||||||
GE (ctx,
|
|
||||||
glUniformMatrix4fv (program_state->mvp_uniform,
|
|
||||||
1, /* count */
|
|
||||||
FALSE, /* transpose */
|
|
||||||
cogl_matrix_get_array (&projection)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CoglMatrix combined;
|
|
||||||
|
|
||||||
cogl_matrix_multiply (&combined,
|
|
||||||
&projection,
|
|
||||||
&modelview);
|
|
||||||
GE (ctx,
|
|
||||||
glUniformMatrix4fv (program_state->mvp_uniform,
|
|
||||||
1, /* count */
|
|
||||||
FALSE, /* transpose */
|
|
||||||
cogl_matrix_get_array (&combined)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
CoglBool disable_flip;
|
|
||||||
|
|
||||||
/* If there are vertex snippets, then we'll disable flipping the
|
|
||||||
geometry via the matrix and use the flip vertex instead */
|
|
||||||
disable_flip = program_state->flip_uniform != -1;
|
|
||||||
|
|
||||||
_cogl_matrix_entry_flush_to_gl_builtins (ctx,
|
|
||||||
projection_entry,
|
|
||||||
COGL_MATRIX_PROJECTION,
|
|
||||||
framebuffer,
|
|
||||||
disable_flip);
|
|
||||||
_cogl_matrix_entry_flush_to_gl_builtins (ctx,
|
|
||||||
modelview_entry,
|
|
||||||
COGL_MATRIX_MODELVIEW,
|
|
||||||
framebuffer,
|
|
||||||
disable_flip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (program_state->flip_uniform != -1
|
if (program_state->flip_uniform != -1
|
||||||
&& program_state->flushed_flip_state != needs_flip)
|
&& program_state->flushed_flip_state != needs_flip)
|
||||||
|
@ -61,8 +61,7 @@ typedef struct
|
|||||||
unsigned int user_program_age;
|
unsigned int user_program_age;
|
||||||
|
|
||||||
/* The number of tex coord attributes that the shader was generated
|
/* The number of tex coord attributes that the shader was generated
|
||||||
for. If this changes on GLES2 then we need to regenerate the
|
* for. If this changes then we need to regenerate the shader */
|
||||||
shader */
|
|
||||||
int n_tex_coord_attribs;
|
int n_tex_coord_attribs;
|
||||||
} CoglPipelineShaderState;
|
} CoglPipelineShaderState;
|
||||||
|
|
||||||
@ -219,14 +218,12 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
|
|||||||
{
|
{
|
||||||
/* If we already have a valid GLSL shader then we don't need to
|
/* 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
|
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
|
has changed since the last link then we do need a new shader.
|
||||||
shader. If the number of tex coord attribs changes on GLES2
|
Also if the number of tex coord attribs changes then we need
|
||||||
then we need to regenerate the shader with a different boiler
|
to regenerate the shader with a different boiler plate */
|
||||||
plate */
|
|
||||||
if ((user_program == NULL ||
|
if ((user_program == NULL ||
|
||||||
shader_state->user_program_age == user_program->age)
|
shader_state->user_program_age == user_program->age)
|
||||||
&& (ctx->driver != COGL_DRIVER_GLES2 ||
|
&& shader_state->n_tex_coord_attribs == n_tex_coord_attribs)
|
||||||
shader_state->n_tex_coord_attribs == n_tex_coord_attribs))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* We need to recreate the shader so destroy the existing one */
|
/* We need to recreate the shader so destroy the existing one */
|
||||||
@ -287,33 +284,6 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
unit_index = _cogl_pipeline_layer_get_unit_index (layer);
|
unit_index = _cogl_pipeline_layer_get_unit_index (layer);
|
||||||
|
|
||||||
if (ctx->driver != COGL_DRIVER_GLES2)
|
|
||||||
{
|
|
||||||
/* We are using the fixed function uniforms for the user matrices
|
|
||||||
and the only way to set them is with the fixed function API so we
|
|
||||||
still need to flush them here */
|
|
||||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX)
|
|
||||||
{
|
|
||||||
CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX;
|
|
||||||
CoglPipelineLayer *authority =
|
|
||||||
_cogl_pipeline_layer_get_authority (layer, state);
|
|
||||||
CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index);
|
|
||||||
CoglMatrixEntry *matrix_entry;
|
|
||||||
|
|
||||||
_cogl_matrix_stack_set (unit->matrix_stack,
|
|
||||||
&authority->big_state->matrix);
|
|
||||||
|
|
||||||
_cogl_set_active_texture_unit (unit_index);
|
|
||||||
|
|
||||||
matrix_entry = unit->matrix_stack->last_entry;
|
|
||||||
_cogl_matrix_entry_flush_to_gl_builtins (ctx,
|
|
||||||
matrix_entry,
|
|
||||||
COGL_MATRIX_TEXTURE,
|
|
||||||
framebuffer,
|
|
||||||
FALSE /* do flip */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shader_state->source == NULL)
|
if (shader_state->source == NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -464,6 +434,7 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
|
|||||||
source_strings[1] = shader_state->source->str;
|
source_strings[1] = shader_state->source->str;
|
||||||
|
|
||||||
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
||||||
|
NULL,
|
||||||
shader, GL_VERTEX_SHADER,
|
shader, GL_VERTEX_SHADER,
|
||||||
shader_state
|
shader_state
|
||||||
->n_tex_coord_attribs,
|
->n_tex_coord_attribs,
|
||||||
|
@ -457,13 +457,6 @@ _cogl_driver_update_features (CoglContext *ctx,
|
|||||||
_cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
|
_cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
|
||||||
private_flags |= COGL_PRIVATE_FEATURE_PBOS;
|
private_flags |= COGL_PRIVATE_FEATURE_PBOS;
|
||||||
|
|
||||||
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
|
|
||||||
_cogl_check_extension ("GL_ARB_point_sprite", gl_extensions))
|
|
||||||
{
|
|
||||||
flags |= COGL_FEATURE_POINT_SPRITE;
|
|
||||||
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->glGenPrograms)
|
if (ctx->glGenPrograms)
|
||||||
{
|
{
|
||||||
flags |= COGL_FEATURE_SHADERS_ARBFP;
|
flags |= COGL_FEATURE_SHADERS_ARBFP;
|
||||||
@ -503,6 +496,20 @@ _cogl_driver_update_features (CoglContext *ctx,
|
|||||||
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
|
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
|
||||||
|
_cogl_check_extension ("GL_ARB_point_sprite", gl_extensions)) &&
|
||||||
|
|
||||||
|
/* If GLSL is supported then we only enable point sprite support
|
||||||
|
* too if we have glsl >= 1.2 otherwise we don't have the
|
||||||
|
* gl_PointCoord builtin which we depend on in the glsl backend.
|
||||||
|
*/
|
||||||
|
(!COGL_FLAGS_GET (ctx->features, COGL_FEATURE_ID_GLSL) ||
|
||||||
|
COGL_CHECK_GL_VERSION (ctx->glsl_major, ctx->glsl_minor, 1, 2)))
|
||||||
|
{
|
||||||
|
flags |= COGL_FEATURE_POINT_SPRITE;
|
||||||
|
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->glGenBuffers)
|
if (ctx->glGenBuffers)
|
||||||
{
|
{
|
||||||
private_flags |= COGL_PRIVATE_FEATURE_VBOS;
|
private_flags |= COGL_PRIVATE_FEATURE_VBOS;
|
||||||
|
Loading…
Reference in New Issue
Block a user