1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2024-11-11 13:51:02 -05:00

backend: gl: do not use larger-than-screen textures for blur buffers

Blur-texture sampling has been changed to `CLAMP_TO_EDGE` in commit
4b0ff37b36 and to using the buffer
textures at screen position instead of texture origin in commit
89c18afac6.

When using the above approach, expanding the buffer textures by the same
amount as the damage region is not needed anymore, as we cannot render
more than the screen region anyways. Having larger-than-screen buffer
textures might lead to a slight darkening at the upper and right edges
since we don't necessarily trigger the `CLAMP_TO_EDGE` condition in the
intermediate steps. This becomes apparent when using dual-kawase at large
blur-strengths with light backgrounds.

These changes do not affect the general approach of rendering a
larger-than-window region with the blur to accommodate the necessary
increase in damage region.

Related: 6d646b543f
This commit is contained in:
Bernd Busse 2021-08-16 17:17:36 +02:00
parent 78e8666498
commit 1dbffec3ae
No known key found for this signature in database
GPG key ID: 6DD2A3C48E63A5AB
2 changed files with 9 additions and 45 deletions

View file

@ -556,8 +556,7 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
auto bctx = (struct gl_blur_context *)ctx; auto bctx = (struct gl_blur_context *)ctx;
auto gd = (struct gl_data *)base; auto gd = (struct gl_data *)base;
int dst_y_screen_coord = gd->height - extent->y2, int dst_y_fb_coord = bctx->fb_height - extent->y2;
dst_y_fb_coord = bctx->fb_height - extent->y2;
int curr = 0; int curr = 0;
for (int i = 0; i < bctx->npasses; ++i) { for (int i = 0; i < bctx->npasses; ++i) {
@ -567,19 +566,15 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
assert(bctx->blur_textures[curr]); assert(bctx->blur_textures[curr]);
// The origin to use when sampling from the source texture // The origin to use when sampling from the source texture
GLint texorig_x, texorig_y; GLint texorig_x = extent->x1, texorig_y = dst_y_fb_coord;
GLint tex_width, tex_height; GLint tex_width, tex_height;
GLuint src_texture; GLuint src_texture;
if (i == 0) { if (i == 0) {
texorig_x = extent->x1;
texorig_y = dst_y_screen_coord;
src_texture = gd->back_texture; src_texture = gd->back_texture;
tex_width = gd->width; tex_width = gd->width;
tex_height = gd->height; tex_height = gd->height;
} else { } else {
texorig_x = extent->x1 + bctx->resize_width;
texorig_y = dst_y_fb_coord - bctx->resize_height;
src_texture = bctx->blur_textures[curr]; src_texture = bctx->blur_textures[curr];
auto src_size = bctx->texture_sizes[curr]; auto src_size = bctx->texture_sizes[curr];
tex_width = src_size.width; tex_width = src_size.width;
@ -611,8 +606,6 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
} }
glUniform1f(p->unifm_opacity, 1.0); glUniform1f(p->unifm_opacity, 1.0);
glUniform2f(p->orig_loc, (GLfloat)bctx->resize_width,
-(GLfloat)bctx->resize_height);
} else { } else {
// last pass, draw directly into the back buffer, with origin // last pass, draw directly into the back buffer, with origin
// regions // regions
@ -621,7 +614,6 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
glBindFramebuffer(GL_FRAMEBUFFER, gd->back_fbo); glBindFramebuffer(GL_FRAMEBUFFER, gd->back_fbo);
glUniform1f(p->unifm_opacity, (float)opacity); glUniform1f(p->unifm_opacity, (float)opacity);
glUniform2f(p->orig_loc, 0, 0);
} }
glUniform2f(p->texorig_loc, (GLfloat)texorig_x, (GLfloat)texorig_y); glUniform2f(p->texorig_loc, (GLfloat)texorig_x, (GLfloat)texorig_y);
@ -641,8 +633,7 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
auto bctx = (struct gl_blur_context *)ctx; auto bctx = (struct gl_blur_context *)ctx;
auto gd = (struct gl_data *)base; auto gd = (struct gl_data *)base;
int dst_y_screen_coord = gd->height - extent->y2, int dst_y_fb_coord = bctx->fb_height - extent->y2;
dst_y_fb_coord = bctx->fb_height - extent->y2;
int iterations = bctx->blur_texture_count; int iterations = bctx->blur_texture_count;
int scale_factor = 1; int scale_factor = 1;
@ -652,9 +643,7 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
assert(down_pass->prog); assert(down_pass->prog);
glUseProgram(down_pass->prog); glUseProgram(down_pass->prog);
// Downsample always renders with resize offset glUniform2f(down_pass->texorig_loc, (GLfloat)extent->x1, (GLfloat)dst_y_fb_coord);
glUniform2f(down_pass->orig_loc, (GLfloat)bctx->resize_width,
-(GLfloat)bctx->resize_height);
for (int i = 0; i < iterations; ++i) { for (int i = 0; i < iterations; ++i) {
// Scale output width / height by half in each iteration // Scale output width / height by half in each iteration
@ -662,25 +651,18 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
GLuint src_texture; GLuint src_texture;
int tex_width, tex_height; int tex_width, tex_height;
int texorig_x, texorig_y;
if (i == 0) { if (i == 0) {
// first pass: copy from back buffer // first pass: copy from back buffer
src_texture = gd->back_texture; src_texture = gd->back_texture;
tex_width = gd->width; tex_width = gd->width;
tex_height = gd->height; tex_height = gd->height;
texorig_x = extent->x1;
texorig_y = dst_y_screen_coord;
} else { } else {
// copy from previous pass // copy from previous pass
src_texture = bctx->blur_textures[i - 1]; src_texture = bctx->blur_textures[i - 1];
auto src_size = bctx->texture_sizes[i - 1]; auto src_size = bctx->texture_sizes[i - 1];
tex_width = src_size.width; tex_width = src_size.width;
tex_height = src_size.height; tex_height = src_size.height;
texorig_x = extent->x1 + bctx->resize_width;
texorig_y = dst_y_fb_coord - bctx->resize_height;
} }
assert(src_texture); assert(src_texture);
@ -692,7 +674,6 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bctx->blur_fbos[i]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bctx->blur_fbos[i]);
glDrawBuffer(GL_COLOR_ATTACHMENT0); glDrawBuffer(GL_COLOR_ATTACHMENT0);
glUniform2f(down_pass->texorig_loc, (GLfloat)texorig_x, (GLfloat)texorig_y);
glUniform1f(down_pass->scale_loc, (GLfloat)scale_factor); glUniform1f(down_pass->scale_loc, (GLfloat)scale_factor);
glUniform2f(down_pass->unifm_pixel_norm, 1.0f / (GLfloat)tex_width, glUniform2f(down_pass->unifm_pixel_norm, 1.0f / (GLfloat)tex_width,
@ -706,9 +687,7 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
assert(up_pass->prog); assert(up_pass->prog);
glUseProgram(up_pass->prog); glUseProgram(up_pass->prog);
// Upsample always samples from textures with resize offset glUniform2f(up_pass->texorig_loc, (GLfloat)extent->x1, (GLfloat)dst_y_fb_coord);
glUniform2f(up_pass->texorig_loc, (GLfloat)(extent->x1 + bctx->resize_width),
(GLfloat)(dst_y_fb_coord - bctx->resize_height));
for (int i = iterations - 1; i >= 0; --i) { for (int i = iterations - 1; i >= 0; --i) {
// Scale output width / height back by two in each iteration // Scale output width / height back by two in each iteration
@ -735,8 +714,6 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bctx->blur_fbos[i - 1]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bctx->blur_fbos[i - 1]);
glDrawBuffer(GL_COLOR_ATTACHMENT0); glDrawBuffer(GL_COLOR_ATTACHMENT0);
glUniform2f(up_pass->orig_loc, (GLfloat)bctx->resize_width,
-(GLfloat)bctx->resize_height);
glUniform1f(up_pass->unifm_opacity, (GLfloat)1); glUniform1f(up_pass->unifm_opacity, (GLfloat)1);
} else { } else {
// last pass, draw directly into the back buffer // last pass, draw directly into the back buffer
@ -744,7 +721,6 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
nelems = vao_nelems[0]; nelems = vao_nelems[0];
glBindFramebuffer(GL_FRAMEBUFFER, gd->back_fbo); glBindFramebuffer(GL_FRAMEBUFFER, gd->back_fbo);
glUniform2f(up_pass->orig_loc, (GLfloat)0, (GLfloat)0);
glUniform1f(up_pass->unifm_opacity, (GLfloat)opacity); glUniform1f(up_pass->unifm_opacity, (GLfloat)opacity);
} }
@ -765,12 +741,11 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, const region_t *reg_blu
bool ret = false; bool ret = false;
if (gd->width + bctx->resize_width * 2 != bctx->fb_width || if (gd->width != bctx->fb_width || gd->height != bctx->fb_height) {
gd->height + bctx->resize_height * 2 != bctx->fb_height) {
// Resize the temporary textures used for blur in case the root // Resize the temporary textures used for blur in case the root
// size changed // size changed
bctx->fb_width = gd->width + bctx->resize_width * 2; bctx->fb_width = gd->width;
bctx->fb_height = gd->height + bctx->resize_height * 2; bctx->fb_height = gd->height;
for (int i = 0; i < bctx->blur_texture_count; ++i) { for (int i = 0; i < bctx->blur_texture_count; ++i) {
auto tex_size = bctx->texture_sizes + i; auto tex_size = bctx->texture_sizes + i;
@ -894,13 +869,12 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, const region_t *reg_blu
const char *vertex_shader = GLSL(330, const char *vertex_shader = GLSL(330,
uniform mat4 projection; uniform mat4 projection;
uniform float scale = 1.0; uniform float scale = 1.0;
uniform vec2 orig;
uniform vec2 texorig; uniform vec2 texorig;
layout(location = 0) in vec2 coord; layout(location = 0) in vec2 coord;
layout(location = 1) in vec2 in_texcoord; layout(location = 1) in vec2 in_texcoord;
out vec2 texcoord; out vec2 texcoord;
void main() { void main() {
gl_Position = projection * vec4(coord + orig, 0, scale); gl_Position = projection * vec4(coord, 0, scale);
texcoord = in_texcoord + texorig; texcoord = in_texcoord + texorig;
} }
); );
@ -927,10 +901,6 @@ static int gl_win_shader_from_string(const char *vshader_str, const char *fshade
ret->unifm_max_brightness = ret->unifm_max_brightness =
glGetUniformLocationChecked(ret->prog, "max_brightness"); glGetUniformLocationChecked(ret->prog, "max_brightness");
glUseProgram(ret->prog);
int orig_loc = glGetUniformLocation(ret->prog, "orig");
glUniform2f(orig_loc, 0, 0);
gl_check_err(); gl_check_err();
return true; return true;
@ -1279,7 +1249,6 @@ bool gl_create_kernel_blur_context(void *blur_context, GLfloat *projection,
pass->unifm_pixel_norm = pass->unifm_pixel_norm =
glGetUniformLocationChecked(pass->prog, "pixel_norm"); glGetUniformLocationChecked(pass->prog, "pixel_norm");
pass->unifm_opacity = glGetUniformLocationChecked(pass->prog, "opacity"); pass->unifm_opacity = glGetUniformLocationChecked(pass->prog, "opacity");
pass->orig_loc = glGetUniformLocationChecked(pass->prog, "orig");
pass->texorig_loc = glGetUniformLocationChecked(pass->prog, "texorig"); pass->texorig_loc = glGetUniformLocationChecked(pass->prog, "texorig");
// Setup projection matrix // Setup projection matrix
@ -1299,7 +1268,6 @@ bool gl_create_kernel_blur_context(void *blur_context, GLfloat *projection,
pass->prog = gl_create_program_from_str(vertex_shader, dummy_frag); pass->prog = gl_create_program_from_str(vertex_shader, dummy_frag);
pass->unifm_pixel_norm = -1; pass->unifm_pixel_norm = -1;
pass->unifm_opacity = -1; pass->unifm_opacity = -1;
pass->orig_loc = glGetUniformLocationChecked(pass->prog, "orig");
pass->texorig_loc = glGetUniformLocationChecked(pass->prog, "texorig"); pass->texorig_loc = glGetUniformLocationChecked(pass->prog, "texorig");
// Setup projection matrix // Setup projection matrix
@ -1400,8 +1368,6 @@ bool gl_create_dual_kawase_blur_context(void *blur_context, GLfloat *projection,
// Get uniform addresses // Get uniform addresses
down_pass->unifm_pixel_norm = down_pass->unifm_pixel_norm =
glGetUniformLocationChecked(down_pass->prog, "pixel_norm"); glGetUniformLocationChecked(down_pass->prog, "pixel_norm");
down_pass->orig_loc =
glGetUniformLocationChecked(down_pass->prog, "orig");
down_pass->texorig_loc = down_pass->texorig_loc =
glGetUniformLocationChecked(down_pass->prog, "texorig"); glGetUniformLocationChecked(down_pass->prog, "texorig");
down_pass->scale_loc = down_pass->scale_loc =
@ -1465,7 +1431,6 @@ bool gl_create_dual_kawase_blur_context(void *blur_context, GLfloat *projection,
glGetUniformLocationChecked(up_pass->prog, "pixel_norm"); glGetUniformLocationChecked(up_pass->prog, "pixel_norm");
up_pass->unifm_opacity = up_pass->unifm_opacity =
glGetUniformLocationChecked(up_pass->prog, "opacity"); glGetUniformLocationChecked(up_pass->prog, "opacity");
up_pass->orig_loc = glGetUniformLocationChecked(up_pass->prog, "orig");
up_pass->texorig_loc = up_pass->texorig_loc =
glGetUniformLocationChecked(up_pass->prog, "texorig"); glGetUniformLocationChecked(up_pass->prog, "texorig");
up_pass->scale_loc = glGetUniformLocationChecked(up_pass->prog, "scale"); up_pass->scale_loc = glGetUniformLocationChecked(up_pass->prog, "scale");

View file

@ -34,7 +34,6 @@ typedef struct {
GLuint prog; GLuint prog;
GLint unifm_pixel_norm; GLint unifm_pixel_norm;
GLint unifm_opacity; GLint unifm_opacity;
GLint orig_loc;
GLint texorig_loc; GLint texorig_loc;
GLint scale_loc; GLint scale_loc;
} gl_blur_shader_t; } gl_blur_shader_t;