Improvement: Improve color inversion performance & Validate pixmap
- Try to improve the performance of color inversion by applying clipping region during color inversion. (#75) - Validate pixmap on window unmap/destruction. Probably slightly helpful for #52. - Change the design of unmap_win() and destroy_win(), a bit. - Add warning message to help messages about features disabled at compile time, instead of dropping their description completely. (#85) - Silence some warnings. Code clean-up.
This commit is contained in:
parent
152ad5fb57
commit
42e17cb4e9
|
@ -629,6 +629,32 @@ win_rounded_corners(session_t *ps, win *w) {
|
|||
XFree(rects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate pixmap of a window, and destroy pixmap and picture if invalid.
|
||||
*/
|
||||
static void
|
||||
win_validate_pixmap(session_t *ps, win *w) {
|
||||
if (!w->pixmap)
|
||||
return;
|
||||
|
||||
// Detect whether the pixmap is valid with XGetGeometry. Well, maybe there
|
||||
// are better ways.
|
||||
bool invalid = false;
|
||||
{
|
||||
Window rroot = None;
|
||||
int rx = 0, ry = 0;
|
||||
unsigned rwid = 0, rhei = 0, rborder = 0, rdepth = 0;
|
||||
invalid = (!XGetGeometry(ps->dpy, w->pixmap, &rroot, &rx, &ry,
|
||||
&rwid, &rhei, &rborder, &rdepth) || !rwid || !rhei);
|
||||
}
|
||||
|
||||
// Destroy pixmap and picture, if invalid
|
||||
if (invalid) {
|
||||
free_pixmap(ps, &w->pixmap);
|
||||
free_picture(ps, &w->picture);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pattern to a condition linked list.
|
||||
*/
|
||||
|
@ -678,7 +704,7 @@ determine_evmask(session_t *ps, Window wid, win_evmode_t mode) {
|
|||
* Find out the WM frame of a client window by querying X.
|
||||
*
|
||||
* @param ps current session
|
||||
* @param w window ID
|
||||
* @param wid window ID
|
||||
* @return struct _win object of the found window, NULL if not found
|
||||
*/
|
||||
static win *
|
||||
|
@ -1360,7 +1386,7 @@ win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
|||
* Paint a window itself and dim it if asked.
|
||||
*/
|
||||
static inline void
|
||||
win_paint_win(session_t *ps, win *w, Picture tgt_buffer) {
|
||||
win_paint_win(session_t *ps, win *w, Picture tgt_buffer, XserverRegion reg_paint) {
|
||||
int x = w->a.x;
|
||||
int y = w->a.y;
|
||||
int wid = w->widthb;
|
||||
|
@ -1374,6 +1400,14 @@ win_paint_win(session_t *ps, win *w, Picture tgt_buffer) {
|
|||
if (w->invert_color) {
|
||||
Picture newpict = win_build_picture(ps, w, w->a.visual);
|
||||
if (newpict) {
|
||||
// Apply clipping region to save some CPU
|
||||
if (reg_paint) {
|
||||
XserverRegion reg = copy_region(ps, reg_paint);
|
||||
XFixesTranslateRegion(ps->dpy, reg, -x, -y);
|
||||
XFixesSetPictureClipRegion(ps->dpy, newpict, 0, 0, reg);
|
||||
free_region(ps, ®);
|
||||
}
|
||||
|
||||
XRenderComposite(ps->dpy, PictOpSrc, pict, None,
|
||||
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
||||
XRenderComposite(ps->dpy, PictOpDifference, ps->white_picture, None,
|
||||
|
@ -1602,7 +1636,7 @@ paint_all(session_t *ps, XserverRegion region, win *t) {
|
|||
}
|
||||
|
||||
// Painting the window
|
||||
win_paint_win(ps, w, ps->tgt_buffer);
|
||||
win_paint_win(ps, w, ps->tgt_buffer, reg_paint);
|
||||
}
|
||||
|
||||
check_fade_fin(ps, w);
|
||||
|
@ -1706,12 +1740,10 @@ repair_win(session_t *ps, win *w) {
|
|||
|
||||
static wintype_t
|
||||
wid_get_prop_wintype(session_t *ps, Window wid) {
|
||||
int i;
|
||||
|
||||
set_ignore_next(ps);
|
||||
winprop_t prop = wid_get_prop(ps, wid, ps->atom_win_type, 32L, XA_ATOM, 32);
|
||||
|
||||
for (i = 0; i < prop.nitems; ++i) {
|
||||
for (unsigned i = 0; i < prop.nitems; ++i) {
|
||||
for (wintype_t j = 1; j < NUM_WINTYPES; ++j) {
|
||||
if (ps->atoms_wintypes[j] == (Atom) prop.data.p32[i]) {
|
||||
free_winprop(&prop);
|
||||
|
@ -1862,9 +1894,7 @@ unmap_callback(session_t *ps, win *w) {
|
|||
}
|
||||
|
||||
static void
|
||||
unmap_win(session_t *ps, Window id) {
|
||||
win *w = find_win(ps, id);
|
||||
|
||||
unmap_win(session_t *ps, win *w) {
|
||||
if (!w || IsUnmapped == w->a.map_state) return;
|
||||
|
||||
// Set focus out
|
||||
|
@ -1877,8 +1907,12 @@ unmap_win(session_t *ps, Window id) {
|
|||
set_fade_callback(ps, w, unmap_callback, false);
|
||||
if (ps->o.no_fading_openclose) {
|
||||
w->in_openclose = true;
|
||||
win_determine_fade(ps, w);
|
||||
}
|
||||
win_determine_fade(ps, w);
|
||||
|
||||
// Validate pixmap if we have to do fading
|
||||
if (w->fade)
|
||||
win_validate_pixmap(ps, w);
|
||||
|
||||
// don't care about properties anymore
|
||||
win_ev_stop(ps, w);
|
||||
|
@ -2612,6 +2646,8 @@ configure_win(session_t *ps, XConfigureEvent *ce) {
|
|||
}
|
||||
}
|
||||
|
||||
// override_redirect flag cannot be changed after window creation, as far
|
||||
// as I know, so there's no point to re-match windows here.
|
||||
w->a.override_redirect = ce->override_redirect;
|
||||
}
|
||||
|
||||
|
@ -2662,10 +2698,11 @@ destroy_win(session_t *ps, Window id) {
|
|||
win *w = find_win(ps, id);
|
||||
|
||||
if (w) {
|
||||
unmap_win(ps, w);
|
||||
|
||||
w->destroyed = true;
|
||||
|
||||
// Fading out the window
|
||||
w->flags |= WFLAG_OPCT_CHANGE;
|
||||
// Set fading callback
|
||||
set_fade_callback(ps, w, destroy_callback, false);
|
||||
|
||||
#ifdef CONFIG_DBUS
|
||||
|
@ -3364,7 +3401,10 @@ ev_map_notify(session_t *ps, XMapEvent *ev) {
|
|||
|
||||
inline static void
|
||||
ev_unmap_notify(session_t *ps, XUnmapEvent *ev) {
|
||||
unmap_win(ps, ev->window);
|
||||
win *w = find_win(ps, ev->window);
|
||||
|
||||
if (w)
|
||||
unmap_win(ps, w);
|
||||
}
|
||||
|
||||
inline static void
|
||||
|
@ -3745,6 +3785,8 @@ ev_handle(session_t *ps, XEvent *ev) {
|
|||
*/
|
||||
static void
|
||||
usage(void) {
|
||||
#define WARNING_DISABLED " (DISABLED AT COMPILE TIME)"
|
||||
#define WARNING
|
||||
const static char *usage_text =
|
||||
"compton (" COMPTON_VERSION ")\n"
|
||||
"usage: compton [options]\n"
|
||||
|
@ -3825,14 +3867,22 @@ usage(void) {
|
|||
" Set VSync method. There are up to 2 VSync methods currently available\n"
|
||||
" depending on your compile time settings:\n"
|
||||
" none = No VSync\n"
|
||||
#ifdef CONFIG_VSYNC_DRM
|
||||
#undef WARNING
|
||||
#ifndef CONFIG_VSYNC_DRM
|
||||
#define WARNING WARNING_DISABLED
|
||||
#else
|
||||
#define WARNING
|
||||
#endif
|
||||
" drm = VSync with DRM_IOCTL_WAIT_VBLANK. May only work on some\n"
|
||||
" drivers. Experimental.\n"
|
||||
" drivers. Experimental." WARNING "\n"
|
||||
#undef WARNING
|
||||
#ifndef CONFIG_VSYNC_OPENGL
|
||||
#define WARNING WARNING_DISABLED
|
||||
#else
|
||||
#define WARNING
|
||||
#endif
|
||||
#ifdef CONFIG_VSYNC_OPENGL
|
||||
" opengl = Try to VSync with SGI_swap_control OpenGL extension. Only\n"
|
||||
" work on some drivers. Experimental.\n"
|
||||
#endif
|
||||
" work on some drivers. Experimental." WARNING"\n"
|
||||
"--alpha-step val\n"
|
||||
" Step for pregenerating alpha pictures. 0.01 - 1.0. Defaults to\n"
|
||||
" 0.03.\n"
|
||||
|
@ -3883,13 +3933,18 @@ usage(void) {
|
|||
"--invert-color-include condition\n"
|
||||
" Specify a list of conditions of windows that should be painted with\n"
|
||||
" inverted color. Resource-hogging, and is not well tested.\n"
|
||||
#ifdef CONFIG_DBUS
|
||||
#undef WARNING
|
||||
#ifndef CONFIG_DBUS
|
||||
#define WARNING WARNING_DISABLED
|
||||
#else
|
||||
#define WARNING
|
||||
#endif
|
||||
"--dbus\n"
|
||||
" Enable remote control via D-Bus. See the D-BUS API section in the\n"
|
||||
" man page for more details.\n"
|
||||
#endif
|
||||
;
|
||||
" man page for more details." WARNING "\n";
|
||||
fputs(usage_text , stderr);
|
||||
#undef WARNING
|
||||
#undef WARNING_DISABLED
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ win_ev_stop(session_t *ps, win *w) {
|
|||
/**
|
||||
* Get the children of a window.
|
||||
*
|
||||
* @param session_t current session
|
||||
* @param ps current session
|
||||
* @param w window to check
|
||||
* @param children [out] an array of child window IDs
|
||||
* @param nchildren [out] number of children
|
||||
|
@ -374,6 +374,9 @@ win_is_fullscreen(session_t *ps, const win *w) {
|
|||
static void
|
||||
win_rounded_corners(session_t *ps, win *w);
|
||||
|
||||
static void
|
||||
win_validate_pixmap(session_t *ps, win *w);
|
||||
|
||||
/**
|
||||
* Wrapper of c2_match().
|
||||
*/
|
||||
|
@ -492,7 +495,7 @@ static void
|
|||
unmap_callback(session_t *ps, win *w);
|
||||
|
||||
static void
|
||||
unmap_win(session_t *ps, Window id);
|
||||
unmap_win(session_t *ps, win *w);
|
||||
|
||||
static opacity_t
|
||||
wid_get_opacity_prop(session_t *ps, Window wid, opacity_t def);
|
||||
|
@ -900,7 +903,7 @@ redir_stop(session_t *ps);
|
|||
|
||||
static inline time_ms_t
|
||||
timeout_get_newrun(const timeout_t *ptmout) {
|
||||
return ptmout->firstrun + (max_l((ptmout->lastrun + (long) (ptmout->interval * TIMEOUT_RUN_TOLERANCE) - ptmout->firstrun) / ptmout->interval, (ptmout->lastrun + ptmout->interval * (1 - TIMEOUT_RUN_TOLERANCE) - ptmout->firstrun) / ptmout->interval) + 1) * ptmout->interval;
|
||||
return ptmout->firstrun + (max_l((ptmout->lastrun + (time_ms_t) (ptmout->interval * TIMEOUT_RUN_TOLERANCE) - ptmout->firstrun) / ptmout->interval, (ptmout->lastrun + (time_ms_t) (ptmout->interval * (1 - TIMEOUT_RUN_TOLERANCE)) - ptmout->firstrun) / ptmout->interval) + 1) * ptmout->interval;
|
||||
}
|
||||
|
||||
static time_ms_t
|
||||
|
|
Loading…
Reference in New Issue