From d75e5b7726c7c533f3808ec66306a6c6f5affa0d Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 26 Oct 2022 12:03:50 +0200 Subject: [PATCH 1/5] render/gles2: move shaders to individual files Instead of having a C file with strings for each shader, move each shader into its own file. Use a small POSIX shell script to convert the files into C strings (can't wait for C23 #embed...). The benefits from this are: - Improved readability and syntax highlighting. - Line numbers in shader compiler errors are easier to make sense of. - Consistency with the Vulkan renderer. - Shaders will become more complicated as we add color management features. --- meson.build | 2 +- render/gles2/meson.build | 3 +- render/gles2/renderer.c | 22 ++++---- render/gles2/shaders.c | 69 -------------------------- render/gles2/shaders/embed.sh | 11 ++++ render/gles2/shaders/meson.build | 23 +++++++++ render/gles2/shaders/quad.frag | 7 +++ render/gles2/shaders/quad.vert | 12 +++++ render/gles2/shaders/tex.vert | 9 ++++ render/gles2/shaders/tex_external.frag | 10 ++++ render/gles2/shaders/tex_rgba.frag | 8 +++ render/gles2/shaders/tex_rgbx.frag | 8 +++ 12 files changed, 102 insertions(+), 82 deletions(-) delete mode 100644 render/gles2/shaders.c create mode 100755 render/gles2/shaders/embed.sh create mode 100644 render/gles2/shaders/meson.build create mode 100644 render/gles2/shaders/quad.frag create mode 100644 render/gles2/shaders/quad.vert create mode 100644 render/gles2/shaders/tex.vert create mode 100644 render/gles2/shaders/tex_external.frag create mode 100644 render/gles2/shaders/tex_rgba.frag create mode 100644 render/gles2/shaders/tex_rgbx.frag diff --git a/meson.build b/meson.build index a180b43c0..45eeabaa6 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'c', version: '0.16.0-dev', license: 'MIT', - meson_version: '>=0.58.1', + meson_version: '>=0.59.0', default_options: [ 'c_std=c11', 'warning_level=2', diff --git a/render/gles2/meson.build b/render/gles2/meson.build index 504f0c11e..c92269837 100644 --- a/render/gles2/meson.build +++ b/render/gles2/meson.build @@ -10,6 +10,7 @@ wlr_deps += glesv2 wlr_files += files( 'pixel_format.c', 'renderer.c', - 'shaders.c', 'texture.c', ) + +subdir('shaders') diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index b1543cddc..85d6055ba 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -19,6 +19,13 @@ #include "render/pixel_format.h" #include "types/wlr_matrix.h" +#include "quad_vert_src.h" +#include "quad_frag_src.h" +#include "tex_vert_src.h" +#include "tex_rgba_frag_src.h" +#include "tex_rgbx_frag_src.h" +#include "tex_external_frag_src.h" + static const GLfloat verts[] = { 1, 0, // top right 0, 0, // top left @@ -665,13 +672,6 @@ static void load_gl_proc(void *proc_ptr, const char *name) { *(void **)proc_ptr = proc; } -extern const GLchar quad_vertex_src[]; -extern const GLchar quad_fragment_src[]; -extern const GLchar tex_vertex_src[]; -extern const GLchar tex_fragment_src_rgba[]; -extern const GLchar tex_fragment_src_rgbx[]; -extern const GLchar tex_fragment_src_external[]; - struct wlr_renderer *wlr_gles2_renderer_create_with_drm_fd(int drm_fd) { struct wlr_egl *egl = wlr_egl_create_with_drm_fd(drm_fd); if (egl == NULL) { @@ -784,7 +784,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { GLuint prog; renderer->shaders.quad.program = prog = - link_program(renderer, quad_vertex_src, quad_fragment_src); + link_program(renderer, quad_vert_src, quad_frag_src); if (!renderer->shaders.quad.program) { goto error; } @@ -793,7 +793,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos"); renderer->shaders.tex_rgba.program = prog = - link_program(renderer, tex_vertex_src, tex_fragment_src_rgba); + link_program(renderer, tex_vert_src, tex_rgba_frag_src); if (!renderer->shaders.tex_rgba.program) { goto error; } @@ -804,7 +804,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { renderer->shaders.tex_rgba.tex_attrib = glGetAttribLocation(prog, "texcoord"); renderer->shaders.tex_rgbx.program = prog = - link_program(renderer, tex_vertex_src, tex_fragment_src_rgbx); + link_program(renderer, tex_vert_src, tex_rgbx_frag_src); if (!renderer->shaders.tex_rgbx.program) { goto error; } @@ -816,7 +816,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { if (renderer->exts.OES_egl_image_external) { renderer->shaders.tex_ext.program = prog = - link_program(renderer, tex_vertex_src, tex_fragment_src_external); + link_program(renderer, tex_vert_src, tex_external_frag_src); if (!renderer->shaders.tex_ext.program) { goto error; } diff --git a/render/gles2/shaders.c b/render/gles2/shaders.c deleted file mode 100644 index 7898059ed..000000000 --- a/render/gles2/shaders.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include "render/gles2.h" - -// Colored quads -const GLchar quad_vertex_src[] = -"uniform mat3 proj;\n" -"uniform vec4 color;\n" -"attribute vec2 pos;\n" -"attribute vec2 texcoord;\n" -"varying vec4 v_color;\n" -"varying vec2 v_texcoord;\n" -"\n" -"void main() {\n" -" gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);\n" -" v_color = color;\n" -" v_texcoord = texcoord;\n" -"}\n"; - -const GLchar quad_fragment_src[] = -"precision mediump float;\n" -"varying vec4 v_color;\n" -"varying vec2 v_texcoord;\n" -"\n" -"void main() {\n" -" gl_FragColor = v_color;\n" -"}\n"; - -// Textured quads -const GLchar tex_vertex_src[] = -"uniform mat3 proj;\n" -"attribute vec2 pos;\n" -"attribute vec2 texcoord;\n" -"varying vec2 v_texcoord;\n" -"\n" -"void main() {\n" -" gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);\n" -" v_texcoord = texcoord;\n" -"}\n"; - -const GLchar tex_fragment_src_rgba[] = -"precision mediump float;\n" -"varying vec2 v_texcoord;\n" -"uniform sampler2D tex;\n" -"uniform float alpha;\n" -"\n" -"void main() {\n" -" gl_FragColor = texture2D(tex, v_texcoord) * alpha;\n" -"}\n"; - -const GLchar tex_fragment_src_rgbx[] = -"precision mediump float;\n" -"varying vec2 v_texcoord;\n" -"uniform sampler2D tex;\n" -"uniform float alpha;\n" -"\n" -"void main() {\n" -" gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0) * alpha;\n" -"}\n"; - -const GLchar tex_fragment_src_external[] = -"#extension GL_OES_EGL_image_external : require\n\n" -"precision mediump float;\n" -"varying vec2 v_texcoord;\n" -"uniform samplerExternalOES texture0;\n" -"uniform float alpha;\n" -"\n" -"void main() {\n" -" gl_FragColor = texture2D(texture0, v_texcoord) * alpha;\n" -"}\n"; diff --git a/render/gles2/shaders/embed.sh b/render/gles2/shaders/embed.sh new file mode 100755 index 000000000..acd7a1199 --- /dev/null +++ b/render/gles2/shaders/embed.sh @@ -0,0 +1,11 @@ +#!/bin/sh -eu + +var=${1:-data} +hex="$(od -A n -t x1 -v)" + +echo "static const char $var[] = {" +for byte in $hex; do + echo " 0x$byte," +done +echo " 0x00," +echo "};" diff --git a/render/gles2/shaders/meson.build b/render/gles2/shaders/meson.build new file mode 100644 index 000000000..626c2b149 --- /dev/null +++ b/render/gles2/shaders/meson.build @@ -0,0 +1,23 @@ +embed = find_program('./embed.sh', native: true) + +shaders = [ + 'quad.vert', + 'quad.frag', + 'tex.vert', + 'tex_rgba.frag', + 'tex_rgbx.frag', + 'tex_external.frag', +] + +foreach name : shaders + output = name.underscorify() + '_src.h' + var = name.underscorify() + '_src' + wlr_files += custom_target( + output, + command: [embed, var], + input: name, + output: output, + feed: true, + capture: true, + ) +endforeach diff --git a/render/gles2/shaders/quad.frag b/render/gles2/shaders/quad.frag new file mode 100644 index 000000000..08291046a --- /dev/null +++ b/render/gles2/shaders/quad.frag @@ -0,0 +1,7 @@ +precision mediump float; +varying vec4 v_color; +varying vec2 v_texcoord; + +void main() { + gl_FragColor = v_color; +} diff --git a/render/gles2/shaders/quad.vert b/render/gles2/shaders/quad.vert new file mode 100644 index 000000000..abcafd07e --- /dev/null +++ b/render/gles2/shaders/quad.vert @@ -0,0 +1,12 @@ +uniform mat3 proj; +uniform vec4 color; +attribute vec2 pos; +attribute vec2 texcoord; +varying vec4 v_color; +varying vec2 v_texcoord; + +void main() { + gl_Position = vec4(proj * vec3(pos, 1.0), 1.0); + v_color = color; + v_texcoord = texcoord; +} diff --git a/render/gles2/shaders/tex.vert b/render/gles2/shaders/tex.vert new file mode 100644 index 000000000..9cebb458f --- /dev/null +++ b/render/gles2/shaders/tex.vert @@ -0,0 +1,9 @@ +uniform mat3 proj; +attribute vec2 pos; +attribute vec2 texcoord; +varying vec2 v_texcoord; + +void main() { + gl_Position = vec4(proj * vec3(pos, 1.0), 1.0); + v_texcoord = texcoord; +} diff --git a/render/gles2/shaders/tex_external.frag b/render/gles2/shaders/tex_external.frag new file mode 100644 index 000000000..05eac5032 --- /dev/null +++ b/render/gles2/shaders/tex_external.frag @@ -0,0 +1,10 @@ +#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 new file mode 100644 index 000000000..c2e17a90f --- /dev/null +++ b/render/gles2/shaders/tex_rgba.frag @@ -0,0 +1,8 @@ +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 new file mode 100644 index 000000000..42ddf92ff --- /dev/null +++ b/render/gles2/shaders/tex_rgbx.frag @@ -0,0 +1,8 @@ +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; +} From 3295243da6f63a478b58bcaebcfdb66bf10514a1 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 27 Oct 2022 15:58:34 +0200 Subject: [PATCH 2/5] render/gles2: move color uniform from quad.vert to quad.vert We have no use for a v_color varying. We can use the uniform directly from the fragment shader without getting the vertex shader involved. --- render/gles2/shaders/quad.frag | 3 ++- render/gles2/shaders/quad.vert | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/render/gles2/shaders/quad.frag b/render/gles2/shaders/quad.frag index 08291046a..f97127971 100644 --- a/render/gles2/shaders/quad.frag +++ b/render/gles2/shaders/quad.frag @@ -1,7 +1,8 @@ precision mediump float; varying vec4 v_color; varying vec2 v_texcoord; +uniform vec4 color; void main() { - gl_FragColor = v_color; + gl_FragColor = color; } diff --git a/render/gles2/shaders/quad.vert b/render/gles2/shaders/quad.vert index abcafd07e..9cebb458f 100644 --- a/render/gles2/shaders/quad.vert +++ b/render/gles2/shaders/quad.vert @@ -1,12 +1,9 @@ uniform mat3 proj; -uniform vec4 color; attribute vec2 pos; attribute vec2 texcoord; -varying vec4 v_color; varying vec2 v_texcoord; void main() { gl_Position = vec4(proj * vec3(pos, 1.0), 1.0); - v_color = color; v_texcoord = texcoord; } From 30a61470f8e18e2b2a6d5e0db3a8229b136d6ee4 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 27 Oct 2022 16:05:50 +0200 Subject: [PATCH 3/5] render/gles2: de-duplicate vertex shaders The vertex shaders for quads and textures are identical. --- render/gles2/renderer.c | 11 +++++------ render/gles2/shaders/{quad.vert => common.vert} | 0 render/gles2/shaders/meson.build | 3 +-- render/gles2/shaders/tex.vert | 9 --------- 4 files changed, 6 insertions(+), 17 deletions(-) rename render/gles2/shaders/{quad.vert => common.vert} (100%) delete mode 100644 render/gles2/shaders/tex.vert diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 85d6055ba..0d5497f8b 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -19,9 +19,8 @@ #include "render/pixel_format.h" #include "types/wlr_matrix.h" -#include "quad_vert_src.h" +#include "common_vert_src.h" #include "quad_frag_src.h" -#include "tex_vert_src.h" #include "tex_rgba_frag_src.h" #include "tex_rgbx_frag_src.h" #include "tex_external_frag_src.h" @@ -784,7 +783,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { GLuint prog; renderer->shaders.quad.program = prog = - link_program(renderer, quad_vert_src, quad_frag_src); + link_program(renderer, common_vert_src, quad_frag_src); if (!renderer->shaders.quad.program) { goto error; } @@ -793,7 +792,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos"); renderer->shaders.tex_rgba.program = prog = - link_program(renderer, tex_vert_src, tex_rgba_frag_src); + link_program(renderer, common_vert_src, tex_rgba_frag_src); if (!renderer->shaders.tex_rgba.program) { goto error; } @@ -804,7 +803,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { renderer->shaders.tex_rgba.tex_attrib = glGetAttribLocation(prog, "texcoord"); renderer->shaders.tex_rgbx.program = prog = - link_program(renderer, tex_vert_src, tex_rgbx_frag_src); + link_program(renderer, common_vert_src, tex_rgbx_frag_src); if (!renderer->shaders.tex_rgbx.program) { goto error; } @@ -816,7 +815,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { if (renderer->exts.OES_egl_image_external) { renderer->shaders.tex_ext.program = prog = - link_program(renderer, tex_vert_src, tex_external_frag_src); + link_program(renderer, common_vert_src, tex_external_frag_src); if (!renderer->shaders.tex_ext.program) { goto error; } diff --git a/render/gles2/shaders/quad.vert b/render/gles2/shaders/common.vert similarity index 100% rename from render/gles2/shaders/quad.vert rename to render/gles2/shaders/common.vert diff --git a/render/gles2/shaders/meson.build b/render/gles2/shaders/meson.build index 626c2b149..79454d9aa 100644 --- a/render/gles2/shaders/meson.build +++ b/render/gles2/shaders/meson.build @@ -1,9 +1,8 @@ embed = find_program('./embed.sh', native: true) shaders = [ - 'quad.vert', + 'common.vert', 'quad.frag', - 'tex.vert', 'tex_rgba.frag', 'tex_rgbx.frag', 'tex_external.frag', diff --git a/render/gles2/shaders/tex.vert b/render/gles2/shaders/tex.vert deleted file mode 100644 index 9cebb458f..000000000 --- a/render/gles2/shaders/tex.vert +++ /dev/null @@ -1,9 +0,0 @@ -uniform mat3 proj; -attribute vec2 pos; -attribute vec2 texcoord; -varying vec2 v_texcoord; - -void main() { - gl_Position = vec4(proj * vec3(pos, 1.0), 1.0); - v_texcoord = texcoord; -} From 49799ca0bc0391f01b205746c14404e0d711588f Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 26 Oct 2022 19:48:18 +0200 Subject: [PATCH 4/5] render/gles2: log error on shader compilation failure --- render/gles2/renderer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 0d5497f8b..8d0601504 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -596,6 +596,7 @@ static GLuint compile_shader(struct wlr_gles2_renderer *renderer, GLint ok; glGetShaderiv(shader, GL_COMPILE_STATUS, &ok); if (ok == GL_FALSE) { + wlr_log(WLR_ERROR, "Failed to compile shader"); glDeleteShader(shader); shader = 0; } @@ -632,6 +633,7 @@ static GLuint link_program(struct wlr_gles2_renderer *renderer, GLint ok; glGetProgramiv(prog, GL_LINK_STATUS, &ok); if (ok == GL_FALSE) { + wlr_log(WLR_ERROR, "Failed to link shader"); glDeleteProgram(prog); goto error; } From 22594d3723aca8f5a64393301f9ee805fdde18ee Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 26 Oct 2022 21:22:47 +0200 Subject: [PATCH 5/5] render/gles2: unify fragment shader Instead of having 3 different fragment shaders for textures and 1 more for quads, unify them all and compile different variants via a SOURCE constant. In the future, we will have more variant dimensions: pre-multiplied alpha on/off, color transformation, etc. It will become inpractical to have one file per combination. Weston has a similar approach: https://gitlab.freedesktop.org/wayland/weston/-/blob/main/libweston/renderer-gl/fragment.glsl --- include/render/gles2.h | 6 ++ render/gles2/renderer.c | 78 +++++++++++++------------- render/gles2/shaders/common.frag | 45 +++++++++++++++ render/gles2/shaders/meson.build | 5 +- render/gles2/shaders/quad.frag | 8 --- render/gles2/shaders/tex_external.frag | 10 ---- render/gles2/shaders/tex_rgba.frag | 8 --- render/gles2/shaders/tex_rgbx.frag | 8 --- 8 files changed, 91 insertions(+), 77 deletions(-) create mode 100644 render/gles2/shaders/common.frag delete mode 100644 render/gles2/shaders/quad.frag delete mode 100644 render/gles2/shaders/tex_external.frag delete mode 100644 render/gles2/shaders/tex_rgba.frag delete mode 100644 render/gles2/shaders/tex_rgbx.frag diff --git a/include/render/gles2.h b/include/render/gles2.h index 6631d34ce..b3ac31195 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 8d0601504..21bfdff5e 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 @@ -586,11 +583,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; @@ -606,15 +603,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; @@ -646,6 +650,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); @@ -785,7 +806,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; } @@ -793,39 +814,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; -}