From ec76c5f286dac6902631782428caa68767bca22a Mon Sep 17 00:00:00 2001 From: Rytis Karpuska Date: Thu, 7 Nov 2019 02:19:20 +0200 Subject: [PATCH] parameterize max brightness limit --- picom.sample.conf | 2 ++ src/backend/backend.c | 7 +++++++ src/backend/backend.h | 2 ++ src/backend/gl/gl_common.c | 9 +++++++-- src/backend/gl/gl_common.h | 1 + src/backend/gl/glx.c | 1 + src/backend/xrender/xrender.c | 1 + src/config.c | 1 + src/config.h | 2 ++ src/config_libconfig.c | 7 +++++++ src/dbus.c | 2 ++ src/options.c | 17 +++++++++++++++++ 12 files changed, 50 insertions(+), 2 deletions(-) diff --git a/picom.sample.conf b/picom.sample.conf index 0ed48ab0..4e3a2069 100644 --- a/picom.sample.conf +++ b/picom.sample.conf @@ -39,6 +39,8 @@ blur-background-exclude = [ ]; # opacity-rule = [ "80:class_g = 'URxvt'" ]; +# max-brightness = 0.66 + # Fading fading = true; # fade-delta = 30; diff --git a/src/backend/backend.c b/src/backend/backend.c index 224c3696..a256c9c1 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -251,6 +251,13 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) { pixman_region32_fini(®_shadow); } + // Set max brightness + if (ps->o.max_brightness < 1.0) { + ps->backend_data->ops->image_op( + ps->backend_data, IMAGE_OP_MAX_BRIGHTNESS, w->win_image, + NULL, ®_visible, &ps->o.max_brightness); + } + // Draw window on target if (!w->invert_color && !w->dim && w->frame_opacity == 1 && w->opacity == 1) { ps->backend_data->ops->compose(ps->backend_data, w->win_image, diff --git a/src/backend/backend.h b/src/backend/backend.h index baa9c770..5a18e0ac 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -47,6 +47,8 @@ enum image_operations { // effective size. `reg_op` and `reg_visible` is ignored. `arg` is two integers, // width and height, in that order. IMAGE_OP_RESIZE_TILE, + // Limit how bright image can be + IMAGE_OP_MAX_BRIGHTNESS, }; struct gaussian_blur_args { diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index 1af7ff5e..8c015c1c 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -361,7 +361,9 @@ static void _gl_compose(backend_t *base, struct gl_image *img, GLuint target, return; } - GLuint brightness = gl_average_texture_color(base, img); + GLuint brightness = 0; + if (img->max_brightness < 1.0) + brightness = gl_average_texture_color(base, img); assert(gd->win_shader.prog); glUseProgram(gd->win_shader.prog); @@ -381,7 +383,7 @@ static void _gl_compose(backend_t *base, struct gl_image *img, GLuint target, glUniform1i(gd->win_shader.unifm_brightness, 1); } if (gd->win_shader.unifm_max_brightness >= 0) { - glUniform1f(gd->win_shader.unifm_max_brightness, 0.5); //TODO: parameterize + glUniform1f(gd->win_shader.unifm_max_brightness, (float)img->max_brightness); } // log_trace("Draw: %d, %d, %d, %d -> %d, %d (%d, %d) z %d\n", @@ -1436,6 +1438,9 @@ bool gl_image_op(backend_t *base, enum image_operations op, void *image_data, tex->ewidth = iargs[0]; tex->eheight = iargs[1]; break; + case IMAGE_OP_MAX_BRIGHTNESS: + tex->max_brightness = *(double *)arg; + break; } return true; diff --git a/src/backend/gl/gl_common.h b/src/backend/gl/gl_common.h index 0a2e35e8..41fe24f8 100644 --- a/src/backend/gl/gl_common.h +++ b/src/backend/gl/gl_common.h @@ -55,6 +55,7 @@ typedef struct gl_image { struct gl_texture *inner; double opacity; double dim; + double max_brightness; int ewidth, eheight; bool has_alpha; bool color_inverted; diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index c2e30236..5117e2f6 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -390,6 +390,7 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b log_trace("Binding pixmap %#010x", pixmap); auto wd = ccalloc(1, struct gl_image); + wd->max_brightness = 1; wd->inner = ccalloc(1, struct gl_texture); wd->inner->width = wd->ewidth = r->width; wd->inner->height = wd->eheight = r->height; diff --git a/src/backend/xrender/xrender.c b/src/backend/xrender/xrender.c index 8e7f9921..ab4e6643 100644 --- a/src/backend/xrender/xrender.c +++ b/src/backend/xrender/xrender.c @@ -458,6 +458,7 @@ static bool image_op(backend_t *base, enum image_operations op, void *image, img->eheight = iargs[1]; break; case IMAGE_OP_APPLY_ALPHA_ALL: assert(false); + case IMAGE_OP_MAX_BRIGHTNESS: assert(false); } pixman_region32_fini(®); return true; diff --git a/src/config.c b/src/config.c index c43ff0fc..95c79759 100644 --- a/src/config.c +++ b/src/config.c @@ -549,6 +549,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable, .inactive_dim_fixed = false, .invert_color_list = NULL, .opacity_rules = NULL, + .max_brightness = 1.0, .use_ewmh_active_win = false, .focus_blacklist = NULL, diff --git a/src/config.h b/src/config.h index a6a9f616..31a232c9 100644 --- a/src/config.h +++ b/src/config.h @@ -210,6 +210,8 @@ typedef struct options { c2_lptr_t *invert_color_list; /// Rules to change window opacity. c2_lptr_t *opacity_rules; + /// Limit window brightness + double max_brightness; // === Focus related === /// Whether to try to detect WM windows and mark them as focused. diff --git a/src/config_libconfig.c b/src/config_libconfig.c index 902ed91f..0f9f201d 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -422,6 +422,13 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad } // --use-damage lcfg_lookup_bool(&cfg, "use-damage", &opt->use_damage); + + // --max-brightness + if (config_lookup_float(&cfg, "max-brightness", &opt->max_brightness) && opt->use_damage) { + log_warn("max-brightness requires use-damage = false. Falling back to 1.0"); + opt->max_brightness = 1.0; + } + // --glx-use-gpushader4 if (config_lookup_bool(&cfg, "glx-use-gpushader4", &ival) && ival) { log_warn("glx-use-gpushader4 is deprecated since v6, please remove it " diff --git a/src/dbus.c b/src/dbus.c index 3161dbeb..b1218281 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -1035,6 +1035,8 @@ static bool cdbus_process_opts_get(session_t *ps, DBusMessage *msg) { cdbus_m_opts_get_do(inactive_dim, cdbus_reply_double); cdbus_m_opts_get_do(inactive_dim_fixed, cdbus_reply_bool); + cdbus_m_opts_get_do(max_brightness, cdbus_reply_double); + cdbus_m_opts_get_do(use_ewmh_active_win, cdbus_reply_bool); cdbus_m_opts_get_do(detect_transient, cdbus_reply_bool); cdbus_m_opts_get_do(detect_client_leader, cdbus_reply_bool); diff --git a/src/options.c b/src/options.c index c66fbfc0..79143bd8 100644 --- a/src/options.c +++ b/src/options.c @@ -185,6 +185,11 @@ static void usage(const char *argv0, int ret) { "--inactive-dim-fixed\n" " Use fixed inactive dim value.\n" "\n" + "--max-brightness\n" + " Dims windows which average brightness is above this threshold.\n" + " Requires --no-use-damage.\n" + " Default: 1.0 or no dimming.\n" + "\n" "--detect-transient\n" " Use WM_TRANSIENT_FOR to group windows, and consider windows in\n" " the same group focused at the same time.\n" @@ -410,6 +415,7 @@ static const struct option longopts[] = { {"use-damage", no_argument, NULL, 323}, {"no-use-damage", no_argument, NULL, 324}, {"no-vsync", no_argument, NULL, 325}, + {"max-brightness", required_argument, NULL, 326}, {"experimental-backends", no_argument, NULL, 733}, {"monitor-repaint", no_argument, NULL, 800}, {"diagnostics", no_argument, NULL, 801}, @@ -791,6 +797,11 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, case 325: opt->vsync = false; break; + + case 326: + opt->max_brightness = atof(optarg); + break; + P_CASEBOOL(733, experimental_backends); P_CASEBOOL(800, monitor_repaint); case 801: opt->print_diagnostics = true; break; @@ -822,6 +833,12 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, opt->shadow_opacity = normalize_d(opt->shadow_opacity); opt->refresh_rate = normalize_i_range(opt->refresh_rate, 0, 300); + opt->max_brightness = normalize_d(opt->max_brightness); + if (opt->max_brightness < 1.0 && opt->use_damage) { + log_warn("--max-brightness requires --no-use-damage. Falling back to 1.0"); + opt->max_brightness = 1.0; + } + // Apply default wintype options that are dependent on global options set_default_winopts(opt, winopt_mask, shadow_enable, fading_enable);