Skip to content

Commit

Permalink
Remember the number of blur kernels
Browse files Browse the repository at this point in the history
Don't count the number of blur kernels everytime.

Fixes chjj#188

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
  • Loading branch information
yshui committed Jun 7, 2019
1 parent dc7050c commit fa8faaf
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 51 deletions.
10 changes: 5 additions & 5 deletions src/backend/gl/gl_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,12 +662,12 @@ void *gl_copy(backend_t *base, const void *image_data, const region_t *reg_visib
/**
* Initialize GL blur filters.
*/
static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
if (!kernels[0]) {
static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels, int nkernels) {
if (!nkernels) {
return true;
}

for (gd->npasses = 0; kernels[gd->npasses]; gd->npasses++);
gd->npasses = nkernels;
gd->blur_shader = ccalloc(gd->npasses, gl_blur_shader_t);

char *lc_numeric_old = strdup(setlocale(LC_NUMERIC, NULL));
Expand Down Expand Up @@ -700,7 +700,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
const char *shader_add = FRAG_SHADER_BLUR_ADD;
char *extension = strdup("");

for (int i = 0; kernels[i]; i++) {
for (int i = 0; i < nkernels; i++) {
auto kern = kernels[i];
// Build shader
int width = kern->w, height = kern->h;
Expand Down Expand Up @@ -831,7 +831,7 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

gl_win_shader_from_string(vertex_shader, win_shader_glsl, &gd->win_shader);
if (!gl_init_blur(gd, ps->o.blur_kerns)) {
if (!gl_init_blur(gd, ps->o.blur_kerns, ps->o.blur_kernel_count)) {
return false;
}
gd->fill_shader.prog = gl_create_program_from_str(fill_vert, fill_frag);
Expand Down
28 changes: 14 additions & 14 deletions src/backend/xrender/xrender.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ typedef struct _xrender_data {
int target_width, target_height;

/// Blur kernels converted to X format
struct x_convolution_kernel **x_blur_kern;
struct x_convolution_kernel **x_blur_kernel;

/// Number of blur kernels
int x_blur_kernel_count;

xcb_special_event_t *present_event;
} xrender_data;
Expand Down Expand Up @@ -175,16 +178,16 @@ static bool blur(backend_t *backend_data, double opacity, const region_t *reg_bl
// For 1 pass, we do
// back -(pass 1)-> tmp0 -(copy)-> target_buffer
int i;
for (i = 0; xd->x_blur_kern[i]; i++) {
for (i = 0; i < xd->x_blur_kernel_count; i++) {
// Copy from source picture to destination. The filter must
// be applied on source picture, to get the nearby pixels outside the
// window.
// TODO cache converted blur_kerns
xcb_render_set_picture_filter(
c, src_pict, to_u16_checked(strlen(filter)), filter,
to_u32_checked(xd->x_blur_kern[i]->size), xd->x_blur_kern[i]->kernel);
to_u32_checked(xd->x_blur_kernel[i]->size), xd->x_blur_kernel[i]->kernel);

if (xd->x_blur_kern[i + 1] || i == 0) {
if (i < xd->x_blur_kernel_count - 1 || i == 0) {
// This is not the last pass, or this is the first pass
xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, src_pict,
XCB_NONE, dst_pict, src_x, src_y, 0, 0, 0, 0,
Expand Down Expand Up @@ -269,10 +272,10 @@ static void deinit(backend_t *backend_data) {
xcb_render_free_picture(xd->base.c, xd->back[i]);
xcb_free_pixmap(xd->base.c, xd->back_pixmap[i]);
}
for (int i = 0; xd->x_blur_kern[i]; i++) {
free(xd->x_blur_kern[i]);
for (int i = 0; i < xd->x_blur_kernel_count; i++) {
free(xd->x_blur_kernel[i]);
}
free(xd->x_blur_kern);
free(xd->x_blur_kernel);
if (xd->present_event) {
xcb_unregister_for_special_event(xd->base.c, xd->present_event);
}
Expand Down Expand Up @@ -547,14 +550,11 @@ backend_t *backend_xrender_init(session_t *ps) {
ps->c, ps->vis, root_pixmap, 0, NULL);
}

int npasses = 0;
for (; ps->o.blur_kerns[npasses]; npasses++)
;
// +1 for null terminator
xd->x_blur_kern = ccalloc(npasses + 1, struct x_convolution_kernel *);
for (int i = 0; ps->o.blur_kerns[i]; i++) {
x_create_convolution_kernel(ps->o.blur_kerns[i], 1, &xd->x_blur_kern[i]);
xd->x_blur_kernel = ccalloc(ps->o.blur_kernel_count, struct x_convolution_kernel *);
for (int i = 0; i < ps->o.blur_kernel_count; i++) {
x_create_convolution_kernel(ps->o.blur_kerns[i], 1, &xd->x_blur_kernel[i]);
}
xd->x_blur_kernel_count = ps->o.blur_kernel_count;
return &xd->base;
err:
deinit(&xd->base);
Expand Down
2 changes: 1 addition & 1 deletion src/compton.c
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,7 @@ static void session_destroy(session_t *ps) {

free(ps->o.write_pid_path);
free(ps->o.logpath);
for (int i = 0; ps->o.blur_kerns[i]; ++i) {
for (int i = 0; i < ps->o.blur_kernel_count; ++i) {
free(ps->o.blur_kerns[i]);
}
free(ps->o.blur_kerns);
Expand Down
10 changes: 7 additions & 3 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ conv *parse_blur_kern(const char *src, const char **endptr, bool *hasneg) {
* @param[out] hasneg whether any of the kernels have negative values
* @return the kernels
*/
struct conv **parse_blur_kern_lst(const char *src, bool *hasneg) {
struct conv **parse_blur_kern_lst(const char *src, bool *hasneg, int *count) {
// TODO just return a predefined kernels, not parse predefined strings...
static const struct {
const char *name;
Expand Down Expand Up @@ -251,11 +251,12 @@ struct conv **parse_blur_kern_lst(const char *src, bool *hasneg) {
"000000,"},
};

*count = 0;
*hasneg = false;
for (unsigned int i = 0;
i < sizeof(CONV_KERN_PREDEF) / sizeof(CONV_KERN_PREDEF[0]); ++i) {
if (!strcmp(CONV_KERN_PREDEF[i].name, src))
return parse_blur_kern_lst(CONV_KERN_PREDEF[i].kern_str, hasneg);
return parse_blur_kern_lst(CONV_KERN_PREDEF[i].kern_str, hasneg, count);
}

int nkernels = 1;
Expand All @@ -265,7 +266,7 @@ struct conv **parse_blur_kern_lst(const char *src, bool *hasneg) {
}
}

struct conv **ret = ccalloc(nkernels+1, struct conv *); // +1 for NULL terminator
struct conv **ret = ccalloc(nkernels, struct conv *);

int i = 0;
const char *pc = src;
Expand Down Expand Up @@ -294,6 +295,8 @@ struct conv **parse_blur_kern_lst(const char *src, bool *hasneg) {
"removed in future releases");
}

*count = i;

return ret;
}

Expand Down Expand Up @@ -541,6 +544,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
.blur_background_fixed = false,
.blur_background_blacklist = NULL,
.blur_kerns = NULL,
.blur_kernel_count = 0,
.inactive_dim = 0.0,
.inactive_dim_fixed = false,
.invert_color_list = NULL,
Expand Down
4 changes: 3 additions & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ typedef struct options {
c2_lptr_t *blur_background_blacklist;
/// Blur convolution kernel.
struct conv **blur_kerns;
/// Number of convolution kernels
int blur_kernel_count;
/// 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
Expand Down Expand Up @@ -233,7 +235,7 @@ extern const char *const BACKEND_STRS[NUM_BKEND + 1];

bool must_use parse_long(const char *, long *);
bool must_use parse_int(const char *, int *);
struct conv **must_use parse_blur_kern_lst(const char *, bool *hasneg);
struct conv **must_use parse_blur_kern_lst(const char *, bool *hasneg, int *count);
bool must_use parse_geometry(session_t *, const char *, region_t *);
bool must_use parse_rule_opacity(c2_lptr_t **, const char *);
enum blur_method must_use parse_blur_method(const char *src);
Expand Down
6 changes: 4 additions & 2 deletions src/config_libconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,8 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
lcfg_lookup_bool(&cfg, "blur-background-fixed", &opt->blur_background_fixed);
// --blur-kern
if (config_lookup_string(&cfg, "blur-kern", &sval)) {
opt->blur_kerns = parse_blur_kern_lst(sval, conv_kern_hasneg);
opt->blur_kerns =
parse_blur_kern_lst(sval, conv_kern_hasneg, &opt->blur_kernel_count);
if (!opt->blur_kerns) {
log_fatal("Cannot parse \"blur-kern\"");
goto err;
Expand Down Expand Up @@ -464,7 +465,8 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
config_setting_lookup_int(blur_cfg, "size", &opt->blur_radius);

if (config_setting_lookup_string(blur_cfg, "kernel", &sval)) {
opt->blur_kerns = parse_blur_kern_lst(sval, conv_kern_hasneg);
opt->blur_kerns = parse_blur_kern_lst(sval, conv_kern_hasneg,
&opt->blur_kernel_count);
if (!opt->blur_kerns) {
log_warn("Failed to parse blur kernel: %s", sval);
}
Expand Down
21 changes: 10 additions & 11 deletions src/opengl.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,10 @@ bool glx_init(session_t *ps, bool need_render) {
ps->psglx = cmalloc(glx_session_t);
memcpy(ps->psglx, &CGLX_SESSION_DEF, sizeof(glx_session_t));

int npasses;
for (npasses = 0; ps->o.blur_kerns[npasses]; npasses++)
;
// +1 for the zero terminator
ps->psglx->blur_passes = ccalloc(npasses + 1, glx_blur_pass_t);
ps->psglx->blur_passes = ccalloc(ps->o.blur_kernel_count, glx_blur_pass_t);

for (int i = 0; ps->o.blur_kerns[i]; ++i) {
for (int i = 0; i < ps->o.blur_kernel_count; ++i) {
glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];
ppass->unifm_factor_center = -1;
ppass->unifm_offset_x = -1;
Expand Down Expand Up @@ -236,7 +233,7 @@ void glx_destroy(session_t *ps) {
}

// Free GLSL shaders/programs
for (int i = 0; ps->psglx->blur_passes[i].prog; ++i) {
for (int i = 0; i < ps->o.blur_kernel_count; ++i) {
glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];
if (ppass->frag_shader)
glDeleteShader(ppass->frag_shader);
Expand Down Expand Up @@ -277,10 +274,12 @@ void glx_on_root_change(session_t *ps) {
* Initialize GLX blur filter.
*/
bool glx_init_blur(session_t *ps) {
assert(ps->o.blur_kernel_count > 0);
assert(ps->o.blur_kerns);
assert(ps->o.blur_kerns[0]);

// Allocate PBO if more than one blur kernel is present
if (ps->o.blur_kerns[1]) {
if (ps->o.blur_kernel_count > 1) {
// Try to generate a framebuffer
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
Expand Down Expand Up @@ -331,7 +330,7 @@ bool glx_init_blur(session_t *ps) {
extension = strdup("");
}

for (int i = 0; ps->o.blur_kerns[i]; ++i) {
for (int i = 0; i < ps->o.blur_kernel_count; ++i) {
auto kern = ps->o.blur_kerns[i];
glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];

Expand Down Expand Up @@ -695,7 +694,7 @@ static inline void glx_copy_region_to_tex(session_t *ps, GLenum tex_tgt, int bas
bool glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
GLfloat factor_center, const region_t *reg_tgt, glx_blur_cache_t *pbc) {
assert(ps->psglx->blur_passes[0].prog);
const bool more_passes = ps->psglx->blur_passes[1].prog;
const bool more_passes = ps->o.blur_kernel_count > 1;
const bool have_scissors = glIsEnabled(GL_SCISSOR_TEST);
const bool have_stencil = glIsEnabled(GL_STENCIL_TEST);
bool ret = false;
Expand Down Expand Up @@ -788,8 +787,8 @@ bool glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
}

bool last_pass = false;
for (int i = 0; !last_pass; ++i) {
last_pass = !ps->psglx->blur_passes[i + 1].prog;
for (int i = 0; i < ps->o.blur_kernel_count; ++i) {
last_pass = (i == ps->o.blur_kernel_count - 1);
const glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];
assert(ppass->prog);

Expand Down
7 changes: 5 additions & 2 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,8 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
break;
case 301:
// --blur-kern
opt->blur_kerns = parse_blur_kern_lst(optarg, &conv_kern_hasneg);
opt->blur_kerns = parse_blur_kern_lst(optarg, &conv_kern_hasneg,
&opt->blur_kernel_count);
if (!opt->blur_kerns) {
exit(1);
}
Expand Down Expand Up @@ -819,8 +820,10 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
// Fill default blur kernel
if (opt->blur_method == BLUR_METHOD_KERNEL &&
(!opt->blur_kerns || !opt->blur_kerns[0])) {
opt->blur_kerns = parse_blur_kern_lst("3x3box", &conv_kern_hasneg);
opt->blur_kerns = parse_blur_kern_lst("3x3box", &conv_kern_hasneg,
&opt->blur_kernel_count);
CHECK(opt->blur_kerns);
CHECK(opt->blur_kernel_count);
}

if (opt->resize_damage < 0) {
Expand Down
23 changes: 11 additions & 12 deletions src/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,9 +616,10 @@ win_paint_shadow(session_t *ps, struct managed_win *w, region_t *reg_paint) {
*
* @return true if successful, false otherwise
*/
static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int16_t x,
int16_t y, uint16_t wid, uint16_t hei,
struct x_convolution_kernel **blur_kerns, const region_t *reg_clip) {
static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int16_t x, int16_t y,
uint16_t wid, uint16_t hei, struct x_convolution_kernel **blur_kerns,
int nkernels, const region_t *reg_clip) {
assert(blur_kerns);
assert(blur_kerns[0]);

// Directly copying from tgt_buffer to it does not work, so we create a
Expand All @@ -635,7 +636,7 @@ static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int16_t
x_set_picture_clip_region(ps->c, tmp_picture, 0, 0, reg_clip);

xcb_render_picture_t src_pict = tgt_buffer, dst_pict = tmp_picture;
for (int i = 0; blur_kerns[i]; ++i) {
for (int i = 0; i < nkernels; ++i) {
xcb_render_fixed_t *convolution_blur = blur_kerns[i]->kernel;
// `x / 65536.0` converts from X fixed point to double
int kwid = (int)((double)convolution_blur[0] / 65536.0),
Expand Down Expand Up @@ -693,7 +694,7 @@ win_blur_background(session_t *ps, struct managed_win *w, xcb_render_picture_t t
case BKEND_XRENDER:
case BKEND_XR_GLX_HYBRID: {
// Normalize blur kernels
for (int i = 0; ps->o.blur_kerns[i]; ++i) {
for (int i = 0; i < ps->o.blur_kernel_count; i++) {
// Note: `x * 65536` converts double `x` to a X fixed point
// representation. `x / 65536` is the other way.
auto kern_src = ps->o.blur_kerns[i];
Expand Down Expand Up @@ -724,7 +725,8 @@ win_blur_background(session_t *ps, struct managed_win *w, xcb_render_picture_t t
}
// Translate global coordinates to local ones
pixman_region32_translate(&reg_blur, -x, -y);
xr_blur_dst(ps, tgt_buffer, x, y, wid, hei, ps->blur_kerns_cache, &reg_blur);
xr_blur_dst(ps, tgt_buffer, x, y, wid, hei, ps->blur_kerns_cache,
ps->o.blur_kernel_count, &reg_blur);
pixman_region32_clear(&reg_blur);
} break;
#ifdef CONFIG_OPENGL
Expand Down Expand Up @@ -1135,12 +1137,9 @@ bool init_render(session_t *ps) {

// Blur filter
if (ps->o.blur_method) {
int npasses;
for (npasses = 0; ps->o.blur_kerns[npasses]; npasses++)
;
ps->blur_kerns_cache =
ccalloc(ps->o.blur_kernel_count, struct x_convolution_kernel *);

// +1 for NULL terminator
ps->blur_kerns_cache = ccalloc(npasses+1, struct x_convolution_kernel *);
bool ret = false;
if (ps->o.backend == BKEND_GLX) {
#ifdef CONFIG_OPENGL
Expand Down Expand Up @@ -1223,7 +1222,7 @@ void deinit_render(session_t *ps) {
}
#endif

for (int i = 0; ps->blur_kerns_cache[i]; i++) {
for (int i = 0; i < ps->o.blur_kernel_count; i++) {
free(ps->blur_kerns_cache[i]);
}
free(ps->blur_kerns_cache);
Expand Down

0 comments on commit fa8faaf

Please sign in to comment.