diff --git a/include/render/gles2.h b/include/render/gles2.h index f54fc835b..8c281988e 100644 --- a/include/render/gles2.h +++ b/include/render/gles2.h @@ -112,6 +112,12 @@ struct wlr_gles2_texture { struct wlr_addon buffer_addon; }; +enum wlr_gles2_shader_source { + WLR_GLES2_SHADER_SOURCE_SINGLE_COLOR = 1, + WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA = 2, + WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX = 3, + WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL = 4, +}; bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer, const struct wlr_gles2_pixel_format *format); diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 47c58b194..6dcbac53e 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -20,10 +20,7 @@ #include "types/wlr_matrix.h" #include "common_vert_src.h" -#include "quad_frag_src.h" -#include "tex_rgba_frag_src.h" -#include "tex_rgbx_frag_src.h" -#include "tex_external_frag_src.h" +#include "common_frag_src.h" static const GLfloat verts[] = { 1, 0, // top right @@ -610,11 +607,11 @@ static void gles2_log(GLenum src, GLenum type, GLuint id, GLenum severity, } static GLuint compile_shader(struct wlr_gles2_renderer *renderer, - GLuint type, const GLchar *src) { + GLuint type, const GLchar **srcs, size_t srcs_len) { push_gles2_debug(renderer); GLuint shader = glCreateShader(type); - glShaderSource(shader, 1, &src, NULL); + glShaderSource(shader, srcs_len, srcs, NULL); glCompileShader(shader); GLint ok; @@ -630,15 +627,22 @@ static GLuint compile_shader(struct wlr_gles2_renderer *renderer, } static GLuint link_program(struct wlr_gles2_renderer *renderer, - const GLchar *vert_src, const GLchar *frag_src) { + enum wlr_gles2_shader_source source) { + static char frag_preamble[1024]; + snprintf(frag_preamble, sizeof(frag_preamble), + "#define SOURCE %d\n", source); + push_gles2_debug(renderer); - GLuint vert = compile_shader(renderer, GL_VERTEX_SHADER, vert_src); + const GLchar *vert_src = common_vert_src; + GLuint vert = compile_shader(renderer, GL_VERTEX_SHADER, &vert_src, 1); if (!vert) { goto error; } - GLuint frag = compile_shader(renderer, GL_FRAGMENT_SHADER, frag_src); + const GLchar *frag_srcs[2] = { frag_preamble, common_frag_src }; + GLuint frag = + compile_shader(renderer, GL_FRAGMENT_SHADER, frag_srcs, 2); if (!frag) { glDeleteShader(vert); goto error; @@ -670,6 +674,23 @@ error: return 0; } +static bool link_tex_program(struct wlr_gles2_renderer *renderer, + struct wlr_gles2_tex_shader *shader, + enum wlr_gles2_shader_source source) { + shader->program = link_program(renderer, source); + if (!shader->program) { + return false; + } + + shader->proj = glGetUniformLocation(shader->program, "proj"); + shader->tex = glGetUniformLocation(shader->program, "tex"); + shader->alpha = glGetUniformLocation(shader->program, "alpha"); + shader->pos_attrib = glGetAttribLocation(shader->program, "pos"); + shader->tex_attrib = glGetAttribLocation(shader->program, "texcoord"); + + return true; +} + static bool check_gl_ext(const char *exts, const char *ext) { size_t extlen = strlen(ext); const char *end = exts + strlen(exts); @@ -824,7 +845,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { GLuint prog; renderer->shaders.quad.program = prog = - link_program(renderer, common_vert_src, quad_frag_src); + link_program(renderer, WLR_GLES2_SHADER_SOURCE_SINGLE_COLOR); if (!renderer->shaders.quad.program) { goto error; } @@ -832,39 +853,18 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { renderer->shaders.quad.color = glGetUniformLocation(prog, "color"); renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos"); - renderer->shaders.tex_rgba.program = prog = - link_program(renderer, common_vert_src, tex_rgba_frag_src); - if (!renderer->shaders.tex_rgba.program) { + if (!link_tex_program(renderer, &renderer->shaders.tex_rgba, + WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA)) { goto error; } - renderer->shaders.tex_rgba.proj = glGetUniformLocation(prog, "proj"); - renderer->shaders.tex_rgba.tex = glGetUniformLocation(prog, "tex"); - renderer->shaders.tex_rgba.alpha = glGetUniformLocation(prog, "alpha"); - renderer->shaders.tex_rgba.pos_attrib = glGetAttribLocation(prog, "pos"); - renderer->shaders.tex_rgba.tex_attrib = glGetAttribLocation(prog, "texcoord"); - - renderer->shaders.tex_rgbx.program = prog = - link_program(renderer, common_vert_src, tex_rgbx_frag_src); - if (!renderer->shaders.tex_rgbx.program) { + if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx, + WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX)) { goto error; } - renderer->shaders.tex_rgbx.proj = glGetUniformLocation(prog, "proj"); - renderer->shaders.tex_rgbx.tex = glGetUniformLocation(prog, "tex"); - renderer->shaders.tex_rgbx.alpha = glGetUniformLocation(prog, "alpha"); - renderer->shaders.tex_rgbx.pos_attrib = glGetAttribLocation(prog, "pos"); - renderer->shaders.tex_rgbx.tex_attrib = glGetAttribLocation(prog, "texcoord"); - - if (renderer->exts.OES_egl_image_external) { - renderer->shaders.tex_ext.program = prog = - link_program(renderer, common_vert_src, tex_external_frag_src); - if (!renderer->shaders.tex_ext.program) { - goto error; - } - renderer->shaders.tex_ext.proj = glGetUniformLocation(prog, "proj"); - renderer->shaders.tex_ext.tex = glGetUniformLocation(prog, "tex"); - renderer->shaders.tex_ext.alpha = glGetUniformLocation(prog, "alpha"); - renderer->shaders.tex_ext.pos_attrib = glGetAttribLocation(prog, "pos"); - renderer->shaders.tex_ext.tex_attrib = glGetAttribLocation(prog, "texcoord"); + if (renderer->exts.OES_egl_image_external && + !link_tex_program(renderer, &renderer->shaders.tex_ext, + WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL)) { + goto error; } pop_gles2_debug(renderer); diff --git a/render/gles2/shaders/common.frag b/render/gles2/shaders/common.frag new file mode 100644 index 000000000..bd178a722 --- /dev/null +++ b/render/gles2/shaders/common.frag @@ -0,0 +1,45 @@ +/* enum wlr_gles2_shader_source */ +#define SOURCE_SINGLE_COLOR 1 +#define SOURCE_TEXTURE_RGBA 2 +#define SOURCE_TEXTURE_RGBX 3 +#define SOURCE_TEXTURE_EXTERNAL 4 + +#if !defined(SOURCE) +#error "Missing shader preamble" +#endif + +#if SOURCE == SOURCE_TEXTURE_EXTERNAL +#extension GL_OES_EGL_image_external : require +#endif + +precision mediump float; + +varying vec2 v_texcoord; + +#if SOURCE == SOURCE_TEXTURE_EXTERNAL +uniform samplerExternalOES tex; +#elif SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_RGBX +uniform sampler2D tex; +#elif SOURCE == SOURCE_SINGLE_COLOR +uniform vec4 color; +#endif + +#if SOURCE != SOURCE_SINGLE_COLOR +uniform float alpha; +#else +const float alpha = 1.0; +#endif + +vec4 sample_texture() { +#if SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_EXTERNAL + return texture2D(tex, v_texcoord); +#elif SOURCE == SOURCE_TEXTURE_RGBX + return vec4(texture2D(tex, v_texcoord).rgb, 1.0); +#elif SOURCE == SOURCE_SINGLE_COLOR + return color; +#endif +} + +void main() { + gl_FragColor = sample_texture() * alpha; +} diff --git a/render/gles2/shaders/meson.build b/render/gles2/shaders/meson.build index 79454d9aa..62fbe8ce2 100644 --- a/render/gles2/shaders/meson.build +++ b/render/gles2/shaders/meson.build @@ -2,10 +2,7 @@ embed = find_program('./embed.sh', native: true) shaders = [ 'common.vert', - 'quad.frag', - 'tex_rgba.frag', - 'tex_rgbx.frag', - 'tex_external.frag', + 'common.frag', ] foreach name : shaders diff --git a/render/gles2/shaders/quad.frag b/render/gles2/shaders/quad.frag deleted file mode 100644 index f97127971..000000000 --- a/render/gles2/shaders/quad.frag +++ /dev/null @@ -1,8 +0,0 @@ -precision mediump float; -varying vec4 v_color; -varying vec2 v_texcoord; -uniform vec4 color; - -void main() { - gl_FragColor = color; -} diff --git a/render/gles2/shaders/tex_external.frag b/render/gles2/shaders/tex_external.frag deleted file mode 100644 index 05eac5032..000000000 --- a/render/gles2/shaders/tex_external.frag +++ /dev/null @@ -1,10 +0,0 @@ -#extension GL_OES_EGL_image_external : require - -precision mediump float; -varying vec2 v_texcoord; -uniform samplerExternalOES texture0; -uniform float alpha; - -void main() { - gl_FragColor = texture2D(texture0, v_texcoord) * alpha; -} diff --git a/render/gles2/shaders/tex_rgba.frag b/render/gles2/shaders/tex_rgba.frag deleted file mode 100644 index c2e17a90f..000000000 --- a/render/gles2/shaders/tex_rgba.frag +++ /dev/null @@ -1,8 +0,0 @@ -precision mediump float; -varying vec2 v_texcoord; -uniform sampler2D tex; -uniform float alpha; - -void main() { - gl_FragColor = texture2D(tex, v_texcoord) * alpha; -} diff --git a/render/gles2/shaders/tex_rgbx.frag b/render/gles2/shaders/tex_rgbx.frag deleted file mode 100644 index 42ddf92ff..000000000 --- a/render/gles2/shaders/tex_rgbx.frag +++ /dev/null @@ -1,8 +0,0 @@ -precision mediump float; -varying vec2 v_texcoord; -uniform sampler2D tex; -uniform float alpha; - -void main() { - gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0) * alpha; -}