Skip to content

Commit

Permalink
backend: gl: do not use larger-than-screen textures for blur buffers
Browse files Browse the repository at this point in the history
Blur-texture sampling has been changed to `CLAMP_TO_EDGE` in commit
4b0ff37 and to using the buffer
textures at screen position instead of texture origin in commit
89c18af.

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: 6d646b5
  • Loading branch information
tryone144 committed Aug 16, 2021
1 parent 78e8666 commit 1dbffec
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 45 deletions.
53 changes: 9 additions & 44 deletions src/backend/gl/gl_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 gd = (struct gl_data *)base;

int dst_y_screen_coord = gd->height - extent->y2,
dst_y_fb_coord = bctx->fb_height - extent->y2;
int dst_y_fb_coord = bctx->fb_height - extent->y2;

int curr = 0;
for (int i = 0; i < bctx->npasses; ++i) {
Expand All @@ -567,19 +566,15 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
assert(bctx->blur_textures[curr]);

// 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;
GLuint src_texture;

if (i == 0) {
texorig_x = extent->x1;
texorig_y = dst_y_screen_coord;
src_texture = gd->back_texture;
tex_width = gd->width;
tex_height = gd->height;
} else {
texorig_x = extent->x1 + bctx->resize_width;
texorig_y = dst_y_fb_coord - bctx->resize_height;
src_texture = bctx->blur_textures[curr];
auto src_size = bctx->texture_sizes[curr];
tex_width = src_size.width;
Expand Down Expand Up @@ -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);
glUniform2f(p->orig_loc, (GLfloat)bctx->resize_width,
-(GLfloat)bctx->resize_height);
} else {
// last pass, draw directly into the back buffer, with origin
// regions
Expand All @@ -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);

glUniform1f(p->unifm_opacity, (float)opacity);
glUniform2f(p->orig_loc, 0, 0);
}

glUniform2f(p->texorig_loc, (GLfloat)texorig_x, (GLfloat)texorig_y);
Expand All @@ -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 gd = (struct gl_data *)base;

int dst_y_screen_coord = gd->height - extent->y2,
dst_y_fb_coord = bctx->fb_height - extent->y2;
int dst_y_fb_coord = bctx->fb_height - extent->y2;

int iterations = bctx->blur_texture_count;
int scale_factor = 1;
Expand All @@ -652,35 +643,26 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
assert(down_pass->prog);
glUseProgram(down_pass->prog);

// Downsample always renders with resize offset
glUniform2f(down_pass->orig_loc, (GLfloat)bctx->resize_width,
-(GLfloat)bctx->resize_height);
glUniform2f(down_pass->texorig_loc, (GLfloat)extent->x1, (GLfloat)dst_y_fb_coord);

for (int i = 0; i < iterations; ++i) {
// Scale output width / height by half in each iteration
scale_factor <<= 1;

GLuint src_texture;
int tex_width, tex_height;
int texorig_x, texorig_y;

if (i == 0) {
// first pass: copy from back buffer
src_texture = gd->back_texture;
tex_width = gd->width;
tex_height = gd->height;

texorig_x = extent->x1;
texorig_y = dst_y_screen_coord;
} else {
// copy from previous pass
src_texture = bctx->blur_textures[i - 1];
auto src_size = bctx->texture_sizes[i - 1];
tex_width = src_size.width;
tex_height = src_size.height;

texorig_x = extent->x1 + bctx->resize_width;
texorig_y = dst_y_fb_coord - bctx->resize_height;
}

assert(src_texture);
Expand All @@ -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]);
glDrawBuffer(GL_COLOR_ATTACHMENT0);

glUniform2f(down_pass->texorig_loc, (GLfloat)texorig_x, (GLfloat)texorig_y);
glUniform1f(down_pass->scale_loc, (GLfloat)scale_factor);

glUniform2f(down_pass->unifm_pixel_norm, 1.0f / (GLfloat)tex_width,
Expand All @@ -706,9 +687,7 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
assert(up_pass->prog);
glUseProgram(up_pass->prog);

// Upsample always samples from textures with resize offset
glUniform2f(up_pass->texorig_loc, (GLfloat)(extent->x1 + bctx->resize_width),
(GLfloat)(dst_y_fb_coord - bctx->resize_height));
glUniform2f(up_pass->texorig_loc, (GLfloat)extent->x1, (GLfloat)dst_y_fb_coord);

for (int i = iterations - 1; i >= 0; --i) {
// Scale output width / height back by two in each iteration
Expand All @@ -735,16 +714,13 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bctx->blur_fbos[i - 1]);
glDrawBuffer(GL_COLOR_ATTACHMENT0);

glUniform2f(up_pass->orig_loc, (GLfloat)bctx->resize_width,
-(GLfloat)bctx->resize_height);
glUniform1f(up_pass->unifm_opacity, (GLfloat)1);
} else {
// last pass, draw directly into the back buffer
glBindVertexArray(vao[0]);
nelems = vao_nelems[0];
glBindFramebuffer(GL_FRAMEBUFFER, gd->back_fbo);

glUniform2f(up_pass->orig_loc, (GLfloat)0, (GLfloat)0);
glUniform1f(up_pass->unifm_opacity, (GLfloat)opacity);
}

Expand All @@ -765,12 +741,11 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, const region_t *reg_blu

bool ret = false;

if (gd->width + bctx->resize_width * 2 != bctx->fb_width ||
gd->height + bctx->resize_height * 2 != bctx->fb_height) {
if (gd->width != bctx->fb_width || gd->height != bctx->fb_height) {
// Resize the temporary textures used for blur in case the root
// size changed
bctx->fb_width = gd->width + bctx->resize_width * 2;
bctx->fb_height = gd->height + bctx->resize_height * 2;
bctx->fb_width = gd->width;
bctx->fb_height = gd->height;

for (int i = 0; i < bctx->blur_texture_count; ++i) {
auto tex_size = bctx->texture_sizes + i;
Expand Down Expand Up @@ -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,
uniform mat4 projection;
uniform float scale = 1.0;
uniform vec2 orig;
uniform vec2 texorig;
layout(location = 0) in vec2 coord;
layout(location = 1) in vec2 in_texcoord;
out vec2 texcoord;
void main() {
gl_Position = projection * vec4(coord + orig, 0, scale);
gl_Position = projection * vec4(coord, 0, scale);
texcoord = in_texcoord + texorig;
}
);
Expand All @@ -927,10 +901,6 @@ static int gl_win_shader_from_string(const char *vshader_str, const char *fshade
ret->unifm_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();

return true;
Expand Down Expand Up @@ -1279,7 +1249,6 @@ bool gl_create_kernel_blur_context(void *blur_context, GLfloat *projection,
pass->unifm_pixel_norm =
glGetUniformLocationChecked(pass->prog, "pixel_norm");
pass->unifm_opacity = glGetUniformLocationChecked(pass->prog, "opacity");
pass->orig_loc = glGetUniformLocationChecked(pass->prog, "orig");
pass->texorig_loc = glGetUniformLocationChecked(pass->prog, "texorig");

// Setup projection matrix
Expand All @@ -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->unifm_pixel_norm = -1;
pass->unifm_opacity = -1;
pass->orig_loc = glGetUniformLocationChecked(pass->prog, "orig");
pass->texorig_loc = glGetUniformLocationChecked(pass->prog, "texorig");

// Setup projection matrix
Expand Down Expand Up @@ -1400,8 +1368,6 @@ bool gl_create_dual_kawase_blur_context(void *blur_context, GLfloat *projection,
// Get uniform addresses
down_pass->unifm_pixel_norm =
glGetUniformLocationChecked(down_pass->prog, "pixel_norm");
down_pass->orig_loc =
glGetUniformLocationChecked(down_pass->prog, "orig");
down_pass->texorig_loc =
glGetUniformLocationChecked(down_pass->prog, "texorig");
down_pass->scale_loc =
Expand Down Expand Up @@ -1465,7 +1431,6 @@ bool gl_create_dual_kawase_blur_context(void *blur_context, GLfloat *projection,
glGetUniformLocationChecked(up_pass->prog, "pixel_norm");
up_pass->unifm_opacity =
glGetUniformLocationChecked(up_pass->prog, "opacity");
up_pass->orig_loc = glGetUniformLocationChecked(up_pass->prog, "orig");
up_pass->texorig_loc =
glGetUniformLocationChecked(up_pass->prog, "texorig");
up_pass->scale_loc = glGetUniformLocationChecked(up_pass->prog, "scale");
Expand Down
1 change: 0 additions & 1 deletion src/backend/gl/gl_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ typedef struct {
GLuint prog;
GLint unifm_pixel_norm;
GLint unifm_opacity;
GLint orig_loc;
GLint texorig_loc;
GLint scale_loc;
} gl_blur_shader_t;
Expand Down

0 comments on commit 1dbffec

Please sign in to comment.