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 commit4b0ff37b36
and to using the buffer textures at screen position instead of texture origin in commit89c18afac6
. 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:
parent
78e8666498
commit
1dbffec3ae
2 changed files with 9 additions and 45 deletions
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue