summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/desktop/fx_renderer.h7
-rw-r--r--sway/desktop/fx_renderer.c62
-rw-r--r--sway/desktop/shaders/meson.build4
-rw-r--r--sway/desktop/shaders/tex.frag36
-rw-r--r--sway/desktop/shaders/tex_decorated.frag (renamed from sway/desktop/shaders/tex_rgba.frag)32
-rw-r--r--sway/desktop/shaders/tex_external.frag37
-rw-r--r--sway/desktop/shaders/tex_rgbx.frag34
7 files changed, 113 insertions, 99 deletions
diff --git a/include/sway/desktop/fx_renderer.h b/include/sway/desktop/fx_renderer.h
index 8f3aafe2..86cd21a3 100644
--- a/include/sway/desktop/fx_renderer.h
+++ b/include/sway/desktop/fx_renderer.h
@@ -7,6 +7,13 @@
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,
+};
+
struct decoration_data {
float alpha;
float saturation;
diff --git a/sway/desktop/fx_renderer.c b/sway/desktop/fx_renderer.c
index 03645b0f..7ad209d7 100644
--- a/sway/desktop/fx_renderer.c
+++ b/sway/desktop/fx_renderer.c
@@ -25,9 +25,8 @@
#include "quad_round_tr_frag_src.h"
#include "corner_frag_src.h"
#include "box_shadow_frag_src.h"
-#include "tex_rgba_frag_src.h"
-#include "tex_rgbx_frag_src.h"
-#include "tex_external_frag_src.h"
+//#include "tex_frag_src.h"
+#include "tex_decorated_frag_src.h"
static const GLfloat verts[] = {
1, 0, // top right
@@ -101,9 +100,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 *src) {
+static GLuint compile_shader(GLuint type, const GLchar **srcs, size_t srcs_len) {
GLuint shader = glCreateShader(type);
- glShaderSource(shader, 1, &src, NULL);
+ glShaderSource(shader, srcs_len, srcs, NULL);
glCompileShader(shader);
GLint ok;
@@ -117,13 +116,24 @@ static GLuint compile_shader(GLuint type, const GLchar *src) {
return shader;
}
-static GLuint link_program(const GLchar *vert_src, const GLchar *frag_src) {
- GLuint vert = compile_shader(GL_VERTEX_SHADER, vert_src);
+static GLuint link_program(const GLchar *frag_src, enum fx_gles2_shader_source source) {
+ const GLchar *vert_src = common_vert_src;
+ GLuint vert = compile_shader(GL_VERTEX_SHADER, &vert_src, 1);
if (!vert) {
goto error;
}
- GLuint frag = compile_shader(GL_FRAGMENT_SHADER, frag_src);
+ 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);
+ }
if (!frag) {
glDeleteShader(vert);
goto error;
@@ -153,12 +163,16 @@ error:
return 0;
}
-// initializes a provided fragment shader and returns false if unsuccessful
-bool init_frag_shader(struct gles2_tex_shader *shader, GLuint prog) {
- shader->program = prog;
+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_decorated_frag_src;
+
+ shader->program = prog = link_program(frag_src, source);
if (!shader->program) {
return false;
}
+
shader->proj = glGetUniformLocation(prog, "proj");
shader->tex = glGetUniformLocation(prog, "tex");
shader->alpha = glGetUniformLocation(prog, "alpha");
@@ -171,6 +185,7 @@ bool init_frag_shader(struct gles2_tex_shader *shader, GLuint prog) {
shader->radius = glGetUniformLocation(prog, "radius");
shader->saturation = glGetUniformLocation(prog, "saturation");
shader->has_titlebar = glGetUniformLocation(prog, "has_titlebar");
+
return true;
}
@@ -256,7 +271,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
GLuint prog;
// quad fragment shader
- prog = link_program(common_vert_src, quad_frag_src);
+ prog = link_program(quad_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
renderer->shaders.quad.program = prog;
if (!renderer->shaders.quad.program) {
goto error;
@@ -266,21 +281,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(common_vert_src, quad_round_frag_src);
+ prog = link_program(quad_round_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
if (!init_rounded_quad_shader(&renderer->shaders.rounded_quad, prog)) {
goto error;
}
- prog = link_program(common_vert_src, quad_round_tl_frag_src);
+ 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)) {
goto error;
}
- prog = link_program(common_vert_src, quad_round_tr_frag_src);
+ 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)) {
goto error;
}
// Border corner shader
- prog = link_program(common_vert_src, corner_frag_src);
+ prog = link_program(corner_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
renderer->shaders.corner.program = prog;
if (!renderer->shaders.corner.program) {
goto error;
@@ -298,7 +313,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(common_vert_src, box_shadow_frag_src);
+ prog = link_program(box_shadow_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
renderer->shaders.box_shadow.program = prog;
if (!renderer->shaders.box_shadow.program) {
goto error;
@@ -312,19 +327,20 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
renderer->shaders.box_shadow.corner_radius = glGetUniformLocation(prog, "corner_radius");
// fragment shaders
- prog = link_program(common_vert_src, tex_rgba_frag_src);
- if (!init_frag_shader(&renderer->shaders.tex_rgba, prog)) {
+ if (!link_tex_program(renderer, &renderer->shaders.tex_rgba,
+ WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA)) {
goto error;
}
- prog = link_program(common_vert_src, tex_rgbx_frag_src);
- if (!init_frag_shader(&renderer->shaders.tex_rgbx, prog)) {
+ if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx,
+ WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX)) {
goto error;
}
- prog = link_program(common_vert_src, tex_external_frag_src);
- if (!init_frag_shader(&renderer->shaders.tex_ext, prog)) {
+ if (!link_tex_program(renderer, &renderer->shaders.tex_ext,
+ WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL)) {
goto error;
}
+
if (!eglMakeCurrent(wlr_egl_get_display(renderer->egl),
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not unset current EGL");
diff --git a/sway/desktop/shaders/meson.build b/sway/desktop/shaders/meson.build
index ce2439de..ff5e04b2 100644
--- a/sway/desktop/shaders/meson.build
+++ b/sway/desktop/shaders/meson.build
@@ -8,9 +8,7 @@ shaders = [
'quad_round_tr.frag',
'corner.frag',
'box_shadow.frag',
- 'tex_rgba.frag',
- 'tex_rgbx.frag',
- 'tex_external.frag',
+ 'tex_decorated.frag',
]
foreach name : shaders
diff --git a/sway/desktop/shaders/tex.frag b/sway/desktop/shaders/tex.frag
new file mode 100644
index 00000000..3f529137
--- /dev/null
+++ b/sway/desktop/shaders/tex.frag
@@ -0,0 +1,36 @@
+/* enum wlr_gles2_shader_source */
+#define SOURCE_TEXTURE_RGBA 1
+#define SOURCE_TEXTURE_RGBX 2
+#define SOURCE_TEXTURE_EXTERNAL 3
+
+#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;
+#endif
+
+uniform float alpha;
+
+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);
+#endif
+}
+
+void main() {
+ gl_FragColor = sample_texture() * alpha;
+}
diff --git a/sway/desktop/shaders/tex_rgba.frag b/sway/desktop/shaders/tex_decorated.frag
index b46885b2..40320f9b 100644
--- a/sway/desktop/shaders/tex_rgba.frag
+++ b/sway/desktop/shaders/tex_decorated.frag
@@ -1,19 +1,47 @@
+/* enum wlr_gles2_shader_source */
+#define SOURCE_TEXTURE_RGBA 1
+#define SOURCE_TEXTURE_RGBX 2
+#define SOURCE_TEXTURE_EXTERNAL 3
+
+#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;
+#endif
+
uniform float alpha;
uniform float dim;
uniform vec4 dim_color;
-
uniform vec2 size;
uniform vec2 position;
uniform float radius;
uniform bool has_titlebar;
uniform float saturation;
+
const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
+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);
+#endif
+}
+
void main() {
- vec4 color = texture2D(tex, v_texcoord);
+ vec4 color = sample_texture();
// Saturation
if (saturation != 1.0) {
vec4 pixColor = texture2D(tex, v_texcoord);
diff --git a/sway/desktop/shaders/tex_external.frag b/sway/desktop/shaders/tex_external.frag
deleted file mode 100644
index 9976eb51..00000000
--- a/sway/desktop/shaders/tex_external.frag
+++ /dev/null
@@ -1,37 +0,0 @@
-#extension GL_OES_EGL_image_external : require
-
-precision mediump float;
-varying vec2 v_texcoord;
-uniform samplerExternalOES texture0;
-uniform float alpha;
-uniform float dim;
-uniform vec4 dim_color;
-
-uniform vec2 size;
-uniform vec2 position;
-uniform float radius;
-uniform bool has_titlebar;
-uniform float saturation;
-const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
-
-void main() {
- vec4 color = texture2D(texture0, v_texcoord);
- // Saturation
- if (saturation != 1.0) {
- vec4 pixColor = texture2D(texture0, v_texcoord);
- vec3 irgb = pixColor.rgb;
- vec3 target = vec3(dot(irgb, saturation_weight));
- color = vec4(mix(target, irgb, saturation), pixColor.a);
- }
- // Dimming
- gl_FragColor = mix(color, dim_color, dim) * alpha;
-
- if (!has_titlebar || gl_FragCoord.y - position.y > radius) {
- vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy);
- if (max(corner_distance.x, corner_distance.y) < radius) {
- float d = radius - distance(corner_distance, vec2(radius));
- float smooth = smoothstep(-1.0f, 0.5f, d);
- gl_FragColor = mix(vec4(0), gl_FragColor, smooth);
- }
- }
-}
diff --git a/sway/desktop/shaders/tex_rgbx.frag b/sway/desktop/shaders/tex_rgbx.frag
deleted file mode 100644
index 283963f2..00000000
--- a/sway/desktop/shaders/tex_rgbx.frag
+++ /dev/null
@@ -1,34 +0,0 @@
-precision mediump float;
-varying vec2 v_texcoord;
-uniform sampler2D tex;
-uniform float alpha;
-uniform float dim;
-uniform vec4 dim_color;
-
-uniform vec2 size;
-uniform vec2 position;
-uniform float radius;
-uniform bool has_titlebar;
-uniform float saturation;
-const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
-
-void main() {
- vec4 color = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
- // Saturation
- if (saturation != 1.0) {
- vec3 irgb = texture2D(tex, v_texcoord).rgb;
- vec3 target = vec3(dot(irgb, saturation_weight));
- color = vec4(mix(target, irgb, saturation), 1.0);
- }
- // Dimming
- gl_FragColor = mix(color, dim_color, dim) * alpha;
-
- if (!has_titlebar || gl_FragCoord.y - position.y > radius) {
- vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy);
- if (max(corner_distance.x, corner_distance.y) < radius) {
- float d = radius - distance(corner_distance, vec2(radius));
- float smooth = smoothstep(-1.0f, 0.5f, d);
- gl_FragColor = mix(vec4(0), gl_FragColor, smooth);
- }
- }
-}