mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-06-11 21:18:28 +02:00
compositor: add grayscale output color effect
This adds a new output color effect: grayscale. It takes RGB color as input and computes a gray pixel color using the luminance formula for linear sRGB: Y = 0.2126 * R + 0.7152 * G + 0.0722 * B Just like the other color effects we have, this only works for sRGB and are not enabled when color-management is on. Note: although the technique is designed to be applied in linear, it's costly to convert to linear and then back to electrical. As doing the conversion in electrical still gives a reasonable result, we do it this way. When we add support for color effects with color-management on, we'll apply the effect in linear. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This commit is contained in:
parent
ed29f588e4
commit
32d0bd3d0e
10 changed files with 71 additions and 1 deletions
|
|
@ -2060,6 +2060,9 @@ wet_output_set_color_effect(struct weston_output *output,
|
|||
if (strcmp(color_effect, "inversion") == 0) {
|
||||
weston_output_color_effect_inversion(output);
|
||||
goto out;
|
||||
} else if (strcmp(color_effect, "grayscale") == 0) {
|
||||
weston_output_color_effect_grayscale(output);
|
||||
goto out;
|
||||
}
|
||||
|
||||
entry = weston_enum_map_find_name(cvd_correction_name_map, color_effect);
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ enum weston_surface_protection_mode {
|
|||
|
||||
enum weston_output_color_effect_type {
|
||||
WESTON_OUTPUT_COLOR_EFFECT_TYPE_INVERSION = 0,
|
||||
WESTON_OUTPUT_COLOR_EFFECT_TYPE_GRAYSCALE,
|
||||
WESTON_OUTPUT_COLOR_EFFECT_TYPE_CVD_CORRECTION,
|
||||
};
|
||||
|
||||
|
|
@ -2693,6 +2694,9 @@ weston_output_set_transform(struct weston_output *output,
|
|||
void
|
||||
weston_output_color_effect_inversion(struct weston_output *output);
|
||||
|
||||
void
|
||||
weston_output_color_effect_grayscale(struct weston_output *output);
|
||||
|
||||
void
|
||||
weston_output_color_effect_cvd_correction(struct weston_output *output,
|
||||
enum weston_cvd_correction_type type);
|
||||
|
|
|
|||
|
|
@ -436,6 +436,7 @@ struct weston_output_color_effect {
|
|||
|
||||
union {
|
||||
/* color inversion: no parameters */
|
||||
/* color grayscale: no parameters */
|
||||
struct weston_cvd_correction cvd;
|
||||
} u;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7681,6 +7681,27 @@ weston_output_color_effect_inversion(struct weston_output *output)
|
|||
output->color_effect->type = WESTON_OUTPUT_COLOR_EFFECT_TYPE_INVERSION;
|
||||
}
|
||||
|
||||
/** Set output's color effect to grayscale.
|
||||
*
|
||||
* The color effect is an effect applied to the whole scenegraph. Note that in
|
||||
* some cases this may force all the surfaces to be composed on the primary
|
||||
* plane, i.e. offloading to overlay planes won't be possible.
|
||||
*
|
||||
* \param output The output to set the effect.
|
||||
*
|
||||
* \ingroup output
|
||||
*/
|
||||
WL_EXPORT void
|
||||
weston_output_color_effect_grayscale(struct weston_output *output)
|
||||
{
|
||||
struct weston_compositor *compositor = output->compositor;
|
||||
|
||||
weston_assert_ptr_null(compositor, output->color_effect);
|
||||
|
||||
output->color_effect = weston_output_color_effect_create(compositor);
|
||||
output->color_effect->type = WESTON_OUTPUT_COLOR_EFFECT_TYPE_GRAYSCALE;
|
||||
}
|
||||
|
||||
/** Set output's color effect as CVD correction
|
||||
*
|
||||
* The color effect is an effect applied to the whole scenegraph. Note that in
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@
|
|||
/* enum gl_shader_color_effect */
|
||||
#define SHADER_COLOR_EFFECT_NONE 0
|
||||
#define SHADER_COLOR_EFFECT_INVERSION 1
|
||||
#define SHADER_COLOR_EFFECT_CVD_CORRECTION 2
|
||||
#define SHADER_COLOR_EFFECT_GRAYSCALE 2
|
||||
#define SHADER_COLOR_EFFECT_CVD_CORRECTION 3
|
||||
|
||||
/* enum gl_shader_color_curve */
|
||||
#define SHADER_COLOR_CURVE_IDENTITY 0
|
||||
|
|
@ -451,11 +452,32 @@ color_pipeline(vec4 color)
|
|||
vec4
|
||||
color_inversion(vec4 color)
|
||||
{
|
||||
/**
|
||||
* Ideally this should be done in linear space, but converting to linear
|
||||
* and back is costly. Historically this also has been done in the
|
||||
* electrical domain. Let's do in electrical, results are good enough.
|
||||
*/
|
||||
color.rgb = 1.0 - color.rgb;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4
|
||||
color_grayscale(vec4 color)
|
||||
{
|
||||
float gray;
|
||||
|
||||
/**
|
||||
* Ideally this should be done in linear space, but converting to linear
|
||||
* and back is costly. Historically this also has been done in the
|
||||
* electrical domain. Let's do in electrical, results are good enough.
|
||||
*/
|
||||
gray = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
color.rgb = vec3(gray);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4
|
||||
color_cvd_correction(vec4 color)
|
||||
{
|
||||
|
|
@ -504,6 +526,8 @@ main()
|
|||
color = color_pipeline(color);
|
||||
else if (c_color_effect == SHADER_COLOR_EFFECT_INVERSION)
|
||||
color = color_inversion(color);
|
||||
else if (c_color_effect == SHADER_COLOR_EFFECT_GRAYSCALE)
|
||||
color = color_grayscale(color);
|
||||
else if (c_color_effect == SHADER_COLOR_EFFECT_CVD_CORRECTION)
|
||||
color = color_cvd_correction(color);
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ enum gl_shader_texture_variant {
|
|||
enum gl_shader_color_effect {
|
||||
SHADER_COLOR_EFFECT_NONE = 0,
|
||||
SHADER_COLOR_EFFECT_INVERSION,
|
||||
SHADER_COLOR_EFFECT_GRAYSCALE,
|
||||
SHADER_COLOR_EFFECT_CVD_CORRECTION,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2344,6 +2344,12 @@ apply_color_effect(struct gl_renderer *gr, struct weston_output *output,
|
|||
*b = 1.0f - *b;
|
||||
gl_log_paint_node(gr, "\t\tcolor effect: inversion\n");
|
||||
return;
|
||||
case WESTON_OUTPUT_COLOR_EFFECT_TYPE_GRAYSCALE:
|
||||
*r = 0.2126f * (*r) + 0.7152f * (*g) + 0.0722f * (*b);
|
||||
*g = *r;
|
||||
*b = *r;
|
||||
gl_log_paint_node(gr, "\t\tcolor effect: grayscale\n");
|
||||
return;
|
||||
case WESTON_OUTPUT_COLOR_EFFECT_TYPE_CVD_CORRECTION:
|
||||
/**
|
||||
* See weston_output_color_effect_cvd_correction() for more details.
|
||||
|
|
|
|||
|
|
@ -563,6 +563,9 @@ gl_shader_config_set_color_effect(struct gl_renderer *gr,
|
|||
case WESTON_OUTPUT_COLOR_EFFECT_TYPE_INVERSION:
|
||||
sconf->req.color_effect = SHADER_COLOR_EFFECT_INVERSION;
|
||||
break;
|
||||
case WESTON_OUTPUT_COLOR_EFFECT_TYPE_GRAYSCALE:
|
||||
sconf->req.color_effect = SHADER_COLOR_EFFECT_GRAYSCALE;
|
||||
break;
|
||||
case WESTON_OUTPUT_COLOR_EFFECT_TYPE_CVD_CORRECTION:
|
||||
sconf->req.color_effect = SHADER_COLOR_EFFECT_CVD_CORRECTION;
|
||||
sconf->color_effect.cvd.correction = effect->u.cvd.correction;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ gl_shader_color_effect_to_string(enum gl_shader_color_effect kind)
|
|||
#define CASERET(x) case x: return #x;
|
||||
CASERET(SHADER_COLOR_EFFECT_NONE)
|
||||
CASERET(SHADER_COLOR_EFFECT_INVERSION)
|
||||
CASERET(SHADER_COLOR_EFFECT_GRAYSCALE)
|
||||
CASERET(SHADER_COLOR_EFFECT_CVD_CORRECTION)
|
||||
#undef CASERET
|
||||
}
|
||||
|
|
@ -890,6 +891,9 @@ gl_shader_load_config(struct gl_renderer *gr,
|
|||
case SHADER_COLOR_EFFECT_INVERSION:
|
||||
weston_log_scope_printf(gr->paint_node_scope, "\t\tcolor effect: inversion\n");
|
||||
break;
|
||||
case SHADER_COLOR_EFFECT_GRAYSCALE:
|
||||
weston_log_scope_printf(gr->paint_node_scope, "\t\tcolor effect: grayscale\n");
|
||||
break;
|
||||
case SHADER_COLOR_EFFECT_CVD_CORRECTION:
|
||||
weston_assert_int_ne(gr->compositor, shader->cvd_correction_uniform, -1);
|
||||
weston_log_scope_printf(gr->paint_node_scope, "\t\tcolor effect: cvd - %s\n",
|
||||
|
|
|
|||
|
|
@ -702,6 +702,9 @@ The effect can be one of the following strings:
|
|||
.B inversion
|
||||
color inversion, i.e. the RGB complement
|
||||
.TP
|
||||
.B grayscale
|
||||
convert colors to shades of gray
|
||||
.TP
|
||||
.B deuteranopia
|
||||
color correction (not simulation) for deuteranopia
|
||||
.TP
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue