Improvement: Pregenerate alpha pictures
Pregenerate alpha pictures to save time when painting. Add --alpha-step to control the step of alpha picture generation (the opacity difference between two consecutively generated alpha pictures).
This commit is contained in:
parent
72ea4b5f47
commit
07e4420ab4
|
@ -35,3 +35,4 @@ install_manifest.txt
|
|||
core
|
||||
oprofile_data
|
||||
compton.plist
|
||||
callgrind.out.*
|
||||
|
|
|
@ -19,6 +19,7 @@ menu-opacity = 0.8;
|
|||
inactive-opacity = 0.8;
|
||||
frame-opacity = 0.7;
|
||||
inactive-opacity-override = false;
|
||||
alpha-step = 0.06;
|
||||
|
||||
# Fading
|
||||
fading = true;
|
||||
|
|
|
@ -52,6 +52,8 @@ Bool has_name_pixmap;
|
|||
#endif
|
||||
int root_height, root_width;
|
||||
|
||||
/// Pregenerated alpha pictures.
|
||||
Picture *alpha_picts = NULL;
|
||||
/// Whether the program is idling. I.e. no fading, no potential window
|
||||
/// changes.
|
||||
Bool idling;
|
||||
|
@ -187,6 +189,7 @@ static options_t opts = {
|
|||
.frame_opacity = 0.0,
|
||||
.detect_client_opacity = False,
|
||||
.inactive_dim = 0.0,
|
||||
.alpha_step = 0.03,
|
||||
|
||||
.track_focus = False,
|
||||
.track_wdata = False,
|
||||
|
@ -1282,6 +1285,17 @@ get_frame_extents(Display *dpy, win *w, Window client) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline Picture
|
||||
get_alpha_pict_d(double o) {
|
||||
assert((lround(normalize_d(o) / opts.alpha_step)) <= lround(1.0 / opts.alpha_step));
|
||||
return alpha_picts[lround(normalize_d(o) / opts.alpha_step)];
|
||||
}
|
||||
|
||||
static inline Picture
|
||||
get_alpha_pict_o(opacity_t o) {
|
||||
return get_alpha_pict_d((double) o / OPAQUE);
|
||||
}
|
||||
|
||||
static win *
|
||||
paint_preprocess(Display *dpy, win *list) {
|
||||
win *w;
|
||||
|
@ -1356,14 +1370,7 @@ paint_preprocess(Display *dpy, win *list) {
|
|||
add_damage_win(dpy, w);
|
||||
}
|
||||
|
||||
// Rebuild alpha_pict only if necessary
|
||||
if (OPAQUE != w->opacity
|
||||
&& (!w->alpha_pict || w->opacity != w->opacity_cur)) {
|
||||
free_picture(dpy, &w->alpha_pict);
|
||||
w->alpha_pict = solid_picture(
|
||||
dpy, False, get_opacity_percent(dpy, w), 0, 0, 0);
|
||||
w->opacity_cur = w->opacity;
|
||||
}
|
||||
w->alpha_pict = get_alpha_pict_o(w->opacity);
|
||||
|
||||
// Calculate frame_opacity
|
||||
if (opts.frame_opacity && 1.0 != opts.frame_opacity && w->top_width)
|
||||
|
@ -1371,15 +1378,7 @@ paint_preprocess(Display *dpy, win *list) {
|
|||
else
|
||||
w->frame_opacity = 0.0;
|
||||
|
||||
// Rebuild frame_alpha_pict only if necessary
|
||||
if (w->frame_opacity
|
||||
&& (!w->frame_alpha_pict
|
||||
|| w->frame_opacity != w->frame_opacity_cur)) {
|
||||
free_picture(dpy, &w->frame_alpha_pict);
|
||||
w->frame_alpha_pict = solid_picture(
|
||||
dpy, False, w->frame_opacity, 0, 0, 0);
|
||||
w->frame_opacity_cur = w->frame_opacity;
|
||||
}
|
||||
w->frame_alpha_pict = get_alpha_pict_d(w->frame_opacity);
|
||||
|
||||
// Calculate shadow opacity
|
||||
if (w->frame_opacity)
|
||||
|
@ -1396,15 +1395,7 @@ paint_preprocess(Display *dpy, win *list) {
|
|||
w->widthb, w->heightb);
|
||||
}
|
||||
|
||||
// Rebuild shadow_alpha_pict if necessary
|
||||
if (w->shadow
|
||||
&& (!w->shadow_alpha_pict
|
||||
|| w->shadow_opacity != w->shadow_opacity_cur)) {
|
||||
free_picture(dpy, &w->shadow_alpha_pict);
|
||||
w->shadow_alpha_pict = solid_picture(
|
||||
dpy, False, w->shadow_opacity, 0, 0, 0);
|
||||
w->shadow_opacity_cur = w->shadow_opacity;
|
||||
}
|
||||
w->shadow_alpha_pict = get_alpha_pict_d(w->shadow_opacity);
|
||||
|
||||
// Reset flags
|
||||
w->flags = 0;
|
||||
|
@ -2078,7 +2069,6 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) {
|
|||
new->extents = None;
|
||||
new->shadow = False;
|
||||
new->shadow_opacity = 0.0;
|
||||
new->shadow_opacity_cur = 0.0;
|
||||
new->shadow_pict = None;
|
||||
new->shadow_alpha_pict = None;
|
||||
new->shadow_dx = 0;
|
||||
|
@ -2087,7 +2077,6 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) {
|
|||
new->shadow_height = 0;
|
||||
new->opacity = 0;
|
||||
new->opacity_tgt = 0;
|
||||
new->opacity_cur = OPAQUE;
|
||||
new->opacity_prop = OPAQUE;
|
||||
new->opacity_prop_client = OPAQUE;
|
||||
new->fade = False;
|
||||
|
@ -2095,7 +2084,6 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) {
|
|||
new->fade_fin = False;
|
||||
new->alpha_pict = None;
|
||||
new->frame_opacity = 1.0;
|
||||
new->frame_opacity_cur = 1.0;
|
||||
new->frame_alpha_pict = None;
|
||||
new->dim = False;
|
||||
new->focused = False;
|
||||
|
@ -2284,8 +2272,6 @@ finish_destroy_win(Display *dpy, Window id) {
|
|||
finish_unmap_win(dpy, w);
|
||||
*prev = w->next;
|
||||
|
||||
free_picture(dpy, &w->alpha_pict);
|
||||
free_picture(dpy, &w->frame_alpha_pict);
|
||||
free_picture(dpy, &w->shadow_pict);
|
||||
free_damage(dpy, &w->damage);
|
||||
free(w->name);
|
||||
|
@ -3105,6 +3091,9 @@ usage(void) {
|
|||
" opengl = Try to VSync with SGI_swap_control OpenGL extension. Only\n"
|
||||
" work on some drivers. Experimental.\n"
|
||||
" (Note some VSync methods may not be enabled at compile time.)\n"
|
||||
"--alpha-step val\n"
|
||||
" Step for pregenerating alpha pictures. 0.01 - 1.0. Defaults to\n"
|
||||
" 0.03.\n"
|
||||
"\n"
|
||||
"Format of a condition:\n"
|
||||
"\n"
|
||||
|
@ -3421,6 +3410,8 @@ parse_config(char *cpath, struct options_tmp *pcfgtmp) {
|
|||
&opts.detect_client_opacity);
|
||||
// --refresh-rate
|
||||
lcfg_lookup_int(&cfg, "refresh-rate", &opts.refresh_rate);
|
||||
// --alpha-step
|
||||
config_lookup_float(&cfg, "alpha-step", &opts.alpha_step);
|
||||
// --shadow-exclude
|
||||
{
|
||||
config_setting_t *setting =
|
||||
|
@ -3486,6 +3477,7 @@ get_cfg(int argc, char *const *argv) {
|
|||
{ "detect-client-opacity", no_argument, NULL, 268 },
|
||||
{ "refresh-rate", required_argument, NULL, 269 },
|
||||
{ "vsync", required_argument, NULL, 270 },
|
||||
{ "alpha-step", required_argument, NULL, 271 },
|
||||
// Must terminate with a NULL entry
|
||||
{ NULL, 0, NULL, 0 },
|
||||
};
|
||||
|
@ -3668,6 +3660,10 @@ get_cfg(int argc, char *const *argv) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 271:
|
||||
// --alpha-step
|
||||
opts.alpha_step = atof(optarg);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
|
@ -3689,6 +3685,7 @@ get_cfg(int argc, char *const *argv) {
|
|||
opts.shadow_opacity = normalize_d(opts.shadow_opacity);
|
||||
cfgtmp.menu_opacity = normalize_d(cfgtmp.menu_opacity);
|
||||
opts.refresh_rate = normalize_i_range(opts.refresh_rate, 0, 300);
|
||||
opts.alpha_step = normalize_d_range(opts.alpha_step, 0.01, 1.0);
|
||||
if (OPAQUE == opts.inactive_opacity) {
|
||||
opts.inactive_opacity = 0;
|
||||
}
|
||||
|
@ -4028,6 +4025,25 @@ vsync_wait(Display *dpy, struct pollfd *fd, int timeout) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pregenerate alpha pictures.
|
||||
*/
|
||||
static void
|
||||
init_alpha_picts(Display *dpy) {
|
||||
int i;
|
||||
int num = lround(1.0 / opts.alpha_step) + 1;
|
||||
|
||||
alpha_picts = malloc(sizeof(Picture) * num);
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
double o = i * opts.alpha_step;
|
||||
if ((1.0 - o) > opts.alpha_step)
|
||||
alpha_picts[i] = solid_picture(dpy, False, o, 0, 0, 0);
|
||||
else
|
||||
alpha_picts[i] = None;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
XEvent ev;
|
||||
|
@ -4130,6 +4146,7 @@ main(int argc, char **argv) {
|
|||
if (opts.fork_after_register) fork_after();
|
||||
|
||||
get_atoms();
|
||||
init_alpha_picts(dpy);
|
||||
|
||||
pa.subwindow_mode = IncludeInferiors;
|
||||
|
||||
|
|
|
@ -221,8 +221,6 @@ typedef struct _win {
|
|||
opacity_t opacity;
|
||||
/// Target window opacity.
|
||||
opacity_t opacity_tgt;
|
||||
/// Opacity of current alpha_pict.
|
||||
opacity_t opacity_cur;
|
||||
/// Cached value of opacity window attribute.
|
||||
opacity_t opacity_prop;
|
||||
/// Cached value of opacity window attribute on client window. For
|
||||
|
@ -244,8 +242,6 @@ typedef struct _win {
|
|||
// Frame-opacity-related members
|
||||
/// Current window frame opacity. Affected by window opacity.
|
||||
double frame_opacity;
|
||||
/// Opacity of current frame_alpha_pict.
|
||||
opacity_t frame_opacity_cur;
|
||||
/// Alpha mask Picture to render window frame with opacity.
|
||||
Picture frame_alpha_pict;
|
||||
/// Frame widths. Determined by client window attributes.
|
||||
|
@ -256,8 +252,6 @@ typedef struct _win {
|
|||
Bool shadow;
|
||||
/// Opacity of the shadow. Affected by window opacity and frame opacity.
|
||||
double shadow_opacity;
|
||||
/// Opacity of current shadow_pict.
|
||||
double shadow_opacity_cur;
|
||||
/// X offset of shadow. Affected by commandline argument.
|
||||
int shadow_dx;
|
||||
/// Y offset of shadow. Affected by commandline argument.
|
||||
|
@ -359,6 +353,8 @@ typedef struct _options {
|
|||
Bool detect_client_opacity;
|
||||
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
||||
double inactive_dim;
|
||||
/// Step for pregenerating alpha pictures. 0.01 - 1.0.
|
||||
double alpha_step;
|
||||
|
||||
// Calculated
|
||||
/// Whether compton needs to track focus changes.
|
||||
|
@ -1125,3 +1121,6 @@ vsync_opengl_wait(void);
|
|||
|
||||
static Bool
|
||||
vsync_wait(Display *dpy, struct pollfd *fd, int timeout);
|
||||
|
||||
static void
|
||||
init_alpha_picts(Display *dpy);
|
||||
|
|
Loading…
Reference in New Issue