gl-renderer: Compile shaders only when needed

Saves some start up time by not compiling specific shaders until they
are needed.
Ander Conselvan de Oliveira 12 years ago committed by Kristian Høgsberg
parent f6128fcd6c
commit 1ed73246ed
  1. 70
      src/gl-renderer.c

@ -44,6 +44,7 @@ struct gl_shader {
GLint tex_uniforms[3]; GLint tex_uniforms[3];
GLint alpha_uniform; GLint alpha_uniform;
GLint color_uniform; GLint color_uniform;
const char *vertex_source, *fragment_source;
}; };
#define BUFFER_DAMAGE_COUNT 2 #define BUFFER_DAMAGE_COUNT 2
@ -717,13 +718,26 @@ use_output(struct weston_output *output)
return 0; return 0;
} }
static int
shader_init(struct gl_shader *shader, struct gl_renderer *gr,
const char *vertex_source, const char *fragment_source);
static void static void
use_shader(struct gl_renderer *gr, use_shader(struct gl_renderer *gr, struct gl_shader *shader)
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) if (gr->current_shader == shader)
return; return;
glUseProgram(shader->program); glUseProgram(shader->program);
gr->current_shader = shader; gr->current_shader = shader;
} }
@ -1453,14 +1467,13 @@ compile_shader(GLenum type, int count, const char **sources)
} }
static int 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) const char *vertex_source, const char *fragment_source)
{ {
char msg[512]; char msg[512];
GLint status; GLint status;
int count; int count;
const char *sources[3]; const char *sources[3];
struct gl_renderer *renderer = get_renderer(ec);
shader->vertex_shader = shader->vertex_shader =
compile_shader(GL_VERTEX_SHADER, 1, &vertex_source); 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); struct gl_renderer *gr = get_renderer(ec);
if (shader_init(&gr->texture_shader_rgba, ec, gr->texture_shader_rgba.vertex_source = vertex_shader;
vertex_shader, texture_fragment_shader_rgba) < 0) gr->texture_shader_rgba.fragment_source = texture_fragment_shader_rgba;
return -1;
if (shader_init(&gr->texture_shader_rgbx, ec, gr->texture_shader_rgbx.vertex_source = vertex_shader;
vertex_shader, texture_fragment_shader_rgbx) < 0) gr->texture_shader_rgbx.fragment_source = texture_fragment_shader_rgbx;
return -1;
if (gr->has_egl_image_external && gr->texture_shader_egl_external.vertex_source = vertex_shader;
shader_init(&gr->texture_shader_egl_external, ec, gr->texture_shader_egl_external.fragment_source =
vertex_shader, texture_fragment_shader_egl_external) < 0) texture_fragment_shader_egl_external;
return -1;
if (shader_init(&gr->texture_shader_y_uv, ec, gr->texture_shader_y_uv.vertex_source = vertex_shader;
vertex_shader, texture_fragment_shader_y_uv) < 0) gr->texture_shader_y_uv.fragment_source = texture_fragment_shader_y_uv;
return -1;
if (shader_init(&gr->texture_shader_y_u_v, ec, gr->texture_shader_y_u_v.vertex_source = vertex_shader;
vertex_shader, texture_fragment_shader_y_u_v) < 0) gr->texture_shader_y_u_v.fragment_source =
return -1; texture_fragment_shader_y_u_v;
if (shader_init(&gr->texture_shader_y_xuxv, ec,
vertex_shader, texture_fragment_shader_y_xuxv) < 0) gr->texture_shader_y_u_v.vertex_source = vertex_shader;
return -1; gr->texture_shader_y_xuxv.fragment_source =
if (shader_init(&gr->solid_shader, ec, texture_fragment_shader_y_xuxv;
vertex_shader, solid_fragment_shader) < 0)
return -1; gr->solid_shader.vertex_source = vertex_shader;
gr->solid_shader.fragment_source = solid_fragment_shader;
return 0; 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->texture_shader_y_xuxv);
shader_release(&gr->solid_shader); shader_release(&gr->solid_shader);
compile_shaders(ec);
/* Force use_shader() to call glUseProgram(), since we need to use /* Force use_shader() to call glUseProgram(), since we need to use
* the recompiled version of the shader. */ * the recompiled version of the shader. */
gr->current_shader = NULL; gr->current_shader = NULL;

Loading…
Cancel
Save