compositor: fix and simplify shader uniform handling

The uniform location variables should be signed, according to the OpenGL
ES 2 specification. Moreover, GL_NONE, i.e. 0, is not an invalid nor
special location; it is actually used as a valid uniform location.

Change struct weston_shader uniform members to signed.

Stop using 0 for identifying a non-existing uniform, use -1 instead.
Furthermore, as the spec says a) glGetUniformLocation() will return -1
for non-active/existing uniforms, and b) glUniform*() function will
simply ignore all calls with location -1, we can simplify the code. We
don't have to avoid locating uniforms that don't exist, and we don't
need to test for them in weston_surface_draw() either.

Remove the micro-optimisation that avoids setting 'alpha' uniform if it
has not changed, in the name of simplification.

Unify shader creation by dropping init_solid_shader(), and calling
weston_shader_init() instead. The downside is that we compile the vertex
shader twice at startup now.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
dev
Pekka Paalanen 13 years ago
parent 0e4452e02a
commit f55f544e4f
  1. 57
      src/compositor.c
  2. 11
      src/compositor.h

@ -704,21 +704,11 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
glUniformMatrix4fv(es->shader->proj_uniform, glUniformMatrix4fv(es->shader->proj_uniform,
1, GL_FALSE, output->matrix.d); 1, GL_FALSE, output->matrix.d);
glUniform1i(es->shader->tex_uniform, 0);
if (es->shader->tex_uniform != GL_NONE) glUniform4fv(es->shader->color_uniform, 1, es->color);
glUniform1i(es->shader->tex_uniform, 0); glUniform1f(es->shader->alpha_uniform, es->alpha / 255.0);
glUniform1f(es->shader->texwidth_uniform,
if (es->shader->color_uniform != GL_NONE) (GLfloat)es->geometry.width / es->pitch);
glUniform4fv(es->shader->color_uniform,1, es->color);
if (es->shader->alpha_uniform && es->alpha != ec->current_alpha) {
glUniform1f(es->shader->alpha_uniform, es->alpha / 255.0);
ec->current_alpha = es->alpha;
}
if (es->shader->texwidth_uniform != GL_NONE)
glUniform1f(es->shader->texwidth_uniform,
(GLfloat)es->geometry.width / es->pitch);
if (es->transform.enabled) if (es->transform.enabled)
filter = GL_LINEAR; filter = GL_LINEAR;
@ -1849,43 +1839,13 @@ weston_shader_init(struct weston_shader *shader,
shader->proj_uniform = glGetUniformLocation(shader->program, "proj"); shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
shader->tex_uniform = glGetUniformLocation(shader->program, "tex"); shader->tex_uniform = glGetUniformLocation(shader->program, "tex");
shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha"); shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
shader->color_uniform = glGetUniformLocation(shader->program, "color");
shader->texwidth_uniform = glGetUniformLocation(shader->program, shader->texwidth_uniform = glGetUniformLocation(shader->program,
"texwidth"); "texwidth");
return 0; return 0;
} }
static int
init_solid_shader(struct weston_shader *shader,
GLuint vertex_shader, const char *fragment_source)
{
GLint status;
char msg[512];
shader->vertex_shader = vertex_shader;
shader->fragment_shader =
compile_shader(GL_FRAGMENT_SHADER, fragment_source);
shader->program = glCreateProgram();
glAttachShader(shader->program, shader->vertex_shader);
glAttachShader(shader->program, shader->fragment_shader);
glBindAttribLocation(shader->program, 0, "position");
glBindAttribLocation(shader->program, 1, "texcoord");
glLinkProgram(shader->program);
glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
if (!status) {
glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
fprintf(stderr, "link info: %s\n", msg);
return -1;
}
shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
shader->color_uniform = glGetUniformLocation(shader->program, "color");
return 0;
}
WL_EXPORT void WL_EXPORT void
weston_output_destroy(struct weston_output *output) weston_output_destroy(struct weston_output *output)
{ {
@ -2060,9 +2020,8 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
if (weston_shader_init(&ec->texture_shader, if (weston_shader_init(&ec->texture_shader,
vertex_shader, texture_fragment_shader) < 0) vertex_shader, texture_fragment_shader) < 0)
return -1; return -1;
if (init_solid_shader(&ec->solid_shader, if (weston_shader_init(&ec->solid_shader,
ec->texture_shader.vertex_shader, vertex_shader, solid_fragment_shader) < 0)
solid_fragment_shader) < 0)
return -1; return -1;
loop = wl_display_get_event_loop(ec->wl_display); loop = wl_display_get_event_loop(ec->wl_display);

@ -99,11 +99,11 @@ enum weston_visual {
struct weston_shader { struct weston_shader {
GLuint program; GLuint program;
GLuint vertex_shader, fragment_shader; GLuint vertex_shader, fragment_shader;
GLuint proj_uniform; GLint proj_uniform;
GLuint tex_uniform; GLint tex_uniform;
GLuint alpha_uniform; GLint alpha_uniform;
GLuint color_uniform; GLint color_uniform;
GLuint texwidth_uniform; GLint texwidth_uniform;
}; };
struct weston_animation { struct weston_animation {
@ -148,7 +148,6 @@ struct weston_compositor {
EGLContext context; EGLContext context;
EGLConfig config; EGLConfig config;
GLuint fbo; GLuint fbo;
uint32_t current_alpha;
struct weston_shader texture_shader; struct weston_shader texture_shader;
struct weston_shader solid_shader; struct weston_shader solid_shader;
struct weston_shader *current_shader; struct weston_shader *current_shader;

Loading…
Cancel
Save