Remember the number of blur kernels

Don't count the number of blur kernels everytime.

Fixes #188

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui
2019-06-07 21:53:23 +01:00
parent dc7050cb00
commit fa8faaf91d
9 changed files with 60 additions and 51 deletions

View File

@ -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));
@ -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;
@ -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);

View File

@ -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;
@ -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,
@ -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);
}
@ -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);