Move a few more functions into render.c
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
e29d9510ed
commit
9ce1387f52
151
src/compton.c
151
src/compton.c
|
@ -451,48 +451,6 @@ presum_gaussian(session_t *ps, conv *map) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a 1x1 <code>Picture</code> of a particular color.
|
|
||||||
*/
|
|
||||||
static xcb_render_picture_t
|
|
||||||
solid_picture(session_t *ps, bool argb, double a,
|
|
||||||
double r, double g, double b) {
|
|
||||||
xcb_pixmap_t pixmap;
|
|
||||||
xcb_render_picture_t picture;
|
|
||||||
xcb_render_create_picture_value_list_t pa;
|
|
||||||
xcb_render_color_t col;
|
|
||||||
xcb_rectangle_t rect;
|
|
||||||
|
|
||||||
pixmap = x_create_pixmap(ps, argb ? 32 : 8, ps->root, 1, 1);
|
|
||||||
if (!pixmap) return None;
|
|
||||||
|
|
||||||
pa.repeat = True;
|
|
||||||
picture = x_create_picture_with_standard_and_pixmap(ps,
|
|
||||||
argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
|
|
||||||
XCB_RENDER_CP_REPEAT, &pa);
|
|
||||||
|
|
||||||
if (!picture) {
|
|
||||||
xcb_free_pixmap(ps->c, pixmap);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
col.alpha = a * 0xffff;
|
|
||||||
col.red = r * 0xffff;
|
|
||||||
col.green = g * 0xffff;
|
|
||||||
col.blue = b * 0xffff;
|
|
||||||
|
|
||||||
rect.x = 0;
|
|
||||||
rect.y = 0;
|
|
||||||
rect.width = 1;
|
|
||||||
rect.height = 1;
|
|
||||||
|
|
||||||
xcb_render_fill_rectangles(ps->c, XCB_RENDER_PICT_OP_SRC, picture, col, 1, &rect);
|
|
||||||
xcb_free_pixmap(ps->c, pixmap);
|
|
||||||
|
|
||||||
return picture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// === Error handling ===
|
// === Error handling ===
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1177,9 +1135,6 @@ restack_win(session_t *ps, win *w, Window new_above) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
init_filters(session_t *ps);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
||||||
// On root window changes
|
// On root window changes
|
||||||
|
@ -1208,7 +1163,7 @@ configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
||||||
if (ps->o.glx_reinit_on_root_change && ps->psglx) {
|
if (ps->o.glx_reinit_on_root_change && ps->psglx) {
|
||||||
if (!glx_reinit(ps, bkend_use_glx(ps)))
|
if (!glx_reinit(ps, bkend_use_glx(ps)))
|
||||||
printf_errf("(): Failed to reinitialize GLX, troubles ahead.");
|
printf_errf("(): Failed to reinitialize GLX, troubles ahead.");
|
||||||
if (BKEND_GLX == ps->o.backend && !init_filters(ps))
|
if (BKEND_GLX == ps->o.backend && !glx_init_blur(ps))
|
||||||
printf_errf("(): Failed to initialize filters.");
|
printf_errf("(): Failed to initialize filters.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3212,20 +3167,6 @@ swopti_handle_timeout(session_t *ps) {
|
||||||
return (ps->refresh_intv - offset) / 1e6;
|
return (ps->refresh_intv - offset) / 1e6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Pregenerate alpha pictures.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
init_alpha_picts(session_t *ps) {
|
|
||||||
ps->alpha_picts = ccalloc(MAX_ALPHA+1, xcb_render_picture_t);
|
|
||||||
|
|
||||||
for (int i = 0; i <= MAX_ALPHA; ++i) {
|
|
||||||
double o = (double) i / MAX_ALPHA;
|
|
||||||
ps->alpha_picts[i] = solid_picture(ps, false, o, 0, 0, 0);
|
|
||||||
assert(ps->alpha_picts[i] != None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize X composite overlay window.
|
* Initialize X composite overlay window.
|
||||||
*/
|
*/
|
||||||
|
@ -3280,50 +3221,6 @@ init_overlay(session_t *ps) {
|
||||||
return ps->overlay;
|
return ps->overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Query needed X Render / OpenGL filters to check for their existence.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
init_filters(session_t *ps) {
|
|
||||||
// Blur filter
|
|
||||||
if (ps->o.blur_background || ps->o.blur_background_frame) {
|
|
||||||
switch (ps->o.backend) {
|
|
||||||
case BKEND_XRENDER:
|
|
||||||
case BKEND_XR_GLX_HYBRID:
|
|
||||||
{
|
|
||||||
// Query filters
|
|
||||||
xcb_render_query_filters_reply_t *pf = xcb_render_query_filters_reply(ps->c,
|
|
||||||
xcb_render_query_filters(ps->c, get_tgt_window(ps)), NULL);
|
|
||||||
if (pf) {
|
|
||||||
xcb_str_iterator_t iter = xcb_render_query_filters_filters_iterator(pf);
|
|
||||||
for (; iter.rem; xcb_str_next(&iter)) {
|
|
||||||
// Convolution filter
|
|
||||||
if (strlen(XRFILTER_CONVOLUTION) == xcb_str_name_length(iter.data)
|
|
||||||
&& !memcmp(XRFILTER_CONVOLUTION, xcb_str_name(iter.data), strlen(XRFILTER_CONVOLUTION)))
|
|
||||||
ps->xrfilter_convolution_exists = true;
|
|
||||||
}
|
|
||||||
free(pf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turn features off if any required filter is not present
|
|
||||||
if (!ps->xrfilter_convolution_exists) {
|
|
||||||
printf_errf("(): X Render convolution filter unsupported by your X server. Background blur is not possible.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_OPENGL
|
|
||||||
case BKEND_GLX:
|
|
||||||
return glx_init_blur(ps);
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect all windows.
|
* Redirect all windows.
|
||||||
*/
|
*/
|
||||||
|
@ -3927,32 +3824,15 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
// of OpenGL context.
|
// of OpenGL context.
|
||||||
init_overlay(ps);
|
init_overlay(ps);
|
||||||
|
|
||||||
|
// Initialize filters, must be preceded by OpenGL context creation
|
||||||
|
if (!init_render(ps))
|
||||||
|
exit(1);
|
||||||
|
|
||||||
if (ps->o.print_diagnostics) {
|
if (ps->o.print_diagnostics) {
|
||||||
print_diagnostics(ps);
|
print_diagnostics(ps);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize OpenGL as early as possible
|
|
||||||
if (bkend_use_glx(ps)) {
|
|
||||||
#ifdef CONFIG_OPENGL
|
|
||||||
if (!glx_init(ps, true))
|
|
||||||
exit(1);
|
|
||||||
#else
|
|
||||||
printf_errfq(1, "(): GLX backend support not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize window GL shader
|
|
||||||
if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
|
|
||||||
#ifdef CONFIG_OPENGL
|
|
||||||
if (!glx_load_prog_main(ps, NULL, ps->o.glx_fshader_win_str, &ps->o.glx_prog_win))
|
|
||||||
exit(1);
|
|
||||||
#else
|
|
||||||
printf_errf("(): GLSL supported not compiled in, can't load shader.");
|
|
||||||
exit(1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize software optimization
|
// Initialize software optimization
|
||||||
if (ps->o.sw_opti)
|
if (ps->o.sw_opti)
|
||||||
ps->o.sw_opti = swopti_init(ps);
|
ps->o.sw_opti = swopti_init(ps);
|
||||||
|
@ -3963,10 +3843,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
|| ps->o.xinerama_shadow_crop))
|
|| ps->o.xinerama_shadow_crop))
|
||||||
xcb_randr_select_input(ps->c, ps->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
|
xcb_randr_select_input(ps->c, ps->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
|
||||||
|
|
||||||
// Initialize VSync
|
|
||||||
if (!vsync_init(ps))
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
cxinerama_upd_scrs(ps);
|
cxinerama_upd_scrs(ps);
|
||||||
|
|
||||||
// Create registration window
|
// Create registration window
|
||||||
|
@ -3974,7 +3850,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
init_atoms(ps);
|
init_atoms(ps);
|
||||||
init_alpha_picts(ps);
|
|
||||||
|
|
||||||
ps->gaussian_map = gaussian_kernel(ps->o.shadow_radius);
|
ps->gaussian_map = gaussian_kernel(ps->o.shadow_radius);
|
||||||
presum_gaussian(ps, ps->gaussian_map);
|
presum_gaussian(ps, ps->gaussian_map);
|
||||||
|
@ -3993,22 +3868,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
ps->tgt_picture = ps->root_picture;
|
ps->tgt_picture = ps->root_picture;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize filters, must be preceded by OpenGL context creation
|
|
||||||
if (!init_filters(ps))
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
ps->black_picture = solid_picture(ps, true, 1, 0, 0, 0);
|
|
||||||
ps->white_picture = solid_picture(ps, true, 1, 1, 1, 1);
|
|
||||||
|
|
||||||
// Generates another Picture for shadows if the color is modified by
|
|
||||||
// user
|
|
||||||
if (!ps->o.shadow_red && !ps->o.shadow_green && !ps->o.shadow_blue) {
|
|
||||||
ps->cshadow_picture = ps->black_picture;
|
|
||||||
} else {
|
|
||||||
ps->cshadow_picture = solid_picture(ps, true, 1,
|
|
||||||
ps->o.shadow_red, ps->o.shadow_green, ps->o.shadow_blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
ev_io_init(&ps->xiow, x_event_callback, ConnectionNumber(ps->dpy), EV_READ);
|
ev_io_init(&ps->xiow, x_event_callback, ConnectionNumber(ps->dpy), EV_READ);
|
||||||
ev_io_start(ps->loop, &ps->xiow);
|
ev_io_start(ps->loop, &ps->xiow);
|
||||||
ev_init(&ps->unredir_timer, tmout_unredir_callback);
|
ev_init(&ps->unredir_timer, tmout_unredir_callback);
|
||||||
|
|
159
src/render.c
159
src/render.c
|
@ -1087,4 +1087,163 @@ void paint_all(session_t *ps, region_t *region, const region_t *region_real,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query needed X Render / OpenGL filters to check for their existence.
|
||||||
|
*/
|
||||||
|
static bool xr_init_blur(session_t *ps) {
|
||||||
|
// Query filters
|
||||||
|
xcb_render_query_filters_reply_t *pf = xcb_render_query_filters_reply(
|
||||||
|
ps->c, xcb_render_query_filters(ps->c, get_tgt_window(ps)), NULL);
|
||||||
|
if (pf) {
|
||||||
|
xcb_str_iterator_t iter =
|
||||||
|
xcb_render_query_filters_filters_iterator(pf);
|
||||||
|
for (; iter.rem; xcb_str_next(&iter)) {
|
||||||
|
int len = xcb_str_name_length(iter.data);
|
||||||
|
char *name = xcb_str_name(iter.data);
|
||||||
|
// Check for the convolution filter
|
||||||
|
if (strlen(XRFILTER_CONVOLUTION) == len &&
|
||||||
|
!memcmp(XRFILTER_CONVOLUTION, name,
|
||||||
|
strlen(XRFILTER_CONVOLUTION)))
|
||||||
|
ps->xrfilter_convolution_exists = true;
|
||||||
|
}
|
||||||
|
free(pf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn features off if any required filter is not present
|
||||||
|
if (!ps->xrfilter_convolution_exists) {
|
||||||
|
printf_errf("(): Xrender convolution filter "
|
||||||
|
"unsupported by your X server. "
|
||||||
|
"Background blur is not possible.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a 1x1 <code>Picture</code> of a particular color.
|
||||||
|
*/
|
||||||
|
static xcb_render_picture_t
|
||||||
|
solid_picture(session_t *ps, bool argb, double a, double r, double g, double b) {
|
||||||
|
xcb_pixmap_t pixmap;
|
||||||
|
xcb_render_picture_t picture;
|
||||||
|
xcb_render_create_picture_value_list_t pa;
|
||||||
|
xcb_render_color_t col;
|
||||||
|
xcb_rectangle_t rect;
|
||||||
|
|
||||||
|
pixmap = x_create_pixmap(ps, argb ? 32 : 8, ps->root, 1, 1);
|
||||||
|
if (!pixmap)
|
||||||
|
return XCB_NONE;
|
||||||
|
|
||||||
|
pa.repeat = True;
|
||||||
|
picture = x_create_picture_with_standard_and_pixmap(
|
||||||
|
ps, argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
|
||||||
|
XCB_RENDER_CP_REPEAT, &pa);
|
||||||
|
|
||||||
|
if (!picture) {
|
||||||
|
xcb_free_pixmap(ps->c, pixmap);
|
||||||
|
return XCB_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
col.alpha = a * 0xffff;
|
||||||
|
col.red = r * 0xffff;
|
||||||
|
col.green = g * 0xffff;
|
||||||
|
col.blue = b * 0xffff;
|
||||||
|
|
||||||
|
rect.x = 0;
|
||||||
|
rect.y = 0;
|
||||||
|
rect.width = 1;
|
||||||
|
rect.height = 1;
|
||||||
|
|
||||||
|
xcb_render_fill_rectangles(ps->c, XCB_RENDER_PICT_OP_SRC, picture, col, 1,
|
||||||
|
&rect);
|
||||||
|
xcb_free_pixmap(ps->c, pixmap);
|
||||||
|
|
||||||
|
return picture;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pregenerate alpha pictures.
|
||||||
|
*/
|
||||||
|
static bool init_alpha_picts(session_t *ps) {
|
||||||
|
ps->alpha_picts = ccalloc(MAX_ALPHA + 1, xcb_render_picture_t);
|
||||||
|
|
||||||
|
for (int i = 0; i <= MAX_ALPHA; ++i) {
|
||||||
|
double o = (double)i / MAX_ALPHA;
|
||||||
|
ps->alpha_picts[i] = solid_picture(ps, false, o, 0, 0, 0);
|
||||||
|
if (ps->alpha_picts[i] == XCB_NONE)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool init_render(session_t *ps) {
|
||||||
|
// Initialize OpenGL as early as possible
|
||||||
|
if (bkend_use_glx(ps)) {
|
||||||
|
#ifdef CONFIG_OPENGL
|
||||||
|
if (!glx_init(ps, true))
|
||||||
|
exit(1);
|
||||||
|
#else
|
||||||
|
printf_errfq(1, "(): GLX backend support not compiled in.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize VSync
|
||||||
|
if (!vsync_init(ps)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize window GL shader
|
||||||
|
if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
|
||||||
|
#ifdef CONFIG_OPENGL
|
||||||
|
if (!glx_load_prog_main(ps, NULL, ps->o.glx_fshader_win_str,
|
||||||
|
&ps->o.glx_prog_win))
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
printf_errf("(): GLSL supported not compiled in, can't load "
|
||||||
|
"shader.");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!init_alpha_picts(ps)) {
|
||||||
|
printf_errf("(): Failed to init alpha pictures.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blur filter
|
||||||
|
if (ps->o.blur_background || ps->o.blur_background_frame) {
|
||||||
|
bool ret;
|
||||||
|
if (ps->o.backend == BKEND_GLX)
|
||||||
|
ret = glx_init_blur(ps);
|
||||||
|
else
|
||||||
|
ret = xr_init_blur(ps);
|
||||||
|
if (!ret)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ps->black_picture = solid_picture(ps, true, 1, 0, 0, 0);
|
||||||
|
ps->white_picture = solid_picture(ps, true, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
if (ps->black_picture == XCB_NONE || ps->white_picture == XCB_NONE) {
|
||||||
|
printf_errf("(): Failed to create solid xrender pictures.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates another Picture for shadows if the color is modified by
|
||||||
|
// user
|
||||||
|
if (!ps->o.shadow_red && !ps->o.shadow_green && !ps->o.shadow_blue) {
|
||||||
|
ps->cshadow_picture = ps->black_picture;
|
||||||
|
} else {
|
||||||
|
ps->cshadow_picture =
|
||||||
|
solid_picture(ps, true, 1, ps->o.shadow_red, ps->o.shadow_green,
|
||||||
|
ps->o.shadow_blue);
|
||||||
|
if (ps->cshadow_picture == XCB_NONE) {
|
||||||
|
printf_errf("(): Failed to create shadow picture.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// vim: set ts=8 sw=8 noet :
|
// vim: set ts=8 sw=8 noet :
|
||||||
|
|
|
@ -30,3 +30,5 @@ paint_all(session_t *ps, region_t *region, const region_t *region_real, win * co
|
||||||
void free_picture(xcb_connection_t *c, xcb_render_picture_t *p);
|
void free_picture(xcb_connection_t *c, xcb_render_picture_t *p);
|
||||||
|
|
||||||
void free_paint(session_t *ps, paint_t *ppaint);
|
void free_paint(session_t *ps, paint_t *ppaint);
|
||||||
|
|
||||||
|
bool init_render(session_t *ps);
|
||||||
|
|
Loading…
Reference in New Issue