rebase + removed extra shadow lines from render_view
This commit is contained in:
commit
90a8795492
7 changed files with 355 additions and 256 deletions
|
@ -36,7 +36,70 @@ struct decoration_data {
|
|||
bool shadow;
|
||||
};
|
||||
|
||||
struct gles2_tex_shader {
|
||||
struct blur_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint tex;
|
||||
GLint pos_attrib;
|
||||
GLint tex_attrib;
|
||||
GLint radius;
|
||||
GLint halfpixel;
|
||||
};
|
||||
|
||||
struct box_shadow_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
GLint position;
|
||||
GLint size;
|
||||
GLint blur_sigma;
|
||||
GLint corner_radius;
|
||||
};
|
||||
|
||||
struct corner_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
GLint is_top_left;
|
||||
GLint is_top_right;
|
||||
GLint is_bottom_left;
|
||||
GLint is_bottom_right;
|
||||
GLint position;
|
||||
GLint radius;
|
||||
GLint half_size;
|
||||
GLint half_thickness;
|
||||
};
|
||||
|
||||
struct quad_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
};
|
||||
|
||||
struct rounded_quad_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
GLint size;
|
||||
GLint position;
|
||||
GLint radius;
|
||||
};
|
||||
|
||||
struct stencil_mask_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
GLint half_size;
|
||||
GLint position;
|
||||
GLint radius;
|
||||
};
|
||||
|
||||
struct tex_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint tex;
|
||||
|
@ -52,26 +115,6 @@ struct gles2_tex_shader {
|
|||
GLint has_titlebar;
|
||||
};
|
||||
|
||||
struct rounded_quad_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
GLint size;
|
||||
GLint position;
|
||||
GLint radius;
|
||||
};
|
||||
|
||||
struct blur_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint tex;
|
||||
GLint pos_attrib;
|
||||
GLint tex_attrib;
|
||||
GLint radius;
|
||||
GLint halfpixel;
|
||||
};
|
||||
|
||||
struct fx_renderer {
|
||||
float projection[9];
|
||||
|
||||
|
@ -94,54 +137,21 @@ struct fx_renderer {
|
|||
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
|
||||
} procs;
|
||||
|
||||
|
||||
// Shaders
|
||||
struct {
|
||||
struct {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
} quad;
|
||||
|
||||
struct box_shadow_shader box_shadow;
|
||||
struct blur_shader blur1;
|
||||
struct blur_shader blur2;
|
||||
struct corner_shader corner;
|
||||
struct quad_shader quad;
|
||||
struct rounded_quad_shader rounded_quad;
|
||||
struct rounded_quad_shader rounded_tl_quad;
|
||||
struct rounded_quad_shader rounded_tr_quad;
|
||||
struct rounded_quad_shader rounded_bl_quad;
|
||||
struct rounded_quad_shader rounded_br_quad;
|
||||
|
||||
struct blur_shader blur1;
|
||||
struct blur_shader blur2;
|
||||
|
||||
struct {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
GLint is_top_left;
|
||||
GLint is_top_right;
|
||||
GLint is_bottom_left;
|
||||
GLint is_bottom_right;
|
||||
GLint position;
|
||||
GLint radius;
|
||||
GLint half_size;
|
||||
GLint half_thickness;
|
||||
} corner;
|
||||
|
||||
struct {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint pos_attrib;
|
||||
GLint position;
|
||||
GLint size;
|
||||
GLint blur_sigma;
|
||||
GLint corner_radius;
|
||||
} box_shadow;
|
||||
|
||||
struct gles2_tex_shader tex_rgba;
|
||||
struct gles2_tex_shader tex_rgbx;
|
||||
struct gles2_tex_shader tex_ext;
|
||||
struct stencil_mask_shader stencil_mask;
|
||||
struct tex_shader tex_rgba;
|
||||
struct tex_shader tex_rgbx;
|
||||
struct tex_shader tex_ext;
|
||||
} shaders;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "corner_frag_src.h"
|
||||
#include "quad_frag_src.h"
|
||||
#include "quad_round_frag_src.h"
|
||||
#include "stencil_mask_frag_src.h"
|
||||
#include "tex_frag_src.h"
|
||||
|
||||
static const GLfloat verts[] = {
|
||||
|
@ -87,8 +88,115 @@ error:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool link_tex_program(struct fx_renderer *renderer,
|
||||
struct gles2_tex_shader *shader, enum fx_tex_shader_source source) {
|
||||
static bool link_blur_program(struct blur_shader *shader, const char *shader_program) {
|
||||
GLuint prog;
|
||||
shader->program = prog = link_program(shader_program);
|
||||
if (!shader->program) {
|
||||
return false;
|
||||
}
|
||||
shader->proj = glGetUniformLocation(prog, "proj");
|
||||
shader->tex = glGetUniformLocation(prog, "tex");
|
||||
shader->pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
shader->tex_attrib = glGetAttribLocation(prog, "texcoord");
|
||||
shader->radius = glGetUniformLocation(prog, "radius");
|
||||
shader->halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool link_box_shadow_program(struct box_shadow_shader *shader) {
|
||||
GLuint prog;
|
||||
shader->program = prog = link_program(box_shadow_frag_src);
|
||||
if (!shader->program) {
|
||||
return false;
|
||||
}
|
||||
shader->proj = glGetUniformLocation(prog, "proj");
|
||||
shader->color = glGetUniformLocation(prog, "color");
|
||||
shader->pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
shader->position = glGetUniformLocation(prog, "position");
|
||||
shader->size = glGetUniformLocation(prog, "size");
|
||||
shader->blur_sigma = glGetUniformLocation(prog, "blur_sigma");
|
||||
shader->corner_radius = glGetUniformLocation(prog, "corner_radius");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool link_corner_program(struct corner_shader *shader) {
|
||||
GLuint prog;
|
||||
shader->program = prog = link_program(corner_frag_src);
|
||||
if (!shader->program) {
|
||||
return false;
|
||||
}
|
||||
shader->proj = glGetUniformLocation(prog, "proj");
|
||||
shader->color = glGetUniformLocation(prog, "color");
|
||||
shader->pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
shader->position = glGetUniformLocation(prog, "position");
|
||||
shader->half_size = glGetUniformLocation(prog, "half_size");
|
||||
shader->half_thickness = glGetUniformLocation(prog, "half_thickness");
|
||||
shader->radius = glGetUniformLocation(prog, "radius");
|
||||
shader->is_top_left = glGetUniformLocation(prog, "is_top_left");
|
||||
shader->is_top_right = glGetUniformLocation(prog, "is_top_right");
|
||||
shader->is_bottom_left = glGetUniformLocation(prog, "is_bottom_left");
|
||||
shader->is_bottom_right = glGetUniformLocation(prog, "is_bottom_right");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool link_quad_program(struct quad_shader *shader) {
|
||||
GLuint prog;
|
||||
shader->program = prog = link_program(quad_frag_src);
|
||||
if (!shader->program) {
|
||||
return false;
|
||||
}
|
||||
|
||||
shader->proj = glGetUniformLocation(prog, "proj");
|
||||
shader->color = glGetUniformLocation(prog, "color");
|
||||
shader->pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool link_rounded_quad_program(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;
|
||||
}
|
||||
|
||||
static bool link_stencil_mask_program(struct stencil_mask_shader *shader) {
|
||||
GLuint prog;
|
||||
shader->program = prog = link_program(stencil_mask_frag_src);
|
||||
if (!shader->program) {
|
||||
return false;
|
||||
}
|
||||
|
||||
shader->proj = glGetUniformLocation(prog, "proj");
|
||||
shader->color = glGetUniformLocation(prog, "color");
|
||||
shader->pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
shader->position = glGetUniformLocation(prog, "position");
|
||||
shader->half_size = glGetUniformLocation(prog, "half_size");
|
||||
shader->radius = glGetUniformLocation(prog, "radius");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool link_tex_program(struct 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);
|
||||
|
@ -115,28 +223,6 @@ static bool link_tex_program(struct fx_renderer *renderer,
|
|||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static bool check_gl_ext(const char *exts, const char *ext) {
|
||||
size_t extlen = strlen(ext);
|
||||
const char *end = exts + strlen(exts);
|
||||
|
@ -210,114 +296,61 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
|
|||
"glEGLImageTargetTexture2DOES");
|
||||
}
|
||||
|
||||
// init shaders
|
||||
GLuint prog;
|
||||
|
||||
// quad fragment shader
|
||||
prog = link_program(quad_frag_src);
|
||||
renderer->shaders.quad.program = prog;
|
||||
if (!renderer->shaders.quad.program) {
|
||||
// blur shaders
|
||||
if (!link_blur_program(&renderer->shaders.blur1, blur1_frag_src)) {
|
||||
goto error;
|
||||
}
|
||||
if (!link_blur_program(&renderer->shaders.blur2, blur2_frag_src)) {
|
||||
goto error;
|
||||
}
|
||||
// box shadow shader
|
||||
if (!link_box_shadow_program(&renderer->shaders.box_shadow)) {
|
||||
goto error;
|
||||
}
|
||||
// corner border shader
|
||||
if (!link_corner_program(&renderer->shaders.corner)) {
|
||||
goto error;
|
||||
}
|
||||
// quad fragment shader
|
||||
if (!link_quad_program(&renderer->shaders.quad)) {
|
||||
goto error;
|
||||
}
|
||||
renderer->shaders.quad.proj = glGetUniformLocation(prog, "proj");
|
||||
renderer->shaders.quad.color = glGetUniformLocation(prog, "color");
|
||||
renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
|
||||
// rounded quad fragment shaders
|
||||
if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_quad,
|
||||
if (!link_rounded_quad_program(&renderer->shaders.rounded_quad,
|
||||
SHADER_SOURCE_QUAD_ROUND)) {
|
||||
goto error;
|
||||
}
|
||||
if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_tl_quad,
|
||||
if (!link_rounded_quad_program(&renderer->shaders.rounded_tl_quad,
|
||||
SHADER_SOURCE_QUAD_ROUND_TOP_LEFT)) {
|
||||
goto error;
|
||||
}
|
||||
if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_tr_quad,
|
||||
if (!link_rounded_quad_program(&renderer->shaders.rounded_tr_quad,
|
||||
SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT)) {
|
||||
goto error;
|
||||
}
|
||||
if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_bl_quad,
|
||||
if (!link_rounded_quad_program(&renderer->shaders.rounded_bl_quad,
|
||||
SHADER_SOURCE_QUAD_ROUND_BOTTOM_LEFT)) {
|
||||
goto error;
|
||||
}
|
||||
if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_br_quad,
|
||||
if (!link_rounded_quad_program(&renderer->shaders.rounded_br_quad,
|
||||
SHADER_SOURCE_QUAD_ROUND_BOTTOM_RIGHT)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Border corner shader
|
||||
prog = link_program(corner_frag_src);
|
||||
renderer->shaders.corner.program = prog;
|
||||
if (!renderer->shaders.corner.program) {
|
||||
// stencil mask shader
|
||||
if (!link_stencil_mask_program(&renderer->shaders.stencil_mask)) {
|
||||
goto error;
|
||||
}
|
||||
renderer->shaders.corner.proj = glGetUniformLocation(prog, "proj");
|
||||
renderer->shaders.corner.color = glGetUniformLocation(prog, "color");
|
||||
renderer->shaders.corner.pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
renderer->shaders.corner.is_top_left = glGetUniformLocation(prog, "is_top_left");
|
||||
renderer->shaders.corner.is_top_right = glGetUniformLocation(prog, "is_top_right");
|
||||
renderer->shaders.corner.is_bottom_left = glGetUniformLocation(prog, "is_bottom_left");
|
||||
renderer->shaders.corner.is_bottom_right = glGetUniformLocation(prog, "is_bottom_right");
|
||||
renderer->shaders.corner.position = glGetUniformLocation(prog, "position");
|
||||
renderer->shaders.corner.radius = glGetUniformLocation(prog, "radius");
|
||||
renderer->shaders.corner.half_size = glGetUniformLocation(prog, "half_size");
|
||||
renderer->shaders.corner.half_thickness = glGetUniformLocation(prog, "half_thickness");
|
||||
|
||||
// box shadow shader
|
||||
prog = link_program(box_shadow_frag_src);
|
||||
renderer->shaders.box_shadow.program = prog;
|
||||
if (!renderer->shaders.box_shadow.program) {
|
||||
goto error;
|
||||
}
|
||||
renderer->shaders.box_shadow.proj = glGetUniformLocation(prog, "proj");
|
||||
renderer->shaders.box_shadow.color = glGetUniformLocation(prog, "color");
|
||||
renderer->shaders.box_shadow.pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
renderer->shaders.box_shadow.position = glGetUniformLocation(prog, "position");
|
||||
renderer->shaders.box_shadow.size = glGetUniformLocation(prog, "size");
|
||||
renderer->shaders.box_shadow.blur_sigma = glGetUniformLocation(prog, "blur_sigma");
|
||||
renderer->shaders.box_shadow.corner_radius = glGetUniformLocation(prog, "corner_radius");
|
||||
|
||||
// Blur 1
|
||||
prog = link_program(blur1_frag_src);
|
||||
renderer->shaders.blur1.program = prog;
|
||||
if (!renderer->shaders.blur1.program) {
|
||||
goto error;
|
||||
}
|
||||
renderer->shaders.blur1.proj = glGetUniformLocation(prog, "proj");
|
||||
renderer->shaders.blur1.tex = glGetUniformLocation(prog, "tex");
|
||||
renderer->shaders.blur1.pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
renderer->shaders.blur1.tex_attrib = glGetAttribLocation(prog, "texcoord");
|
||||
renderer->shaders.blur1.radius = glGetUniformLocation(prog, "radius");
|
||||
renderer->shaders.blur1.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
|
||||
// Blur 2
|
||||
prog = link_program(blur2_frag_src);
|
||||
renderer->shaders.blur2.program = prog;
|
||||
if (!renderer->shaders.blur2.program) {
|
||||
goto error;
|
||||
}
|
||||
renderer->shaders.blur2.proj = glGetUniformLocation(prog, "proj");
|
||||
renderer->shaders.blur2.tex = glGetUniformLocation(prog, "tex");
|
||||
renderer->shaders.blur2.pos_attrib = glGetAttribLocation(prog, "pos");
|
||||
renderer->shaders.blur2.tex_attrib = glGetAttribLocation(prog, "texcoord");
|
||||
renderer->shaders.blur2.radius = glGetUniformLocation(prog, "radius");
|
||||
renderer->shaders.blur2.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
|
||||
// fragment shaders
|
||||
if (!link_tex_program(renderer, &renderer->shaders.tex_rgba,
|
||||
SHADER_SOURCE_TEXTURE_RGBA)) {
|
||||
if (!link_tex_program(&renderer->shaders.tex_rgba, SHADER_SOURCE_TEXTURE_RGBA)) {
|
||||
goto error;
|
||||
}
|
||||
if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx,
|
||||
SHADER_SOURCE_TEXTURE_RGBX)) {
|
||||
if (!link_tex_program(&renderer->shaders.tex_rgbx, SHADER_SOURCE_TEXTURE_RGBX)) {
|
||||
goto error;
|
||||
}
|
||||
if (!link_tex_program(renderer, &renderer->shaders.tex_ext,
|
||||
SHADER_SOURCE_TEXTURE_EXTERNAL)) {
|
||||
if (!link_tex_program(&renderer->shaders.tex_ext, SHADER_SOURCE_TEXTURE_EXTERNAL)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
if (!eglMakeCurrent(wlr_egl_get_display(egl),
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
|
||||
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not unset current EGL");
|
||||
|
@ -328,16 +361,17 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
|
|||
return renderer;
|
||||
|
||||
error:
|
||||
glDeleteProgram(renderer->shaders.quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_tl_quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_tr_quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_bl_quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_br_quad.program);
|
||||
glDeleteProgram(renderer->shaders.corner.program);
|
||||
glDeleteProgram(renderer->shaders.box_shadow.program);
|
||||
glDeleteProgram(renderer->shaders.blur1.program);
|
||||
glDeleteProgram(renderer->shaders.blur2.program);
|
||||
glDeleteProgram(renderer->shaders.box_shadow.program);
|
||||
glDeleteProgram(renderer->shaders.corner.program);
|
||||
glDeleteProgram(renderer->shaders.quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_bl_quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_br_quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_tl_quad.program);
|
||||
glDeleteProgram(renderer->shaders.rounded_tr_quad.program);
|
||||
glDeleteProgram(renderer->shaders.stencil_mask.program);
|
||||
glDeleteProgram(renderer->shaders.tex_rgba.program);
|
||||
glDeleteProgram(renderer->shaders.tex_rgbx.program);
|
||||
glDeleteProgram(renderer->shaders.tex_ext.program);
|
||||
|
@ -414,7 +448,7 @@ bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct fx_te
|
|||
const struct wlr_fbox *src_box, const struct wlr_box *dst_box, const float matrix[static 9],
|
||||
struct decoration_data deco_data) {
|
||||
|
||||
struct gles2_tex_shader *shader = NULL;
|
||||
struct tex_shader *shader = NULL;
|
||||
|
||||
switch (fx_texture->target) {
|
||||
case GL_TEXTURE_2D:
|
||||
|
@ -537,19 +571,20 @@ void fx_render_rect(struct fx_renderer *renderer, const struct wlr_box *box,
|
|||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
glUseProgram(renderer->shaders.quad.program);
|
||||
struct quad_shader shader = renderer->shaders.quad;
|
||||
glUseProgram(shader.program);
|
||||
|
||||
glUniformMatrix3fv(renderer->shaders.quad.proj, 1, GL_FALSE, gl_matrix);
|
||||
glUniform4f(renderer->shaders.quad.color, color[0], color[1], color[2], color[3]);
|
||||
glUniformMatrix3fv(shader.proj, 1, GL_FALSE, gl_matrix);
|
||||
glUniform4f(shader.color, color[0], color[1], color[2], color[3]);
|
||||
|
||||
glVertexAttribPointer(renderer->shaders.quad.pos_attrib, 2, GL_FLOAT, GL_FALSE,
|
||||
glVertexAttribPointer(shader.pos_attrib, 2, GL_FLOAT, GL_FALSE,
|
||||
0, verts);
|
||||
|
||||
glEnableVertexAttribArray(renderer->shaders.quad.pos_attrib);
|
||||
glEnableVertexAttribArray(shader.pos_attrib);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(renderer->shaders.quad.pos_attrib);
|
||||
glDisableVertexAttribArray(shader.pos_attrib);
|
||||
}
|
||||
|
||||
void fx_render_rounded_rect(struct fx_renderer *renderer, const struct wlr_box *box,
|
||||
|
@ -635,34 +670,75 @@ void fx_render_border_corner(struct fx_renderer *renderer, const struct wlr_box
|
|||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
glUseProgram(renderer->shaders.corner.program);
|
||||
struct corner_shader shader = renderer->shaders.corner;
|
||||
|
||||
glUniformMatrix3fv(renderer->shaders.corner.proj, 1, GL_FALSE, gl_matrix);
|
||||
glUniform4f(renderer->shaders.corner.color, color[0], color[1], color[2], color[3]);
|
||||
glUseProgram(shader.program);
|
||||
|
||||
glUniform1f(renderer->shaders.corner.is_top_left, corner_location == TOP_LEFT);
|
||||
glUniform1f(renderer->shaders.corner.is_top_right, corner_location == TOP_RIGHT);
|
||||
glUniform1f(renderer->shaders.corner.is_bottom_left, corner_location == BOTTOM_LEFT);
|
||||
glUniform1f(renderer->shaders.corner.is_bottom_right, corner_location == BOTTOM_RIGHT);
|
||||
glUniformMatrix3fv(shader.proj, 1, GL_FALSE, gl_matrix);
|
||||
glUniform4f(shader.color, color[0], color[1], color[2], color[3]);
|
||||
|
||||
glUniform2f(renderer->shaders.corner.position, box->x, box->y);
|
||||
glUniform1f(renderer->shaders.corner.radius, radius);
|
||||
glUniform2f(renderer->shaders.corner.half_size, box->width / 2.0, box->height / 2.0);
|
||||
glUniform1f(renderer->shaders.corner.half_thickness, border_thickness / 2.0);
|
||||
glUniform1f(shader.is_top_left, corner_location == TOP_LEFT);
|
||||
glUniform1f(shader.is_top_right, corner_location == TOP_RIGHT);
|
||||
glUniform1f(shader.is_bottom_left, corner_location == BOTTOM_LEFT);
|
||||
glUniform1f(shader.is_bottom_right, corner_location == BOTTOM_RIGHT);
|
||||
|
||||
glVertexAttribPointer(renderer->shaders.corner.pos_attrib, 2, GL_FLOAT, GL_FALSE,
|
||||
glUniform2f(shader.position, box->x, box->y);
|
||||
glUniform1f(shader.radius, radius);
|
||||
glUniform2f(shader.half_size, box->width / 2.0, box->height / 2.0);
|
||||
glUniform1f(shader.half_thickness, border_thickness / 2.0);
|
||||
|
||||
glVertexAttribPointer(shader.pos_attrib, 2, GL_FLOAT, GL_FALSE,
|
||||
0, verts);
|
||||
|
||||
glEnableVertexAttribArray(renderer->shaders.corner.pos_attrib);
|
||||
glEnableVertexAttribArray(shader.pos_attrib);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(renderer->shaders.corner.pos_attrib);
|
||||
glDisableVertexAttribArray(shader.pos_attrib);
|
||||
}
|
||||
|
||||
void fx_render_stencil_mask(struct fx_renderer *renderer, const struct wlr_box *box,
|
||||
const float matrix[static 9], int corner_radius) {
|
||||
if (box->width == 0 || box->height == 0) {
|
||||
return;
|
||||
}
|
||||
assert(box->width > 0 && box->height > 0);
|
||||
|
||||
// TODO: just pass gl_matrix?
|
||||
float gl_matrix[9];
|
||||
wlr_matrix_multiply(gl_matrix, renderer->projection, matrix);
|
||||
|
||||
// TODO: investigate why matrix is flipped prior to this cmd
|
||||
// wlr_matrix_multiply(gl_matrix, flip_180, gl_matrix);
|
||||
|
||||
wlr_matrix_transpose(gl_matrix, gl_matrix);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
struct stencil_mask_shader shader = renderer->shaders.stencil_mask;
|
||||
|
||||
glUseProgram(shader.program);
|
||||
|
||||
glUniformMatrix3fv(shader.proj, 1, GL_FALSE, gl_matrix);
|
||||
|
||||
glUniform2f(shader.half_size, box->width * 0.5, box->height * 0.5);
|
||||
glUniform2f(shader.position, box->x, box->y);
|
||||
glUniform1f(shader.radius, corner_radius);
|
||||
|
||||
glVertexAttribPointer(shader.pos_attrib, 2, GL_FLOAT, GL_FALSE,
|
||||
0, verts);
|
||||
|
||||
glEnableVertexAttribArray(shader.pos_attrib);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(shader.pos_attrib);
|
||||
|
||||
}
|
||||
|
||||
// TODO: alpha input arg?
|
||||
void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *box,
|
||||
const float color[static 4], const float matrix [static 9], int corner_radius,
|
||||
const float color[static 4], const float matrix[static 9], int corner_radius,
|
||||
float blur_sigma) {
|
||||
if (box->width == 0 || box->height == 0) {
|
||||
return;
|
||||
|
@ -678,8 +754,6 @@ void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *bo
|
|||
wlr_matrix_transpose(gl_matrix, gl_matrix);
|
||||
|
||||
// Init stencil work
|
||||
// NOTE: Alpha needs to be set to 1.0 to be able to discard any "empty" pixels
|
||||
const float col[4] = {0.0, 0.0, 0.0, 1.0};
|
||||
struct wlr_box inner_box;
|
||||
memcpy(&inner_box, box, sizeof(struct wlr_box));
|
||||
inner_box.x += blur_sigma;
|
||||
|
@ -696,7 +770,7 @@ void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *bo
|
|||
// Disable writing to color buffer
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
// Draw the rounded rect as a mask
|
||||
fx_render_rounded_rect(renderer, &inner_box, col, matrix, corner_radius, ALL);
|
||||
fx_render_stencil_mask(renderer, &inner_box, matrix, corner_radius);
|
||||
// Close the mask
|
||||
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
@ -709,24 +783,26 @@ void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *bo
|
|||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glUseProgram(renderer->shaders.box_shadow.program);
|
||||
struct box_shadow_shader shader = renderer->shaders.box_shadow;
|
||||
|
||||
glUniformMatrix3fv(renderer->shaders.box_shadow.proj, 1, GL_FALSE, gl_matrix);
|
||||
glUniform4f(renderer->shaders.box_shadow.color, color[0], color[1], color[2], color[3]);
|
||||
glUniform1f(renderer->shaders.box_shadow.blur_sigma, blur_sigma);
|
||||
glUniform1f(renderer->shaders.box_shadow.corner_radius, corner_radius);
|
||||
glUseProgram(shader.program);
|
||||
|
||||
glUniform2f(renderer->shaders.box_shadow.size, box->width, box->height);
|
||||
glUniform2f(renderer->shaders.box_shadow.position, box->x, box->y);
|
||||
glUniformMatrix3fv(shader.proj, 1, GL_FALSE, gl_matrix);
|
||||
glUniform4f(shader.color, color[0], color[1], color[2], color[3]);
|
||||
glUniform1f(shader.blur_sigma, blur_sigma);
|
||||
glUniform1f(shader.corner_radius, corner_radius);
|
||||
|
||||
glVertexAttribPointer(renderer->shaders.box_shadow.pos_attrib, 2, GL_FLOAT, GL_FALSE,
|
||||
glUniform2f(shader.size, box->width, box->height);
|
||||
glUniform2f(shader.position, box->x, box->y);
|
||||
|
||||
glVertexAttribPointer(shader.pos_attrib, 2, GL_FLOAT, GL_FALSE,
|
||||
0, verts);
|
||||
|
||||
glEnableVertexAttribArray(renderer->shaders.box_shadow.pos_attrib);
|
||||
glEnableVertexAttribArray(shader.pos_attrib);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(renderer->shaders.box_shadow.pos_attrib);
|
||||
glDisableVertexAttribArray(shader.pos_attrib);
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ shaders = [
|
|||
'corner.frag',
|
||||
'quad.frag',
|
||||
'quad_round.frag',
|
||||
'stencil_mask.frag',
|
||||
'tex.frag',
|
||||
]
|
||||
|
||||
|
|
|
@ -36,8 +36,4 @@ void main() {
|
|||
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);
|
||||
|
||||
if (gl_FragColor.a == 0.0) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
|
17
sway/desktop/fx_renderer/shaders/stencil_mask.frag
Normal file
17
sway/desktop/fx_renderer/shaders/stencil_mask.frag
Normal file
|
@ -0,0 +1,17 @@
|
|||
precision mediump float;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
uniform vec2 half_size;
|
||||
uniform vec2 position;
|
||||
uniform float radius;
|
||||
|
||||
void main() {
|
||||
vec2 q = abs(gl_FragCoord.xy - position - half_size) - half_size + radius;
|
||||
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.0), vec4(1.0), smoothedAlpha);
|
||||
|
||||
if (gl_FragColor.a < 1.0) {
|
||||
discard;
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include "log.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/desktop/transaction.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
|
|
|
@ -306,7 +306,7 @@ void render_blur(bool optimized, struct sway_output *output,
|
|||
pixman_region32_t *output_damage, const struct wlr_fbox *src_box,
|
||||
const struct wlr_box *dst_box, pixman_region32_t *opaque_region,
|
||||
int surface_width, int surface_height, int32_t surface_scale,
|
||||
int corner_radius) {
|
||||
int corner_radius, bool should_round_top) {
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct fx_renderer *renderer = output->renderer;
|
||||
|
||||
|
@ -363,6 +363,7 @@ void render_blur(bool optimized, struct sway_output *output,
|
|||
|
||||
struct decoration_data deco_data = get_undecorated_decoration_data();
|
||||
deco_data.corner_radius = corner_radius;
|
||||
deco_data.has_titlebar = should_round_top;
|
||||
render_texture(wlr_output, &damage, &buffer->texture, src_box, dst_box, matrix, deco_data);
|
||||
|
||||
damage_finish:
|
||||
|
@ -487,7 +488,8 @@ static void render_surface_iterator(struct sway_output *output,
|
|||
wlr_output_transform_invert(wlr_output->transform), monitor_box.width, monitor_box.height);
|
||||
struct wlr_fbox blur_src_box = wlr_fbox_from_wlr_box(&monitor_box);
|
||||
render_blur(should_optimize_blur, output, output_damage, &blur_src_box, &dst_box, &opaque_region,
|
||||
surface->current.width, surface->current.height, surface->current.scale, deco_data.corner_radius);
|
||||
surface->current.width, surface->current.height, surface->current.scale,
|
||||
deco_data.corner_radius, deco_data.has_titlebar);
|
||||
}
|
||||
|
||||
pixman_region32_fini(&opaque_region);
|
||||
|
@ -863,7 +865,7 @@ static void render_saved_view(struct sway_view *view, struct sway_output *output
|
|||
struct wlr_fbox src_box = wlr_fbox_from_wlr_box(&monitor_box);
|
||||
bool should_optimize_blur = !container_is_floating(con);
|
||||
render_blur(should_optimize_blur, output, damage, &src_box, &dst_box, &opaque_region,
|
||||
saved_buf->width, saved_buf->height, 1, deco_data.corner_radius);
|
||||
saved_buf->width, saved_buf->height, 1, deco_data.corner_radius, deco_data.has_titlebar);
|
||||
|
||||
pixman_region32_fini(&opaque_region);
|
||||
}
|
||||
|
@ -905,18 +907,12 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
|
|||
render_view_toplevels(view, output, damage, deco_data);
|
||||
}
|
||||
|
||||
// Only draw shadows on CSD windows if shadows_on_csd is enabled
|
||||
if (state->border == B_CSD && !config->shadows_on_csd_enabled) {
|
||||
if (state->border == B_NONE || state->border == B_CSD) {
|
||||
return;
|
||||
}
|
||||
|
||||
float output_scale = output->wlr_output->scale;
|
||||
struct wlr_box box;
|
||||
|
||||
if (state->border == B_NONE || state->border == B_CSD) {
|
||||
return;
|
||||
}
|
||||
|
||||
float color[4];
|
||||
|
||||
if (state->border_left) {
|
||||
|
@ -1449,9 +1445,6 @@ static void render_containers_linear(struct sway_output *output,
|
|||
}
|
||||
|
||||
bool has_titlebar = state->border == B_NORMAL;
|
||||
int corner_radius = config->smart_corner_radius &&
|
||||
output->current.active_workspace->current_gaps.top == 0
|
||||
? 0 : child->corner_radius;
|
||||
|
||||
struct decoration_data deco_data = {
|
||||
.alpha = child->alpha,
|
||||
|
@ -1460,7 +1453,9 @@ static void render_containers_linear(struct sway_output *output,
|
|||
: config->dim_inactive_colors.unfocused,
|
||||
.dim = child->current.focused || parent->focused ? 0.0f : child->dim,
|
||||
// no corner radius if no gaps (allows smart_gaps to work as expected)
|
||||
.corner_radius = corner_radius,
|
||||
.corner_radius = config->smart_corner_radius &&
|
||||
output->current.active_workspace->current_gaps.top == 0
|
||||
? 0 : child->corner_radius,
|
||||
.saturation = child->saturation,
|
||||
.has_titlebar = has_titlebar,
|
||||
.blur = child->blur_enabled,
|
||||
|
@ -1501,6 +1496,21 @@ static void render_containers_tabbed(struct sway_output *output,
|
|||
struct border_colors *current_colors = &config->border_colors.unfocused;
|
||||
int tab_width = parent->box.width / parent->children->length;
|
||||
|
||||
struct decoration_data deco_data = {
|
||||
.alpha = current->alpha,
|
||||
.dim_color = view_is_urgent(current->view)
|
||||
? config->dim_inactive_colors.urgent
|
||||
: config->dim_inactive_colors.unfocused,
|
||||
.dim = current->current.focused || parent->focused ? 0.0f : current->dim,
|
||||
// no corner radius if no gaps (allows smart_gaps to work as expected)
|
||||
.corner_radius = config->smart_corner_radius &&
|
||||
output->current.active_workspace->current_gaps.top == 0
|
||||
? 0 : current->corner_radius,
|
||||
.saturation = current->saturation,
|
||||
.has_titlebar = true,
|
||||
.blur = current->blur_enabled,
|
||||
};
|
||||
|
||||
// Render tabs
|
||||
for (int i = 0; i < parent->children->length; ++i) {
|
||||
struct sway_container *child = parent->children->items[i];
|
||||
|
@ -1554,7 +1564,7 @@ static void render_containers_tabbed(struct sway_output *output,
|
|||
}
|
||||
|
||||
render_titlebar(output, damage, child, x, parent->box.y, tab_width, colors,
|
||||
child->alpha, child->corner_radius, corner_location, title_texture, marks_texture);
|
||||
deco_data.alpha, deco_data.corner_radius, corner_location, title_texture, marks_texture);
|
||||
|
||||
if (child == current) {
|
||||
current_colors = colors;
|
||||
|
@ -1563,18 +1573,6 @@ static void render_containers_tabbed(struct sway_output *output,
|
|||
|
||||
// Render surface and left/right/bottom borders
|
||||
if (current->view) {
|
||||
struct decoration_data deco_data = {
|
||||
.alpha = current->alpha,
|
||||
.dim_color = view_is_urgent(current->view)
|
||||
? config->dim_inactive_colors.urgent
|
||||
: config->dim_inactive_colors.unfocused,
|
||||
.dim = current->current.focused || parent->focused ? 0.0f : current->dim,
|
||||
.corner_radius = current->corner_radius,
|
||||
.saturation = current->saturation,
|
||||
.has_titlebar = true,
|
||||
.blur = current->blur_enabled,
|
||||
.shadow = current->shadow_enabled,
|
||||
};
|
||||
render_view(output, damage, current, current_colors, deco_data);
|
||||
} else {
|
||||
render_container(output, damage, current,
|
||||
|
@ -1594,6 +1592,20 @@ static void render_containers_stacked(struct sway_output *output,
|
|||
struct border_colors *current_colors = &config->border_colors.unfocused;
|
||||
size_t titlebar_height = container_titlebar_height();
|
||||
|
||||
struct decoration_data deco_data = {
|
||||
.alpha = current->alpha,
|
||||
.dim_color = view_is_urgent(current->view)
|
||||
? config->dim_inactive_colors.urgent
|
||||
: config->dim_inactive_colors.unfocused,
|
||||
.dim = current->current.focused || parent->focused ? 0.0f : current->dim,
|
||||
.saturation = current->saturation,
|
||||
.corner_radius = config->smart_corner_radius &&
|
||||
output->current.active_workspace->current_gaps.top == 0
|
||||
? 0 : current->corner_radius,
|
||||
.has_titlebar = true,
|
||||
.blur = current->blur_enabled,
|
||||
};
|
||||
|
||||
// Render titles
|
||||
for (int i = 0; i < parent->children->length; ++i) {
|
||||
struct sway_container *child = parent->children->items[i];
|
||||
|
@ -1628,9 +1640,9 @@ static void render_containers_stacked(struct sway_output *output,
|
|||
}
|
||||
|
||||
int y = parent->box.y + titlebar_height * i;
|
||||
int corner_radius = i != 0 ? 0 : child->corner_radius;
|
||||
int corner_radius = i != 0 ? 0 : deco_data.corner_radius;
|
||||
render_titlebar(output, damage, child, parent->box.x, y, parent->box.width,
|
||||
colors, child->alpha, corner_radius, ALL, title_texture, marks_texture);
|
||||
colors, deco_data.alpha, corner_radius, ALL, title_texture, marks_texture);
|
||||
|
||||
if (child == current) {
|
||||
current_colors = colors;
|
||||
|
@ -1639,18 +1651,6 @@ static void render_containers_stacked(struct sway_output *output,
|
|||
|
||||
// Render surface and left/right/bottom borders
|
||||
if (current->view) {
|
||||
struct decoration_data deco_data = {
|
||||
.alpha = current->alpha,
|
||||
.dim_color = view_is_urgent(current->view)
|
||||
? config->dim_inactive_colors.urgent
|
||||
: config->dim_inactive_colors.unfocused,
|
||||
.dim = current->current.focused || parent->focused ? 0.0f : current->dim,
|
||||
.saturation = current->saturation,
|
||||
.corner_radius = current->corner_radius,
|
||||
.has_titlebar = true,
|
||||
.blur = current->blur_enabled,
|
||||
.shadow = current->shadow_enabled,
|
||||
};
|
||||
render_view(output, damage, current, current_colors, deco_data);
|
||||
} else {
|
||||
render_container(output, damage, current,
|
||||
|
|
Loading…
Add table
Reference in a new issue