diff --git a/include/sway/desktop/fx_renderer.h b/include/sway/desktop/fx_renderer.h index 86cd21a3..a48a00e1 100644 --- a/include/sway/desktop/fx_renderer.h +++ b/include/sway/desktop/fx_renderer.h @@ -7,11 +7,16 @@ enum corner_location { ALL, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, NONE }; -enum fx_gles2_shader_source { - WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA = 1, - WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX = 2, - WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL = 3, - WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE = 4, +enum fx_tex_shader_source { + SHADER_SOURCE_TEXTURE_RGBA = 1, + SHADER_SOURCE_TEXTURE_RGBX = 2, + SHADER_SOURCE_TEXTURE_EXTERNAL = 3, +}; + +enum fx_rounded_quad_shader_source { + SHADER_SOURCE_QUAD_ROUND = 1, + SHADER_SOURCE_QUAD_ROUND_TOP_LEFT = 2, + SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT = 3, }; struct decoration_data { diff --git a/sway/desktop/fx_renderer.c b/sway/desktop/fx_renderer.c index 80ede4d3..a5ad0dab 100644 --- a/sway/desktop/fx_renderer.c +++ b/sway/desktop/fx_renderer.c @@ -22,8 +22,6 @@ #include "corner_frag_src.h" #include "quad_frag_src.h" #include "quad_round_frag_src.h" -#include "quad_round_tl_frag_src.h" -#include "quad_round_tr_frag_src.h" #include "tex_frag_src.h" static const GLfloat verts[] = { @@ -98,9 +96,9 @@ static void matrix_projection(float mat[static 9], int width, int height, mat[8] = 1.0f; } -static GLuint compile_shader(GLuint type, const GLchar **srcs, size_t srcs_len) { +static GLuint compile_shader(GLuint type, const GLchar *src) { GLuint shader = glCreateShader(type); - glShaderSource(shader, srcs_len, srcs, NULL); + glShaderSource(shader, 1, &src, NULL); glCompileShader(shader); GLint ok; @@ -114,24 +112,14 @@ static GLuint compile_shader(GLuint type, const GLchar **srcs, size_t srcs_len) return shader; } -static GLuint link_program(const GLchar *frag_src, enum fx_gles2_shader_source source) { +static GLuint link_program(const GLchar *frag_src) { const GLchar *vert_src = common_vert_src; - GLuint vert = compile_shader(GL_VERTEX_SHADER, &vert_src, 1); + GLuint vert = compile_shader(GL_VERTEX_SHADER, vert_src); if (!vert) { goto error; } - GLuint frag; - if (source != WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE) { - static char frag_preamble[1024]; - snprintf(frag_preamble, sizeof(frag_preamble), - "#define SOURCE %d\n", source); - - const GLchar *frag_srcs[2] = { frag_preamble, frag_src }; - frag = compile_shader(GL_FRAGMENT_SHADER, frag_srcs, 2); - } else { - frag = compile_shader(GL_FRAGMENT_SHADER, &frag_src, 1); - } + GLuint frag = compile_shader(GL_FRAGMENT_SHADER, frag_src); if (!frag) { glDeleteShader(vert); goto error; @@ -162,11 +150,13 @@ error: } static bool link_tex_program(struct fx_renderer *renderer, - struct gles2_tex_shader *shader, enum fx_gles2_shader_source source) { - GLuint prog; - const GLchar *frag_src = tex_frag_src; + struct gles2_tex_shader *shader, enum fx_tex_shader_source source) { + GLchar frag_src[2048]; + snprintf(frag_src, sizeof(frag_src), + "#define SOURCE %d\n%s", source, tex_frag_src); - shader->program = prog = link_program(frag_src, source); + GLuint prog; + shader->program = prog = link_program(frag_src); if (!shader->program) { return false; } @@ -187,18 +177,25 @@ static bool link_tex_program(struct fx_renderer *renderer, return true; } -// initializes a provided rounded quad shader and returns false if unsuccessful -bool init_rounded_quad_shader(struct rounded_quad_shader *shader, GLuint prog) { - shader->program = prog; +static bool link_rounded_quad_program(struct fx_renderer *renderer, + struct rounded_quad_shader *shader, enum fx_rounded_quad_shader_source source) { + GLchar quad_src[2048]; + snprintf(quad_src, sizeof(quad_src), + "#define SOURCE %d\n%s", source, quad_round_frag_src); + + GLuint prog; + shader->program = prog = link_program(quad_src); if (!shader->program) { return false; } + shader->proj = glGetUniformLocation(prog, "proj"); shader->color = glGetUniformLocation(prog, "color"); shader->pos_attrib = glGetAttribLocation(prog, "pos"); shader->size = glGetUniformLocation(prog, "size"); shader->position = glGetUniformLocation(prog, "position"); shader->radius = glGetUniformLocation(prog, "radius"); + return true; } @@ -269,7 +266,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) { GLuint prog; // quad fragment shader - prog = link_program(quad_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); + prog = link_program(quad_frag_src); renderer->shaders.quad.program = prog; if (!renderer->shaders.quad.program) { goto error; @@ -279,21 +276,21 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) { renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos"); // rounded quad fragment shaders - prog = link_program(quad_round_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); - if (!init_rounded_quad_shader(&renderer->shaders.rounded_quad, prog)) { + if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_quad, + SHADER_SOURCE_QUAD_ROUND)) { goto error; } - prog = link_program(quad_round_tl_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); - if (!init_rounded_quad_shader(&renderer->shaders.rounded_tl_quad, prog)) { + if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_tl_quad, + SHADER_SOURCE_QUAD_ROUND_TOP_LEFT)) { goto error; } - prog = link_program(quad_round_tr_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); - if (!init_rounded_quad_shader(&renderer->shaders.rounded_tr_quad, prog)) { + if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_tr_quad, + SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT)) { goto error; } // Border corner shader - prog = link_program(corner_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); + prog = link_program(corner_frag_src); renderer->shaders.corner.program = prog; if (!renderer->shaders.corner.program) { goto error; @@ -311,7 +308,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) { renderer->shaders.corner.half_thickness = glGetUniformLocation(prog, "half_thickness"); // box shadow shader - prog = link_program(box_shadow_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); + prog = link_program(box_shadow_frag_src); renderer->shaders.box_shadow.program = prog; if (!renderer->shaders.box_shadow.program) { goto error; @@ -326,15 +323,15 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) { // fragment shaders if (!link_tex_program(renderer, &renderer->shaders.tex_rgba, - WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA)) { + SHADER_SOURCE_TEXTURE_RGBA)) { goto error; } if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx, - WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX)) { + SHADER_SOURCE_TEXTURE_RGBX)) { goto error; } if (!link_tex_program(renderer, &renderer->shaders.tex_ext, - WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL)) { + SHADER_SOURCE_TEXTURE_EXTERNAL)) { goto error; } diff --git a/sway/desktop/shaders/meson.build b/sway/desktop/shaders/meson.build index 14014c7d..6c0dd1d3 100644 --- a/sway/desktop/shaders/meson.build +++ b/sway/desktop/shaders/meson.build @@ -6,8 +6,6 @@ shaders = [ 'corner.frag', 'quad.frag', 'quad_round.frag', - 'quad_round_tl.frag', - 'quad_round_tr.frag', 'tex.frag', ] diff --git a/sway/desktop/shaders/quad_round.frag b/sway/desktop/shaders/quad_round.frag index ddd6fe9b..4dcf0c53 100644 --- a/sway/desktop/shaders/quad_round.frag +++ b/sway/desktop/shaders/quad_round.frag @@ -1,3 +1,11 @@ +#define SOURCE_QUAD_ROUND 1 +#define SOURCE_QUAD_ROUND_TOP_LEFT 2 +#define SOURCE_QUAD_ROUND_TOP_RIGHT 3 + +#if !defined(SOURCE) +#error "Missing shader preamble" +#endif + precision mediump float; varying vec4 v_color; varying vec2 v_texcoord; @@ -6,9 +14,19 @@ uniform vec2 size; uniform vec2 position; uniform float radius; -void main() { +vec2 getCornerDist() { +#if SOURCE == SOURCE_QUAD_ROUND vec2 half_size = size * 0.5; - vec2 q = abs(gl_FragCoord.xy - position - half_size) - half_size + radius; + return abs(gl_FragCoord.xy - position - half_size) - half_size + radius; +#elif SOURCE == SOURCE_QUAD_ROUND_TOP_LEFT + return abs(gl_FragCoord.xy - position - size) - size + radius; +#elif SOURCE == SOURCE_QUAD_ROUND_TOP_RIGHT + return abs(gl_FragCoord.xy - position - vec2(0, size.y)) - size + radius; +#endif +} + +void main() { + vec2 q = getCornerDist(); float dist = min(max(q.x,q.y), 0.0) + length(max(q, 0.0)) - radius; float smoothedAlpha = 1.0 - smoothstep(-1.0, 0.5, dist); gl_FragColor = mix(vec4(0), v_color, smoothedAlpha); diff --git a/sway/desktop/shaders/quad_round_tl.frag b/sway/desktop/shaders/quad_round_tl.frag deleted file mode 100644 index 758fece9..00000000 --- a/sway/desktop/shaders/quad_round_tl.frag +++ /dev/null @@ -1,14 +0,0 @@ -precision mediump float; -varying vec4 v_color; -varying vec2 v_texcoord; - -uniform vec2 size; -uniform vec2 position; -uniform float radius; - -void main() { - vec2 q = abs(gl_FragCoord.xy - position - size) - size + radius; - float distance = min(max(q.x,q.y),0.0) + length(max(q,0.0)) - radius; - float smoothedAlpha = 1.0 - smoothstep(-1.0, 0.5, distance); - gl_FragColor = mix(vec4(0), v_color, smoothedAlpha); -} diff --git a/sway/desktop/shaders/quad_round_tr.frag b/sway/desktop/shaders/quad_round_tr.frag deleted file mode 100644 index 1d8e879f..00000000 --- a/sway/desktop/shaders/quad_round_tr.frag +++ /dev/null @@ -1,14 +0,0 @@ -precision mediump float; -varying vec4 v_color; -varying vec2 v_texcoord; - -uniform vec2 size; -uniform vec2 position; -uniform float radius; - -void main() { - vec2 q = abs(gl_FragCoord.xy - position - vec2(0, size.y)) - size + radius; - float distance = min(max(q.x,q.y),0.0) + length(max(q,0.0)) - radius; - float smoothedAlpha = 1.0 - smoothstep(-1.0, 0.5, distance); - gl_FragColor = mix(vec4(0), v_color, smoothedAlpha); -} diff --git a/sway/desktop/shaders/tex.frag b/sway/desktop/shaders/tex.frag index 51a42c4f..817b838c 100644 --- a/sway/desktop/shaders/tex.frag +++ b/sway/desktop/shaders/tex.frag @@ -1,4 +1,3 @@ -/* enum wlr_gles2_shader_source */ #define SOURCE_TEXTURE_RGBA 1 #define SOURCE_TEXTURE_RGBX 2 #define SOURCE_TEXTURE_EXTERNAL 3