From 1ed73246ed339897640981e9b7cb0abd84e30241 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Fri, 17 May 2013 14:00:40 +0300 Subject: [PATCH] gl-renderer: Compile shaders only when needed Saves some start up time by not compiling specific shaders until they are needed. --- src/gl-renderer.c | 70 +++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 12451f8f..be74eba3 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -44,6 +44,7 @@ struct gl_shader { GLint tex_uniforms[3]; GLint alpha_uniform; GLint color_uniform; + const char *vertex_source, *fragment_source; }; #define BUFFER_DAMAGE_COUNT 2 @@ -717,13 +718,26 @@ use_output(struct weston_output *output) return 0; } +static int +shader_init(struct gl_shader *shader, struct gl_renderer *gr, + const char *vertex_source, const char *fragment_source); + static void -use_shader(struct gl_renderer *gr, - struct gl_shader *shader) +use_shader(struct gl_renderer *gr, struct gl_shader *shader) { + if (!shader->program) { + int ret; + + ret = shader_init(shader, gr, + shader->vertex_source, + shader->fragment_source); + + if (ret < 0) + weston_log("warning: failed to compile shader\n"); + } + if (gr->current_shader == shader) return; - glUseProgram(shader->program); gr->current_shader = shader; } @@ -1453,14 +1467,13 @@ compile_shader(GLenum type, int count, const char **sources) } static int -shader_init(struct gl_shader *shader, struct weston_compositor *ec, +shader_init(struct gl_shader *shader, struct gl_renderer *renderer, const char *vertex_source, const char *fragment_source) { char msg[512]; GLint status; int count; const char *sources[3]; - struct gl_renderer *renderer = get_renderer(ec); shader->vertex_shader = compile_shader(GL_VERTEX_SHADER, 1, &vertex_source); @@ -1844,28 +1857,29 @@ compile_shaders(struct weston_compositor *ec) { struct gl_renderer *gr = get_renderer(ec); - if (shader_init(&gr->texture_shader_rgba, ec, - vertex_shader, texture_fragment_shader_rgba) < 0) - return -1; - if (shader_init(&gr->texture_shader_rgbx, ec, - vertex_shader, texture_fragment_shader_rgbx) < 0) - return -1; - if (gr->has_egl_image_external && - shader_init(&gr->texture_shader_egl_external, ec, - vertex_shader, texture_fragment_shader_egl_external) < 0) - return -1; - if (shader_init(&gr->texture_shader_y_uv, ec, - vertex_shader, texture_fragment_shader_y_uv) < 0) - return -1; - if (shader_init(&gr->texture_shader_y_u_v, ec, - vertex_shader, texture_fragment_shader_y_u_v) < 0) - return -1; - if (shader_init(&gr->texture_shader_y_xuxv, ec, - vertex_shader, texture_fragment_shader_y_xuxv) < 0) - return -1; - if (shader_init(&gr->solid_shader, ec, - vertex_shader, solid_fragment_shader) < 0) - return -1; + gr->texture_shader_rgba.vertex_source = vertex_shader; + gr->texture_shader_rgba.fragment_source = texture_fragment_shader_rgba; + + gr->texture_shader_rgbx.vertex_source = vertex_shader; + gr->texture_shader_rgbx.fragment_source = texture_fragment_shader_rgbx; + + gr->texture_shader_egl_external.vertex_source = vertex_shader; + gr->texture_shader_egl_external.fragment_source = + texture_fragment_shader_egl_external; + + gr->texture_shader_y_uv.vertex_source = vertex_shader; + gr->texture_shader_y_uv.fragment_source = texture_fragment_shader_y_uv; + + gr->texture_shader_y_u_v.vertex_source = vertex_shader; + gr->texture_shader_y_u_v.fragment_source = + texture_fragment_shader_y_u_v; + + gr->texture_shader_y_u_v.vertex_source = vertex_shader; + gr->texture_shader_y_xuxv.fragment_source = + texture_fragment_shader_y_xuxv; + + gr->solid_shader.vertex_source = vertex_shader; + gr->solid_shader.fragment_source = solid_fragment_shader; return 0; } @@ -1888,8 +1902,6 @@ fragment_debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, shader_release(&gr->texture_shader_y_xuxv); shader_release(&gr->solid_shader); - compile_shaders(ec); - /* Force use_shader() to call glUseProgram(), since we need to use * the recompiled version of the shader. */ gr->current_shader = NULL;