gl-renderer: Compile shaders only when needed
Saves some start up time by not compiling specific shaders until they are needed.
This commit is contained in:
committed by
Kristian Høgsberg
parent
f6128fcd6c
commit
1ed73246ed
+41
-29
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user