Lift the MAX_BLUR_PASS limit
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
@ -388,7 +388,6 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, extent->x1, dst_y, width, height);
|
||||
|
||||
for (int i = 0; i < gd->npasses; ++i) {
|
||||
assert(i < MAX_BLUR_PASS - 1);
|
||||
const gl_blur_shader_t *p = &gd->blur_shader[i];
|
||||
assert(p->prog);
|
||||
|
||||
@ -668,6 +667,9 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (gd->npasses = 0; kernels[gd->npasses]; gd->npasses++);
|
||||
gd->blur_shader = ccalloc(gd->npasses, gl_blur_shader_t);
|
||||
|
||||
char *lc_numeric_old = strdup(setlocale(LC_NUMERIC, NULL));
|
||||
// Enforce LC_NUMERIC locale "C" here to make sure decimal point is sane
|
||||
// Thanks to hiciu for reporting.
|
||||
@ -698,8 +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("");
|
||||
|
||||
gl_blur_shader_t *passes = gd->blur_shader;
|
||||
for (int i = 0; i < MAX_BLUR_PASS && kernels[i]; gd->npasses = ++i) {
|
||||
for (int i = 0; kernels[i]; i++) {
|
||||
auto kern = kernels[i];
|
||||
// Build shader
|
||||
int width = kern->w, height = kern->h;
|
||||
@ -728,7 +729,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
|
||||
}
|
||||
}
|
||||
|
||||
auto pass = passes + i;
|
||||
auto pass = gd->blur_shader + i;
|
||||
size_t shader_len = strlen(FRAG_SHADER_BLUR) + strlen(extension) +
|
||||
strlen(shader_body) + 10 /* sum */ +
|
||||
1 /* null terminator */;
|
||||
@ -812,10 +813,6 @@ const char *win_shader_glsl = GLSL(330,
|
||||
|
||||
bool gl_init(struct gl_data *gd, session_t *ps) {
|
||||
// Initialize GLX data structure
|
||||
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
||||
gd->blur_shader[i] = (gl_blur_shader_t){.prog = 0};
|
||||
}
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
@ -833,7 +830,6 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
gd->npasses = 0;
|
||||
gl_win_shader_from_string(vertex_shader, win_shader_glsl, &gd->win_shader);
|
||||
if (!gl_init_blur(gd, ps->o.blur_kerns)) {
|
||||
return false;
|
||||
@ -874,9 +870,10 @@ static inline void gl_free_blur_shader(gl_blur_shader_t *shader) {
|
||||
|
||||
void gl_deinit(struct gl_data *gd) {
|
||||
// Free GLSL shaders/programs
|
||||
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
||||
for (int i = 0; i < gd->npasses; ++i) {
|
||||
gl_free_blur_shader(&gd->blur_shader[i]);
|
||||
}
|
||||
free(gd->blur_shader);
|
||||
|
||||
gl_free_prog_main(&gd->win_shader);
|
||||
|
||||
|
@ -69,7 +69,7 @@ struct gl_data {
|
||||
int npasses;
|
||||
gl_win_shader_t win_shader;
|
||||
gl_fill_shader_t fill_shader;
|
||||
gl_blur_shader_t blur_shader[MAX_BLUR_PASS];
|
||||
gl_blur_shader_t *blur_shader;
|
||||
|
||||
// Temporary textures used for blurring. They are always the same size as the
|
||||
// target, so they are always big enough without resizing.
|
||||
|
@ -60,9 +60,7 @@ typedef struct _xrender_data {
|
||||
int target_width, target_height;
|
||||
|
||||
/// Blur kernels converted to X format
|
||||
xcb_render_fixed_t *x_blur_kern[MAX_BLUR_PASS];
|
||||
/// Number of elements in each blur kernel
|
||||
int x_blur_kern_size[MAX_BLUR_PASS];
|
||||
struct x_convolution_kernel **x_blur_kern;
|
||||
|
||||
xcb_special_event_t *present_event;
|
||||
} xrender_data;
|
||||
@ -178,15 +176,13 @@ static bool blur(backend_t *backend_data, double opacity, const region_t *reg_bl
|
||||
// back -(pass 1)-> tmp0 -(copy)-> target_buffer
|
||||
int i;
|
||||
for (i = 0; xd->x_blur_kern[i]; i++) {
|
||||
assert(i < MAX_BLUR_PASS - 1);
|
||||
|
||||
// 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_size[i]), xd->x_blur_kern[i]);
|
||||
to_u32_checked(xd->x_blur_kern[i]->size), xd->x_blur_kern[i]->kernel);
|
||||
|
||||
if (xd->x_blur_kern[i + 1] || i == 0) {
|
||||
// This is not the last pass, or this is the first pass
|
||||
@ -276,6 +272,7 @@ static void deinit(backend_t *backend_data) {
|
||||
for (int i = 0; xd->x_blur_kern[i]; i++) {
|
||||
free(xd->x_blur_kern[i]);
|
||||
}
|
||||
free(xd->x_blur_kern);
|
||||
if (xd->present_event) {
|
||||
xcb_unregister_for_special_event(xd->base.c, xd->present_event);
|
||||
}
|
||||
@ -377,8 +374,8 @@ static bool image_op(backend_t *base, enum image_operations op, void *image,
|
||||
XCB_NONE, tmp_pict, 0, 0, 0, 0, 0, 0, tmpw, tmph);
|
||||
|
||||
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_DIFFERENCE,
|
||||
xd->white_pixel, XCB_NONE, img->pict, 0, 0, 0,
|
||||
0, 0, 0, tmpw, tmph);
|
||||
xd->white_pixel, XCB_NONE, img->pict, 0, 0,
|
||||
0, 0, 0, 0, tmpw, tmph);
|
||||
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_IN_REVERSE,
|
||||
tmp_pict, XCB_NONE, img->pict, 0, 0, 0, 0, 0,
|
||||
0, tmpw, tmph);
|
||||
@ -549,10 +546,14 @@ backend_t *backend_xrender_init(session_t *ps) {
|
||||
xd->root_pict = x_create_picture_with_visual_and_pixmap(
|
||||
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++) {
|
||||
assert(i < MAX_BLUR_PASS - 1);
|
||||
xd->x_blur_kern_size[i] = x_picture_filter_from_conv(
|
||||
ps->o.blur_kerns[i], 1, &xd->x_blur_kern[i], (size_t[]){0});
|
||||
x_create_convolution_kernel(ps->o.blur_kerns[i], 1, &xd->x_blur_kern[i]);
|
||||
}
|
||||
return &xd->base;
|
||||
err:
|
||||
|
Reference in New Issue
Block a user