mirror of https://github.com/yshui/picom.git
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:
parent
e2d990dc3d
commit
e942f253f7
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue