Improvement: --blur-background-exclude #98 & MESA_swap_control & others

- Add --blur-background-exclude. (#98)

- Add `opengl-mswc` VSync, which uses MESA_swap_control instead of
  SGI_swap_control. I don't expect it to perform better than
  SGI_swap_control, though.

- Update CMakeLists.txt .

- Add a few targets for D-Bus `win_get`. Misc changes.

- Known issue: Apparently I've forgotten implementing --inactive-dim on
  GLX backend... Silly me.
This commit is contained in:
Richard Grenville 2013-03-23 22:06:41 +08:00
parent 65cda415dd
commit 75912d23f3
7 changed files with 131 additions and 18 deletions

View File

@ -8,14 +8,19 @@ set(CPACK_PACKAGE_VERSION_PATCH "0")
add_subdirectory(man)
set(compton_SRCS src/compton.c)
add_executable(compton ${compton_SRCS})
set(CMAKE_C_FLAGS_DEBUG "-ggdb")
set(CMAKE_C_FLAGS_RELEASE "-O2 -march=native")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -march=native -ggdb")
set(CMAKE_C_FLAGS_RELWITHDBGINFO "-O2 -march=native -ggdb")
add_definitions("-Wall" "-std=c99")
# == Version ==
execute_process(COMMAND sh -c "echo -n \\\"git-$(git describe --always --dirty)-$(git log -1 --date=short --pretty=format:%cd)\\\""
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE COMPTON_VERSION)
add_definitions("-DCOMPTON_VERSION=${COMPTON_VERSION}")
# == Options ==
option(CONFIG_REGEX_PCRE "Enable PCRE regular expression support for blacklist entries (requires libpcre)" ON)
@ -38,11 +43,20 @@ if (CONFIG_VSYNC_DRM)
add_definitions("-DCONFIG_VSYNC_DRM")
endif ()
option(CONFIG_VSYNC_OPENGL "Enable OpenGL VSync support" ON)
option(CONFIG_VSYNC_OPENGL "Enable OpenGL support" ON)
if (CONFIG_VSYNC_OPENGL)
add_definitions("-DCONFIG_VSYNC_OPENGL")
list(APPEND compton_SRCS src/opengl.c)
endif ()
option(CONFIG_C2 "Enable matching system" ON)
if (CONFIG_C2)
add_definitions("-DCONFIG_C2")
list(APPEND compton_SRCS src/c2.c)
endif ()
add_executable(compton ${compton_SRCS})
# == Find libraries ==
target_link_libraries(compton "-lm" "-lrt")
@ -74,12 +88,14 @@ X11LIB_CHK(Xrandr)
# --- Find libpcre ---
if (CONFIG_REGEX_PCRE)
pkg_check_modules(LIBPCRE REQUIRED libpcre>=8.12)
add_definitions("${LIBPCRE_CFLAGS}")
target_link_libraries(compton "${LIBPCRE_LDFLAGS}")
endif ()
# --- Find libconfig ---
if (CONFIG_LIBCONFIG)
pkg_check_modules(LIBCONFIG REQUIRED libconfig>=1.3.2)
add_definitions("${LIBCONFIG_CFLAGS}")
target_link_libraries(compton "${LIBCONFIG_LDFLAGS}")
if (LIBCONFIG_VERSION VERSION_LESS 1.4)
add_definitions("-DCONFIG_LIBCONFIG_LEGACY")
@ -91,6 +107,7 @@ endif ()
if (CONFIG_VSYNC_DRM)
pkg_check_modules(LIBDRM REQUIRED libdrm)
# We only use its header file
add_definitions("${LIBDRM_CFLAGS}")
endif ()
# == Install ==
@ -121,8 +138,8 @@ set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/desc.txt")
set(CPACK_GENERATOR "TBZ2" "DEB" "RPM")
set(CPACK_MONOLITHIC_INSTALL 1)
set(CPACK_STRIP_FILES 1)
set(CPACK_RESOURCE_FILE_LICENSE "LICENSE")
set(CPACK_RESOURCE_FILE_README "README.md")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.md")
# --- Source package config ---
set(CPACK_SOURCE_GENERATOR "TBZ2" "DEB" "RPM")

View File

@ -25,6 +25,7 @@ alpha-step = 0.06;
# blur-background = true;
# blur-background-frame = true;
blur-background-fixed = false;
blur-background-exclude = [ "window_type = 'dock'", "window_type = 'desktop'" ];
# Fading
fading = true;

View File

@ -120,7 +120,7 @@ OPTIONS
Specify refresh rate of the screen. If not specified or 0, compton will try detecting this with X RandR extension.
*--vsync* 'VSYNC_METHOD'::
Set VSync method. There are 3 VSync methods currently available:
Set VSync method. VSync methods currently available:
+
--
* 'none': No VSync
@ -128,6 +128,7 @@ OPTIONS
* 'opengl': Try to VSync with 'SGI_swap_control' OpenGL extension. Only work on some drivers. Experimental.
* 'opengl-oml': Try to VSync with 'OML_sync_control' OpenGL extension. Only work on some drivers. Experimental.
* 'opengl-swc': Try to VSync with 'SGI_swap_control' OpenGL extension. Only work on some drivers. Works only with GLX backend. Known to be most effective on many drivers. Does not actually control paint timing, only buffer swap is affected, so it doesn't have the effect of *--sw-opti* unlike other methods. Experimental.
* 'opengl-mswc': Try to VSync with 'MESA_swap_control' OpenGL extension. Basically the same as 'opengl-swc' above, except the extension we use.
(Note some VSync methods may not be enabled at compile time.)
--

View File

@ -260,6 +260,7 @@ typedef enum {
VSYNC_OPENGL,
VSYNC_OPENGL_OML,
VSYNC_OPENGL_SWC,
VSYNC_OPENGL_MSWC,
NUM_VSYNC,
} vsync_t;
@ -280,6 +281,7 @@ typedef Bool (*f_GetSyncValuesOML) (Display* dpy, GLXDrawable drawable, int64_t*
typedef Bool (*f_WaitForMscOML) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc);
typedef int (*f_SwapIntervalSGI) (int interval);
typedef int (*f_SwapIntervalMESA) (unsigned int interval);
typedef void (*f_BindTexImageEXT) (Display *display, GLXDrawable drawable, int buffer, const int *attrib_list);
typedef void (*f_ReleaseTexImageEXT) (Display *display, GLXDrawable drawable, int buffer);
@ -443,6 +445,8 @@ typedef struct {
/// Whether to use fixed blur strength instead of adjusting according
/// to window opacity.
bool blur_background_fixed;
/// Background blur blacklist. A linked list of conditions.
c2_lptr_t *blur_background_blacklist;
/// 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
@ -624,6 +628,8 @@ typedef struct {
f_WaitForMscOML glXWaitForMscOML;
/// Pointer to glXSwapIntervalSGI function.
f_SwapIntervalSGI glXSwapIntervalProc;
/// Pointer to glXSwapIntervalMESA function.
f_SwapIntervalMESA glXSwapIntervalMESAProc;
/// Pointer to glXBindTexImageEXT function.
f_BindTexImageEXT glXBindTexImageProc;
/// Pointer to glXReleaseTexImageEXT function.
@ -821,6 +827,7 @@ typedef struct _win {
const c2_lptr_t *cache_fblst;
const c2_lptr_t *cache_fcblst;
const c2_lptr_t *cache_ivclst;
const c2_lptr_t *cache_bbblst;
// Opacity-related members
/// Current window opacity.
@ -880,6 +887,9 @@ typedef struct _win {
/// Override value of window color inversion state. Set by D-Bus method
/// calls.
switch_t invert_color_force;
/// Whether to blur window background.
bool blur_background;
} win;
/// Temporary structure used for communication between

View File

@ -33,11 +33,12 @@ const char * const WINTYPES[NUM_WINTYPES] = {
/// Names of VSync modes.
const char * const VSYNC_STRS[NUM_VSYNC] = {
"none", // VSYNC_NONE
"drm", // VSYNC_DRM
"opengl", // VSYNC_OPENGL
"opengl-oml", // VSYNC_OPENGL_OML
"opengl-swc", // VSYNC_OPENGL_SWC
"none", // VSYNC_NONE
"drm", // VSYNC_DRM
"opengl", // VSYNC_OPENGL
"opengl-oml", // VSYNC_OPENGL_OML
"opengl-swc", // VSYNC_OPENGL_SWC
"opengl-mswc", // VSYNC_OPENGL_MSWC
};
/// Names of backends.
@ -48,10 +49,11 @@ const char * const BACKEND_STRS[NUM_BKEND] = {
/// Function pointers to init VSync modes.
static bool (* const (VSYNC_FUNCS_INIT[NUM_VSYNC]))(session_t *ps) = {
[VSYNC_DRM ] = vsync_drm_init,
[VSYNC_OPENGL ] = vsync_opengl_init,
[VSYNC_OPENGL_OML ] = vsync_opengl_oml_init,
[VSYNC_OPENGL_SWC ] = vsync_opengl_swc_init,
[VSYNC_DRM ] = vsync_drm_init,
[VSYNC_OPENGL ] = vsync_opengl_init,
[VSYNC_OPENGL_OML ] = vsync_opengl_oml_init,
[VSYNC_OPENGL_SWC ] = vsync_opengl_swc_init,
[VSYNC_OPENGL_MSWC ] = vsync_opengl_mswc_init,
};
/// Function pointers to wait for VSync.
@ -1560,7 +1562,8 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint) {
free_picture(ps, &pict);
// Dimming the window if needed
if (w->dim && w->dim_alpha_pict != ps->alpha_picts[0]) {
if (BKEND_XRENDER == ps->o.backend
&& w->dim && w->dim_alpha_pict != ps->alpha_picts[0]) {
XRenderComposite(ps->dpy, PictOpOver, ps->black_picture,
w->dim_alpha_pict, ps->tgt_buffer, 0, 0, 0, 0, x, y, wid, hei);
}
@ -1725,8 +1728,8 @@ paint_all(session_t *ps, XserverRegion region, win *t) {
if (!is_region_empty(ps, reg_paint)) {
set_tgt_clip(ps, reg_paint);
// Blur window background
if ((ps->o.blur_background && WMODE_SOLID != w->mode)
|| (ps->o.blur_background_frame && w->frame_opacity)) {
if (w->blur_background && (WMODE_SOLID != w->mode
|| (ps->o.blur_background_frame && w->frame_opacity))) {
win_blur_background(ps, w, ps->tgt_buffer, reg_paint);
}
@ -1977,6 +1980,8 @@ map_win(session_t *ps, Window id) {
}
win_determine_fade(ps, w);
win_determine_blur_background(ps, w);
w->damaged = false;
/* if any configure events happened while
@ -2292,6 +2297,23 @@ win_determine_invert_color(session_t *ps, win *w) {
add_damage_win(ps, w);
}
/**
* Determine if a window should have background blurred.
*/
static void
win_determine_blur_background(session_t *ps, win *w) {
bool blur_background_old = w->blur_background;
w->blur_background = ps->o.blur_background
&& !win_match(ps, w, ps->o.blur_background_blacklist, &w->cache_bbblst);
// Only consider window damaged if it's previously painted with background
// blurred
if (w->blur_background != blur_background_old && (WMODE_SOLID != w->mode
|| (ps->o.blur_background_frame && w->frame_opacity)))
add_damage_win(ps, w);
}
/**
* Function to be called on window type changes.
*/
@ -2317,6 +2339,8 @@ win_on_factor_change(session_t *ps, win *w) {
win_determine_invert_color(ps, w);
if (ps->o.focus_blacklist)
win_update_focused(ps, w);
if (ps->o.blur_background_blacklist)
win_determine_blur_background(ps, w);
}
/**
@ -2533,6 +2557,7 @@ add_win(session_t *ps, Window id, Window prev) {
.cache_fblst = NULL,
.cache_fcblst = NULL,
.cache_ivclst = NULL,
.cache_bbblst = NULL,
.opacity = 0,
.opacity_tgt = 0,
@ -2563,6 +2588,8 @@ add_win(session_t *ps, Window id, Window prev) {
.invert_color = false,
.invert_color_force = UNSET,
.blur_background = false,
};
// Reject overlay window and already added windows
@ -4097,6 +4124,9 @@ usage(void) {
" Does not actually control paint timing, only buffer swap is\n"
" affected, so it doesn't have the effect of --sw-opti unlike\n"
" other methods. Experimental." WARNING "\n"
" opengl-mswc = Try to VSync with MESA_swap_control OpenGL\n"
" extension. Basically the same as opengl-swc above, except the\n"
" extension we use." WARNING "\n"
"--alpha-step val\n"
" Step for pregenerating alpha pictures. 0.01 - 1.0. Defaults to\n"
" 0.03.\n"
@ -4549,6 +4579,8 @@ parse_config(session_t *ps, struct options_tmp *pcfgtmp) {
parse_cfg_condlst(ps, &cfg, &ps->o.focus_blacklist, "focus-exclude");
// --invert-color-include
parse_cfg_condlst(ps, &cfg, &ps->o.invert_color_list, "invert-color-include");
// --blur-background-exclude
parse_cfg_condlst(ps, &cfg, &ps->o.blur_background_blacklist, "blur-background-exclude");
// --blur-background
lcfg_lookup_bool(&cfg, "blur-background", &ps->o.blur_background);
// --blur-background-frame
@ -4630,6 +4662,7 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
{ "benchmark", required_argument, NULL, 293 },
{ "benchmark-wid", required_argument, NULL, 294 },
{ "glx-use-copysubbuffermesa", no_argument, NULL, 295 },
{ "blur-background-exclude", required_argument, NULL, 296 },
// Must terminate with a NULL entry
{ NULL, 0, NULL, 0 },
};
@ -4912,6 +4945,10 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
// --glx-use-copysubbuffermesa
ps->o.glx_use_copysubbuffermesa = true;
break;
case 296:
// --blur-background-exclude
condlst_add(ps, &ps->o.blur_background_blacklist, optarg);
break;
default:
usage();
break;
@ -4955,6 +4992,10 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
if (ps->o.blur_background_frame)
ps->o.blur_background = true;
// Free background blur blacklist if background blur is not actually enabled
if (!ps->o.blur_background)
free_wincondlst(&ps->o.blur_background_blacklist);
// Other variables determined by options
// Determine whether we need to track focus changes
@ -5238,6 +5279,34 @@ vsync_opengl_swc_init(session_t *ps) {
#endif
}
static bool
vsync_opengl_mswc_init(session_t *ps) {
#ifdef CONFIG_VSYNC_OPENGL
if (!ensure_glx_context(ps))
return false;
if (BKEND_GLX != ps->o.backend) {
printf_errf("(): I'm afraid glXSwapIntervalMESA wouldn't help if you are "
"not using GLX backend. You could try, nonetheless.");
}
// Get video sync functions
if (!ps->glXSwapIntervalMESAProc)
ps->glXSwapIntervalMESAProc = (f_SwapIntervalMESA)
glXGetProcAddress ((const GLubyte *) "glXSwapIntervalMESA");
if (!ps->glXSwapIntervalMESAProc) {
printf_errf("(): Failed to get MESA_swap_control function.");
return false;
}
ps->glXSwapIntervalMESAProc(1);
return true;
#else
printf_errf("(): Program not compiled with OpenGL VSync support.");
return false;
#endif
}
#ifdef CONFIG_VSYNC_OPENGL
/**
* Wait for next VSync, OpenGL method.
@ -5759,6 +5828,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
.blur_background = false,
.blur_background_frame = false,
.blur_background_fixed = false,
.blur_background_blacklist = NULL,
.inactive_dim = 0.0,
.inactive_dim_fixed = false,
.invert_color_list = NULL,

View File

@ -667,6 +667,12 @@ win_update_prop_shadow(session_t *ps, win *w);
static void
win_determine_shadow(session_t *ps, win *w);
static void
win_determine_invert_color(session_t *ps, win *w);
static void
win_determine_blur_background(session_t *ps, win *w);
static void
win_on_wtype_change(session_t *ps, win *w);
@ -988,6 +994,9 @@ vsync_opengl_oml_init(session_t *ps);
static bool
vsync_opengl_swc_init(session_t *ps);
static bool
vsync_opengl_mswc_init(session_t *ps);
#ifdef CONFIG_VSYNC_OPENGL
static int
vsync_opengl_wait(session_t *ps);

View File

@ -716,6 +716,11 @@ cdbus_process_win_get(session_t *ps, DBusMessage *msg) {
cdbus_m_win_get_do(right_width, cdbus_reply_uint32);
cdbus_m_win_get_do(top_width, cdbus_reply_uint32);
cdbus_m_win_get_do(bottom_width, cdbus_reply_uint32);
cdbus_m_win_get_do(shadow, cdbus_reply_bool);
cdbus_m_win_get_do(fade, cdbus_reply_bool);
cdbus_m_win_get_do(invert_color, cdbus_reply_bool);
cdbus_m_win_get_do(blur_background, cdbus_reply_bool);
#undef cdbus_m_win_get_do
printf_errf("(): " CDBUS_ERROR_BADTGT_S, target);