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