backend: gl: make blur take a source texture and a target fbo

Instead of always using the back texture/fbo. Also use the size of the
source texture, instead of hard coded back buffer size.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2022-08-25 13:34:21 +01:00
parent e2d990dc3d
commit e942f253f7
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
2 changed files with 42 additions and 34 deletions

View File

@ -38,12 +38,10 @@ struct gl_blur_context {
/** /**
* Blur contents in a particular region. * Blur contents in a particular region.
*/ */
bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *extent, bool gl_kernel_blur(double opacity, struct gl_blur_context *bctx, const rect_t *extent,
struct backend_image *mask, coord_t mask_dst, const GLuint vao[2], struct backend_image *mask, coord_t mask_dst, const GLuint vao[2],
const int vao_nelems[2]) { const int vao_nelems[2], GLuint source_texture,
auto bctx = (struct gl_blur_context *)ctx; geometry_t source_size, GLuint target_fbo, GLuint default_mask) {
auto gd = (struct gl_data *)base;
int dst_y_fb_coord = bctx->fb_height - extent->y2; int dst_y_fb_coord = bctx->fb_height - extent->y2;
int curr = 0; int curr = 0;
@ -59,9 +57,9 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
GLuint src_texture; GLuint src_texture;
if (i == 0) { if (i == 0) {
src_texture = gd->back_texture; src_texture = source_texture;
tex_width = gd->width; tex_width = source_size.width;
tex_height = gd->height; tex_height = source_size.height;
} else { } else {
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];
@ -76,7 +74,7 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
1.0F / (GLfloat)tex_height); 1.0F / (GLfloat)tex_height);
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gd->default_mask_texture); glBindTexture(GL_TEXTURE_2D, default_mask);
glUniform1i(p->uniform_mask_tex, 1); glUniform1i(p->uniform_mask_tex, 1);
glUniform2f(p->uniform_mask_offset, 0.0F, 0.0F); glUniform2f(p->uniform_mask_offset, 0.0F, 0.0F);
@ -119,7 +117,7 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
} }
glBindVertexArray(vao[0]); glBindVertexArray(vao[0]);
nelems = vao_nelems[0]; nelems = vao_nelems[0];
glBindFramebuffer(GL_FRAMEBUFFER, gd->back_fbo); glBindFramebuffer(GL_FRAMEBUFFER, target_fbo);
glUniform1f(p->uniform_opacity, (float)opacity); glUniform1f(p->uniform_opacity, (float)opacity);
} }
@ -136,12 +134,10 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
return true; return true;
} }
bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_t *extent, bool gl_dual_kawase_blur(double opacity, struct gl_blur_context *bctx, const rect_t *extent,
struct backend_image *mask, coord_t mask_dst, struct backend_image *mask, coord_t mask_dst, const GLuint vao[2],
const GLuint vao[2], const int vao_nelems[2]) { const int vao_nelems[2], GLuint source_texture,
auto bctx = (struct gl_blur_context *)ctx; geometry_t source_size, GLuint target_fbo, GLuint default_mask) {
auto gd = (struct gl_data *)base;
int 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 iterations = bctx->blur_texture_count;
@ -163,9 +159,9 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
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 = source_texture;
tex_width = gd->width; tex_width = source_size.width;
tex_height = gd->height; tex_height = source_size.height;
} else { } else {
// copy from previous pass // copy from previous pass
src_texture = bctx->blur_textures[i - 1]; src_texture = bctx->blur_textures[i - 1];
@ -216,7 +212,7 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, src_texture); glBindTexture(GL_TEXTURE_2D, src_texture);
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gd->default_mask_texture); glBindTexture(GL_TEXTURE_2D, default_mask);
glUniform1i(up_pass->uniform_mask_tex, 1); glUniform1i(up_pass->uniform_mask_tex, 1);
glUniform2f(up_pass->uniform_mask_offset, 0.0F, 0.0F); glUniform2f(up_pass->uniform_mask_offset, 0.0F, 0.0F);
@ -248,7 +244,7 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
} }
glBindVertexArray(vao[0]); glBindVertexArray(vao[0]);
nelems = vao_nelems[0]; nelems = vao_nelems[0];
glBindFramebuffer(GL_FRAMEBUFFER, gd->back_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target_fbo);
glUniform1f(up_pass->uniform_opacity, (GLfloat)opacity); glUniform1f(up_pass->uniform_opacity, (GLfloat)opacity);
} }
@ -263,18 +259,17 @@ bool gl_dual_kawase_blur(backend_t *base, double opacity, void *ctx, const rect_
return true; return true;
} }
bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mask_dst, bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask,
const region_t *reg_blur, const region_t *reg_visible attr_unused) { coord_t mask_dst, const region_t *reg_blur,
auto bctx = (struct gl_blur_context *)ctx; const region_t *reg_visible attr_unused, GLuint source_texture,
auto gd = (struct gl_data *)base; geometry_t source_size, GLuint target_fbo, GLuint default_mask) {
bool ret = false; bool ret = false;
if (gd->width != bctx->fb_width || gd->height != bctx->fb_height) { if (source_size.width != bctx->fb_width || source_size.height != 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->fb_width = source_size.width;
bctx->fb_height = gd->height; bctx->fb_height = source_size.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;
@ -329,7 +324,7 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mas
auto indices = ccalloc(nrects * 6, GLuint); auto indices = ccalloc(nrects * 6, GLuint);
x_rect_to_coords(nrects, rects, x_rect_to_coords(nrects, rects,
(coord_t){.x = extent_resized->x1, .y = extent_resized->y2}, (coord_t){.x = extent_resized->x1, .y = extent_resized->y2},
bctx->fb_height, gd->height, false, coord, indices); bctx->fb_height, source_size.height, false, coord, indices);
auto coord_resized = ccalloc(nrects_resized * 16, GLint); auto coord_resized = ccalloc(nrects_resized * 16, GLint);
auto indices_resized = ccalloc(nrects_resized * 6, GLuint); auto indices_resized = ccalloc(nrects_resized * 6, GLuint);
@ -373,11 +368,13 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mas
int vao_nelems[2] = {nrects * 6, nrects_resized * 6}; int vao_nelems[2] = {nrects * 6, nrects_resized * 6};
if (bctx->method == BLUR_METHOD_DUAL_KAWASE) { if (bctx->method == BLUR_METHOD_DUAL_KAWASE) {
ret = gl_dual_kawase_blur(base, opacity, ctx, extent_resized, mask, ret = gl_dual_kawase_blur(opacity, bctx, extent_resized, mask, mask_dst,
mask_dst, vao, vao_nelems); vao, vao_nelems, source_texture, source_size,
target_fbo, default_mask);
} else { } else {
ret = gl_kernel_blur(base, opacity, ctx, extent_resized, mask, mask_dst, ret = gl_kernel_blur(opacity, bctx, extent_resized, mask, mask_dst, vao,
vao, vao_nelems); vao_nelems, source_texture, source_size, target_fbo,
default_mask);
} }
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -401,6 +398,16 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mas
return ret; return ret;
} }
bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mask_dst,
const region_t *reg_blur, const region_t *reg_visible attr_unused) {
auto gd = (struct gl_data *)base;
auto bctx = (struct gl_blur_context *)ctx;
return gl_blur_impl(opacity, bctx, mask, mask_dst, reg_blur, reg_visible,
gd->back_texture,
(geometry_t){.width = gd->width, .height = gd->height},
gd->back_fbo, gd->default_mask_texture);
}
static inline void gl_free_blur_shader(gl_blur_shader_t *shader) { static inline void gl_free_blur_shader(gl_blur_shader_t *shader) {
if (shader->prog) { if (shader->prog) {
glDeleteProgram(shader->prog); glDeleteProgram(shader->prog);

View File

@ -12,6 +12,7 @@
#define CASESTRRET(s) \ #define CASESTRRET(s) \
case s: return #s case s: return #s
struct gl_blur_context;
static inline GLint glGetUniformLocationChecked(GLuint p, const char *name) { static inline GLint glGetUniformLocationChecked(GLuint p, const char *name) {
auto ret = glGetUniformLocation(p, name); auto ret = glGetUniformLocation(p, name);