compositor: fix and simplify shader uniform handling
authorPekka Paalanen <ppaalanen@gmail.com>
Thu, 2 Feb 2012 14:49:05 +0000 (16:49 +0200)
committerPekka Paalanen <ppaalanen@gmail.com>
Thu, 2 Feb 2012 14:49:05 +0000 (16:49 +0200)
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>
src/compositor.c
src/compositor.h

index 1fe90cd..3a26424 100644 (file)
@@ -704,21 +704,11 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
 
        glUniformMatrix4fv(es->shader->proj_uniform,
                           1, GL_FALSE, output->matrix.d);
-
-       if (es->shader->tex_uniform != GL_NONE)
-               glUniform1i(es->shader->tex_uniform, 0);
-
-       if (es->shader->color_uniform != GL_NONE)
-               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);
+       glUniform1i(es->shader->tex_uniform, 0);
+       glUniform4fv(es->shader->color_uniform, 1, es->color);
+       glUniform1f(es->shader->alpha_uniform, es->alpha / 255.0);
+       glUniform1f(es->shader->texwidth_uniform,
+                   (GLfloat)es->geometry.width / es->pitch);
 
        if (es->transform.enabled)
                filter = GL_LINEAR;
@@ -1849,43 +1839,13 @@ weston_shader_init(struct weston_shader *shader,
        shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
        shader->tex_uniform = glGetUniformLocation(shader->program, "tex");
        shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
+       shader->color_uniform = glGetUniformLocation(shader->program, "color");
        shader->texwidth_uniform = glGetUniformLocation(shader->program,
                                                        "texwidth");
 
        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
 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,
                             vertex_shader, texture_fragment_shader) < 0)
                return -1;
-       if (init_solid_shader(&ec->solid_shader,
-                             ec->texture_shader.vertex_shader,
-                             solid_fragment_shader) < 0)
+       if (weston_shader_init(&ec->solid_shader,
+                            vertex_shader, solid_fragment_shader) < 0)
                return -1;
 
        loop = wl_display_get_event_loop(ec->wl_display);
index 4bc4ba2..5d12d43 100644 (file)
@@ -99,11 +99,11 @@ enum weston_visual {
 struct weston_shader {
        GLuint program;
        GLuint vertex_shader, fragment_shader;
-       GLuint proj_uniform;
-       GLuint tex_uniform;
-       GLuint alpha_uniform;
-       GLuint color_uniform;
-       GLuint texwidth_uniform;
+       GLint proj_uniform;
+       GLint tex_uniform;
+       GLint alpha_uniform;
+       GLint color_uniform;
+       GLint texwidth_uniform;
 };
 
 struct weston_animation {
@@ -148,7 +148,6 @@ struct weston_compositor {
        EGLContext context;
        EGLConfig config;
        GLuint fbo;
-       uint32_t current_alpha;
        struct weston_shader texture_shader;
        struct weston_shader solid_shader;
        struct weston_shader *current_shader;