From 6929e29b9fdf7ac90d3e55007ee0e34974b0ce5d Mon Sep 17 00:00:00 2001 From: Bernd Busse Date: Thu, 22 Feb 2018 21:49:53 +0100 Subject: [PATCH] Add additional blur levels and fix downscaling --- man/compton.1.asciidoc | 2 +- src/common.h | 107 ++++++++++++++--------------------------- src/compton.c | 5 +- src/opengl.c | 29 ++++++++--- 4 files changed, 60 insertions(+), 83 deletions(-) diff --git a/man/compton.1.asciidoc b/man/compton.1.asciidoc index cb7e6541..7b1b9811 100644 --- a/man/compton.1.asciidoc +++ b/man/compton.1.asciidoc @@ -212,7 +212,7 @@ Note: `kawase` only works with the `glx` backend. *--blur-strength* 'LEVEL':: Only valid for *--blur-method kawase*! - The strength of the kawase blur as an integer between 1 and 15. + The strength of the kawase blur as an integer between 1 and 20. Defaults to 5. *--blur-kern* 'MATRIX':: Only valid for *--blur-method convolution*! diff --git a/src/common.h b/src/common.h index 8daa6584..e41139f1 100644 --- a/src/common.h +++ b/src/common.h @@ -229,7 +229,7 @@ #define CGLX_MAX_BUFFER_AGE 5 /// @brief Maximum passes for blur. -#define MAX_BLUR_PASS 5 +#define MAX_BLUR_PASS 6 // Window flags @@ -491,9 +491,8 @@ typedef struct { typedef struct { /// Framebuffer used for blurring. GLuint fbo; - // FIXME.kawase: Set maximum number of textures for kawase blur /// Textures used for blurring. - GLuint textures[6]; // 4 + 2 + GLuint textures[MAX_BLUR_PASS]; /// Width of the textures. int width; /// Height of the textures. @@ -552,6 +551,11 @@ struct _timeout_t; struct _win; +typedef struct { + int iterations; + float offset; +} blur_strength_t; + typedef struct _c2_lptr c2_lptr_t; /// Structure representing all options. @@ -726,8 +730,7 @@ typedef struct _options_t { /// Blur convolution kernel. XFixed *blur_kerns[MAX_BLUR_PASS]; /// Blur strength. - int blur_strength_iterations; - float blur_strength_offset; + blur_strength_t blur_strength; /// How much to dim an inactive window. 0.0 - 1.0, 0 to disable. double inactive_dim; /// Whether to use fixed inactive dim opacity, instead of deciding @@ -1708,72 +1711,35 @@ parse_blur_method(session_t *ps, const char *str) { */ static inline bool parse_blur_strength(session_t *ps, const int level) { - switch (level) { - case 1: - ps->o.blur_strength_iterations = 1; - ps->o.blur_strength_offset = 1.5; - break; - case 2: - ps->o.blur_strength_iterations = 1; - ps->o.blur_strength_offset = 2.0; - break; - case 3: - ps->o.blur_strength_iterations = 2; - ps->o.blur_strength_offset = 2.5; - break; - case 4: - ps->o.blur_strength_iterations = 2; - ps->o.blur_strength_offset = 3.0; - break; - case 5: - ps->o.blur_strength_iterations = 3; - ps->o.blur_strength_offset = 2.6; - break; - case 6: - ps->o.blur_strength_iterations = 3; - ps->o.blur_strength_offset = 3.2; - break; - case 7: - ps->o.blur_strength_iterations = 3; - ps->o.blur_strength_offset = 3.8; - break; - case 8: - ps->o.blur_strength_iterations = 3; - ps->o.blur_strength_offset = 4.4; - break; - case 9: - ps->o.blur_strength_iterations = 3; - ps->o.blur_strength_offset = 5.0; - break; - case 10: - ps->o.blur_strength_iterations = 4; - ps->o.blur_strength_offset = 3.833; - break; - case 11: - ps->o.blur_strength_iterations = 4; - ps->o.blur_strength_offset = 4.667; - break; - case 12: - ps->o.blur_strength_iterations = 4; - ps->o.blur_strength_offset = 5.5; - break; - case 13: - ps->o.blur_strength_iterations = 4; - ps->o.blur_strength_offset = 6.333; - break; - case 14: - ps->o.blur_strength_iterations = 4; - ps->o.blur_strength_offset = 7.167; - break; - case 15: - ps->o.blur_strength_iterations = 4; - ps->o.blur_strength_offset = 8.0; - break; - default: - printf_errf("(\"%d\"): Invalid blur_strength argument. Needs to be a number between 1 and 15.", level); - return false; + static const blur_strength_t values[20] = { + { .iterations = 1, .offset = 1.5 }, // 1 + { .iterations = 1, .offset = 2.0 }, // 2 + { .iterations = 2, .offset = 2.5 }, // 3 + { .iterations = 2, .offset = 3.0 }, // 4 + { .iterations = 3, .offset = 2.75 }, // 5 + { .iterations = 3, .offset = 3.5 }, // 6 + { .iterations = 3, .offset = 4.25 }, // 7 + { .iterations = 3, .offset = 5.0 }, // 8 + { .iterations = 4, .offset = 3.71429 }, // 9 + { .iterations = 4, .offset = 4.42857 }, // 10 + { .iterations = 4, .offset = 5.14286 }, // 11 + { .iterations = 4, .offset = 5.85714 }, // 12 + { .iterations = 4, .offset = 6.57143 }, // 13 + { .iterations = 4, .offset = 7.28571 }, // 14 + { .iterations = 4, .offset = 8.0 }, // 15 + { .iterations = 5, .offset = 6.0 }, // 16 + { .iterations = 5, .offset = 7.0 }, // 17 + { .iterations = 5, .offset = 8.0 }, // 18 + { .iterations = 5, .offset = 9.0 }, // 19 + { .iterations = 5, .offset = 10.0 }, // 20 + }; + + if (level < 1 || level > 20) { + printf_errf("(\"%d\"): Invalid blur_strength argument. Needs to be a number between 1 and 20.", level); + return false; } + ps->o.blur_strength = values[level - 1]; return true; } @@ -2385,8 +2351,7 @@ free_glx_fbo(session_t *ps, GLuint *pfbo) { */ static inline void free_glx_bc_resize(session_t *ps, glx_blur_cache_t *pbc) { - // FIXME.kawase: Use maximum number of textures - for (int i = 0; i < 6; i++) + for (int i = 0; i < MAX_BLUR_PASS; i++) free_texture_r(ps, &pbc->textures[i]); pbc->width = 0; pbc->height = 0; diff --git a/src/compton.c b/src/compton.c index 506dccab..5f9bdeca 100644 --- a/src/compton.c +++ b/src/compton.c @@ -4712,7 +4712,7 @@ usage(int ret) { "\n" "--blur-strength level\n" " Only valid for '--blur-method kawase'!\n" - " The strength of the kawase blur as an integer between 1 and 15.\n" + " The strength of the kawase blur as an integer between 1 and 20. Defaults to 5.\n" "\n" "--blur-kern matrix\n" " Only valid for '--blur-method convolution'!\n" @@ -7075,8 +7075,7 @@ session_init(session_t *ps_old, int argc, char **argv) { .blur_background_blacklist = NULL, .blur_method = BLRMTHD_CONV, .blur_kerns = { NULL }, - .blur_strength_iterations = 1, - .blur_strength_offset = 1.5, + .blur_strength = { .iterations = 3, .offset = 2.75 }, .inactive_dim = 0.0, .inactive_dim_fixed = false, .invert_color_list = NULL, diff --git a/src/opengl.c b/src/opengl.c index d0dd9b7a..144c08f3 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -1589,6 +1589,9 @@ glx_kawase_blur_dst(session_t *ps, int dx, int dy, int width, int height, float const bool have_stencil = glIsEnabled(GL_STENCIL_TEST); bool ret = false; + int iterations = ps->o.blur_strength.iterations; + float offset = ps->o.blur_strength.offset; + // Calculate copy region size glx_blur_cache_t ibc = { .width = 0, .height = 0 }; if (!pbc) @@ -1612,8 +1615,12 @@ glx_kawase_blur_dst(session_t *ps, int dx, int dy, int width, int height, float pbc->textures[0] = glx_gen_texture(ps, tex_tgt, mwidth, mheight); GLuint tex_scr = pbc->textures[0]; - // FIXME.kawase: Allocate only as many textures as needed - for (int i = 1; i < 6; i++) { + // Check if we can scale down blur_strength.iterations + while ((mwidth / (1 << (iterations-1))) < 1 || (mheight / (1 << (iterations-1))) < 1) + --iterations; + + assert(iterations < MAX_BLUR_PASS); + for (int i = 1; i <= iterations; i++) { if (!pbc->textures[i]) pbc->textures[i] = glx_gen_texture(ps, tex_tgt, mwidth / (1 << (i-1)), mheight / (1 << (i-1))); } @@ -1625,10 +1632,16 @@ glx_kawase_blur_dst(session_t *ps, int dx, int dy, int width, int height, float glGenFramebuffers(1, &pbc->fbo); const GLuint fbo = pbc->fbo; - if (!tex_scr || !pbc->textures[1] || !pbc->textures[2] || !pbc->textures[3] || !pbc->textures[4] || !pbc->textures[5]) { - printf_errf("(): Failed to allocate textures."); + if (!tex_scr) { + printf_errf("(): Failed to allocate texture."); goto glx_kawase_blur_dst_end; } + for (int i = 1; i <= iterations; i++) { + if (!pbc->textures[i]) { + printf_errf("(): Failed to allocate additional textures."); + goto glx_kawase_blur_dst_end; + } + } if (!fbo) { printf_errf("(): Failed to allocate framebuffer."); goto glx_kawase_blur_dst_end; @@ -1644,7 +1657,7 @@ glx_kawase_blur_dst(session_t *ps, int dx, int dy, int width, int height, float glDisable(GL_SCISSOR_TEST); // First pass(es): Kawase Downsample - for (int i = 1; i <= ps->o.blur_strength_iterations; i++) { + for (int i = 1; i <= iterations; i++) { const glx_blur_pass_t *down_pass = &ps->psglx->blur_passes[0]; assert(down_pass->prog); @@ -1669,7 +1682,7 @@ glx_kawase_blur_dst(session_t *ps, int dx, int dy, int width, int height, float glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glUseProgram(down_pass->prog); if (down_pass->unifm_offset >= 0) - glUniform1f(down_pass->unifm_offset, ps->o.blur_strength_offset); + glUniform1f(down_pass->unifm_offset, offset); if (down_pass->unifm_halfpixel >= 0) glUniform2f(down_pass->unifm_halfpixel, 0.5 / tex_width, 0.5 / tex_height); if (down_pass->unifm_fulltex >= 0) @@ -1703,7 +1716,7 @@ glx_kawase_blur_dst(session_t *ps, int dx, int dy, int width, int height, float } // Second pass(es): Kawase Upsample - for (int i = ps->o.blur_strength_iterations; i >= 1; i--) { + for (int i = iterations; i >= 1; i--) { const glx_blur_pass_t *up_pass = &ps->psglx->blur_passes[1]; bool is_last = (i == 1); assert(up_pass->prog); @@ -1742,7 +1755,7 @@ glx_kawase_blur_dst(session_t *ps, int dx, int dy, int width, int height, float glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glUseProgram(up_pass->prog); if (up_pass->unifm_offset >= 0) - glUniform1f(up_pass->unifm_offset, ps->o.blur_strength_offset); + glUniform1f(up_pass->unifm_offset, offset); if (up_pass->unifm_halfpixel >= 0) glUniform2f(up_pass->unifm_halfpixel, 0.5 / tex_width, 0.5 / tex_height); if (up_pass->unifm_fulltex >= 0)