clutter/color-state: Add support for gamma TF
This TF can't be defined as a TransferFunction enum because it needs a gamma_exp value too. Add to EOTFType enum a new type: EOTF_TYPE_GAMMA. With this new type, now EOTFs are unions that can have either a TransferFunction enum or a gamma_exp. Set gamma_exp as uniform. Add the support of it in the color management protocol. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4020>
This commit is contained in:
parent
3b53f7cb6c
commit
fcbd2e3840
5 changed files with 285 additions and 61 deletions
|
@ -27,10 +27,10 @@
|
|||
typedef struct _ClutterColorTransformKey
|
||||
{
|
||||
struct {
|
||||
ClutterTransferFunction transfer_function;
|
||||
guint eotf_key;
|
||||
} source;
|
||||
struct {
|
||||
ClutterTransferFunction transfer_function;
|
||||
guint eotf_key;
|
||||
} target;
|
||||
} ClutterColorTransformKey;
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
|
||||
#define UNIFORM_NAME_LUMINANCE_MAPPING "luminance_mapping"
|
||||
#define UNIFORM_NAME_COLOR_SPACE_MAPPING "color_space_mapping"
|
||||
#define UNIFORM_NAME_GAMMA_EXP "gamma_exp"
|
||||
#define UNIFORM_NAME_INV_GAMMA_EXP "inv_gamma_exp"
|
||||
|
||||
struct _ClutterColorState
|
||||
{
|
||||
|
@ -82,8 +84,8 @@ clutter_color_transform_key_hash (gconstpointer data)
|
|||
{
|
||||
const ClutterColorTransformKey *key = data;
|
||||
|
||||
return (key->source.transfer_function ^
|
||||
key->target.transfer_function);
|
||||
return (key->source.eotf_key ^
|
||||
key->target.eotf_key);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -93,8 +95,20 @@ clutter_color_transform_key_equal (gconstpointer data1,
|
|||
const ClutterColorTransformKey *key1 = data1;
|
||||
const ClutterColorTransformKey *key2 = data2;
|
||||
|
||||
return (key1->source.transfer_function == key2->source.transfer_function &&
|
||||
key1->target.transfer_function == key2->target.transfer_function);
|
||||
return (key1->source.eotf_key == key2->source.eotf_key &&
|
||||
key1->target.eotf_key == key2->target.eotf_key);
|
||||
}
|
||||
|
||||
static guint
|
||||
get_eotf_key (ClutterEOTF eotf)
|
||||
{
|
||||
switch (eotf.type)
|
||||
{
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
return eotf.tf_name << 1;
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -107,8 +121,8 @@ clutter_color_transform_key_init (ClutterColorTransformKey *key,
|
|||
ClutterColorStatePrivate *target_priv =
|
||||
clutter_color_state_get_instance_private (target_color_state);
|
||||
|
||||
key->source.transfer_function = priv->eotf.tf_name;
|
||||
key->target.transfer_function = target_priv->eotf.tf_name;
|
||||
key->source.eotf_key = get_eotf_key (priv->eotf);
|
||||
key->target.eotf_key = get_eotf_key (target_priv->eotf);
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -128,14 +142,20 @@ clutter_colorspace_to_string (ClutterColorspace colorspace)
|
|||
static const char *
|
||||
clutter_eotf_to_string (ClutterEOTF eotf)
|
||||
{
|
||||
switch (eotf.tf_name)
|
||||
switch (eotf.type)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
return "sRGB";
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return "PQ";
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return "linear";
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
return "gamma";
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
switch (eotf.tf_name)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
return "sRGB";
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return "PQ";
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return "linear";
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
|
@ -194,13 +214,19 @@ static const ClutterLuminance pq_default_luminance = {
|
|||
const ClutterLuminance *
|
||||
clutter_eotf_get_default_luminance (ClutterEOTF eotf)
|
||||
{
|
||||
switch (eotf.tf_name)
|
||||
switch (eotf.type)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
return &sdr_default_luminance;
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return &pq_default_luminance;
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
switch (eotf.tf_name)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return &sdr_default_luminance;
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return &pq_default_luminance;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
|
@ -280,7 +306,7 @@ clutter_color_state_new (ClutterContext *context,
|
|||
{
|
||||
return clutter_color_state_new_full (context,
|
||||
colorspace, transfer_function, NULL,
|
||||
-1.0f, -1.0f, -1.0f);
|
||||
-1.0f, -1.0f, -1.0f, -1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -296,6 +322,7 @@ clutter_color_state_new_full (ClutterContext *context,
|
|||
ClutterColorspace colorspace,
|
||||
ClutterTransferFunction transfer_function,
|
||||
ClutterPrimaries *primaries,
|
||||
float gamma_exp,
|
||||
float min_lum,
|
||||
float max_lum,
|
||||
float ref_lum)
|
||||
|
@ -322,8 +349,16 @@ clutter_color_state_new_full (ClutterContext *context,
|
|||
priv->colorimetry.colorspace = colorspace;
|
||||
}
|
||||
|
||||
priv->eotf.type = CLUTTER_EOTF_TYPE_NAMED;
|
||||
priv->eotf.tf_name = transfer_function;
|
||||
if (gamma_exp >= 1.0f)
|
||||
{
|
||||
priv->eotf.type = CLUTTER_EOTF_TYPE_GAMMA;
|
||||
priv->eotf.gamma_exp = gamma_exp;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->eotf.type = CLUTTER_EOTF_TYPE_NAMED;
|
||||
priv->eotf.tf_name = transfer_function;
|
||||
}
|
||||
|
||||
if (min_lum >= 0.0f && max_lum > 0.0f && ref_lum >= 0.0f)
|
||||
{
|
||||
|
@ -386,6 +421,36 @@ static const char pq_inv_eotf_source[] =
|
|||
" return vec4 (pq_inv_eotf (color.rgb), color.a);\n"
|
||||
"}\n";
|
||||
|
||||
static const char gamma_eotf_source[] =
|
||||
"uniform float " UNIFORM_NAME_GAMMA_EXP ";\n"
|
||||
"// gamma_eotf:\n"
|
||||
"// @color: Normalized ([0,1]) electrical signal value\n"
|
||||
"// Returns: tristimulus values ([0,1])\n"
|
||||
"vec3 gamma_eotf (vec3 color)\n"
|
||||
"{\n"
|
||||
" return pow (color, vec3 (" UNIFORM_NAME_GAMMA_EXP "));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 gamma_eotf (vec4 color)\n"
|
||||
"{\n"
|
||||
" return vec4 (gamma_eotf (color.rgb), color.a);\n"
|
||||
"}\n";
|
||||
|
||||
static const char gamma_inv_eotf_source[] =
|
||||
"uniform float " UNIFORM_NAME_INV_GAMMA_EXP ";\n"
|
||||
"// gamma_inv_eotf:\n"
|
||||
"// @color: Normalized tristimulus values ([0,1])"
|
||||
"// Returns: Normalized ([0,1]) electrical signal value\n"
|
||||
"vec3 gamma_inv_eotf (vec3 color)\n"
|
||||
"{\n"
|
||||
" return pow (color, vec3 (" UNIFORM_NAME_INV_GAMMA_EXP "));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 gamma_inv_eotf (vec4 color)\n"
|
||||
"{\n"
|
||||
" return vec4 (gamma_inv_eotf (color.rgb), color.a);\n"
|
||||
"}\n";
|
||||
|
||||
static const char srgb_eotf_source[] =
|
||||
"// srgb_eotf:\n"
|
||||
"// @color: Normalized ([0,1]) electrical signal value.\n"
|
||||
|
@ -437,6 +502,16 @@ static const TransferFunction pq_inv_eotf = {
|
|||
.name = "pq_inv_eotf",
|
||||
};
|
||||
|
||||
static const TransferFunction gamma_eotf = {
|
||||
.source = gamma_eotf_source,
|
||||
.name = "gamma_eotf",
|
||||
};
|
||||
|
||||
static const TransferFunction gamma_inv_eotf = {
|
||||
.source = gamma_inv_eotf_source,
|
||||
.name = "gamma_inv_eotf",
|
||||
};
|
||||
|
||||
static const TransferFunction srgb_eotf = {
|
||||
.source = srgb_eotf_source,
|
||||
.name = "srgb_eotf",
|
||||
|
@ -469,14 +544,20 @@ get_eotf (ClutterColorState *color_state)
|
|||
ClutterColorStatePrivate *priv =
|
||||
clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
switch (priv->eotf.tf_name)
|
||||
switch (priv->eotf.type)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return &pq_eotf;
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
return &srgb_eotf;
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return NULL;
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
return &gamma_eotf;
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
switch (priv->eotf.tf_name)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return &pq_eotf;
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
return &srgb_eotf;
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_warning ("Unhandled tranfer function %s",
|
||||
|
@ -490,14 +571,20 @@ get_inv_eotf (ClutterColorState *color_state)
|
|||
ClutterColorStatePrivate *priv =
|
||||
clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
switch (priv->eotf.tf_name)
|
||||
switch (priv->eotf.type)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return &pq_inv_eotf;
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
return &srgb_inv_eotf;
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return NULL;
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
return &gamma_inv_eotf;
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
switch (priv->eotf.tf_name)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return &pq_inv_eotf;
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
return &srgb_inv_eotf;
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_warning ("Unhandled tranfer function %s",
|
||||
|
@ -942,11 +1029,39 @@ clutter_color_state_update_uniforms (ClutterColorState *color_state,
|
|||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
const ClutterEOTF *eotf;
|
||||
const ClutterEOTF *target_eotf;
|
||||
float luminance_mapping;
|
||||
float color_space_mapping[9] = { 0 };
|
||||
int uniform_location_gamma_exp;
|
||||
int uniform_location_inv_gamma_exp;
|
||||
int uniform_location_luminance_mapping;
|
||||
int uniform_location_color_space_mapping;
|
||||
|
||||
eotf = clutter_color_state_get_eotf (color_state);
|
||||
if (eotf->type == CLUTTER_EOTF_TYPE_GAMMA)
|
||||
{
|
||||
uniform_location_gamma_exp =
|
||||
cogl_pipeline_get_uniform_location (pipeline,
|
||||
UNIFORM_NAME_GAMMA_EXP);
|
||||
|
||||
cogl_pipeline_set_uniform_1f (pipeline,
|
||||
uniform_location_gamma_exp,
|
||||
eotf->gamma_exp);
|
||||
}
|
||||
|
||||
target_eotf = clutter_color_state_get_eotf (target_color_state);
|
||||
if (target_eotf->type == CLUTTER_EOTF_TYPE_GAMMA)
|
||||
{
|
||||
uniform_location_inv_gamma_exp =
|
||||
cogl_pipeline_get_uniform_location (pipeline,
|
||||
UNIFORM_NAME_INV_GAMMA_EXP);
|
||||
|
||||
cogl_pipeline_set_uniform_1f (pipeline,
|
||||
uniform_location_inv_gamma_exp,
|
||||
1.0f / target_eotf->gamma_exp);
|
||||
}
|
||||
|
||||
luminance_mapping = get_luminance_mapping (color_state, target_color_state);
|
||||
|
||||
uniform_location_luminance_mapping =
|
||||
|
@ -1060,6 +1175,14 @@ eotf_equal (ClutterColorState *color_state,
|
|||
other_priv->eotf.type == CLUTTER_EOTF_TYPE_NAMED)
|
||||
return priv->eotf.tf_name == other_priv->eotf.tf_name;
|
||||
|
||||
if (priv->eotf.type == CLUTTER_EOTF_TYPE_GAMMA &&
|
||||
other_priv->eotf.type == CLUTTER_EOTF_TYPE_GAMMA)
|
||||
{
|
||||
return G_APPROX_VALUE (priv->eotf.gamma_exp,
|
||||
other_priv->eotf.gamma_exp,
|
||||
0.0001f);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1138,14 +1261,20 @@ clutter_color_state_required_format (ClutterColorState *color_state)
|
|||
|
||||
priv = clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
switch (priv->eotf.tf_name)
|
||||
switch (priv->eotf.type)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return CLUTTER_ENCODING_REQUIRED_FORMAT_FP16;
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return CLUTTER_ENCODING_REQUIRED_FORMAT_UINT10;
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
return CLUTTER_ENCODING_REQUIRED_FORMAT_UINT8;
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
switch (priv->eotf.tf_name)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
return CLUTTER_ENCODING_REQUIRED_FORMAT_FP16;
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
return CLUTTER_ENCODING_REQUIRED_FORMAT_UINT10;
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
return CLUTTER_ENCODING_REQUIRED_FORMAT_UINT8;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
|
@ -1181,24 +1310,33 @@ clutter_color_state_get_blending (ClutterColorState *color_state,
|
|||
|
||||
priv = clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
switch (priv->eotf.tf_name)
|
||||
switch (priv->eotf.type)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
switch (priv->eotf.tf_name)
|
||||
{
|
||||
case CLUTTER_TRANSFER_FUNCTION_PQ:
|
||||
case CLUTTER_TRANSFER_FUNCTION_LINEAR:
|
||||
blending_tf = CLUTTER_TRANSFER_FUNCTION_LINEAR;
|
||||
break;
|
||||
/* effectively this means we will blend sRGB content in sRGB, not linear */
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
blending_tf = priv->eotf.tf_name;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
break;
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
blending_tf = CLUTTER_TRANSFER_FUNCTION_LINEAR;
|
||||
break;
|
||||
/* effectively this means we will blend sRGB content in sRGB, not linear */
|
||||
case CLUTTER_TRANSFER_FUNCTION_SRGB:
|
||||
blending_tf = priv->eotf.tf_name;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (force)
|
||||
blending_tf = CLUTTER_TRANSFER_FUNCTION_LINEAR;
|
||||
|
||||
if (priv->eotf.tf_name == blending_tf)
|
||||
if (priv->eotf.type == CLUTTER_EOTF_TYPE_NAMED &&
|
||||
priv->eotf.tf_name == blending_tf)
|
||||
return g_object_ref (color_state);
|
||||
|
||||
switch (priv->colorimetry.type)
|
||||
|
@ -1217,6 +1355,7 @@ clutter_color_state_get_blending (ClutterColorState *color_state,
|
|||
colorspace,
|
||||
blending_tf,
|
||||
primaries,
|
||||
-1.0f,
|
||||
priv->luminance.min,
|
||||
priv->luminance.max,
|
||||
priv->luminance.ref);
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef enum
|
|||
typedef enum
|
||||
{
|
||||
CLUTTER_EOTF_TYPE_NAMED,
|
||||
CLUTTER_EOTF_TYPE_GAMMA,
|
||||
} ClutterEOTFType;
|
||||
|
||||
typedef enum
|
||||
|
@ -83,7 +84,11 @@ typedef struct _ClutterColorimetry
|
|||
typedef struct _ClutterEOTF
|
||||
{
|
||||
ClutterEOTFType type : 1;
|
||||
ClutterTransferFunction tf_name;
|
||||
union
|
||||
{
|
||||
ClutterTransferFunction tf_name;
|
||||
float gamma_exp;
|
||||
};
|
||||
} ClutterEOTF;
|
||||
|
||||
typedef struct _ClutterLuminance
|
||||
|
@ -110,6 +115,7 @@ ClutterColorState * clutter_color_state_new_full (ClutterContext *conte
|
|||
ClutterColorspace colorspace,
|
||||
ClutterTransferFunction transfer_function,
|
||||
ClutterPrimaries *primaries,
|
||||
float gamma_exp,
|
||||
float min_lum,
|
||||
float max_lum,
|
||||
float ref_lum);
|
||||
|
|
|
@ -687,7 +687,9 @@ update_color_state (MetaColorDevice *color_device)
|
|||
g_autoptr (ClutterColorState) color_state = NULL;
|
||||
ClutterColorspace colorspace;
|
||||
ClutterEOTF eotf;
|
||||
ClutterTransferFunction transfer_function;
|
||||
const ClutterLuminance *luminance;
|
||||
float gamma_exp;
|
||||
float reference_luminance_factor;
|
||||
float new_ref_luminance;
|
||||
UpdateResult result = 0;
|
||||
|
@ -701,10 +703,23 @@ update_color_state (MetaColorDevice *color_device)
|
|||
meta_debug_control_get_luminance_percentage (debug_control) / 100.0f;
|
||||
new_ref_luminance = luminance->ref * reference_luminance_factor;
|
||||
|
||||
switch (eotf.type)
|
||||
{
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
transfer_function = eotf.tf_name;
|
||||
gamma_exp = -1.0f;
|
||||
break;
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
transfer_function = CLUTTER_TRANSFER_FUNCTION_SRGB;
|
||||
gamma_exp = eotf.gamma_exp;
|
||||
break;
|
||||
}
|
||||
|
||||
color_state = clutter_color_state_new_full (clutter_context,
|
||||
colorspace,
|
||||
eotf.tf_name,
|
||||
transfer_function,
|
||||
NULL,
|
||||
gamma_exp,
|
||||
luminance->min,
|
||||
luminance->max,
|
||||
new_ref_luminance);
|
||||
|
|
|
@ -184,6 +184,14 @@ wayland_tf_to_clutter (enum xx_color_manager_v4_transfer_function tf,
|
|||
{
|
||||
switch (tf)
|
||||
{
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22:
|
||||
eotf->type = CLUTTER_EOTF_TYPE_GAMMA;
|
||||
eotf->gamma_exp = 2.2f;
|
||||
return TRUE;
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28:
|
||||
eotf->type = CLUTTER_EOTF_TYPE_GAMMA;
|
||||
eotf->gamma_exp = 2.8f;
|
||||
return TRUE;
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB:
|
||||
eotf->type = CLUTTER_EOTF_TYPE_NAMED;
|
||||
eotf->tf_name = CLUTTER_TRANSFER_FUNCTION_SRGB;
|
||||
|
@ -374,8 +382,24 @@ send_information (struct wl_resource *info_resource,
|
|||
}
|
||||
|
||||
eotf = clutter_color_state_get_eotf (color_state);
|
||||
tf = clutter_tf_to_wayland (eotf->tf_name);
|
||||
xx_image_description_info_v4_send_tf_named (info_resource, tf);
|
||||
switch (eotf->type)
|
||||
{
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
tf = clutter_tf_to_wayland (eotf->tf_name);
|
||||
xx_image_description_info_v4_send_tf_named (info_resource, tf);
|
||||
break;
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
if (G_APPROX_VALUE (eotf->gamma_exp, 2.2f, 0.0001f))
|
||||
xx_image_description_info_v4_send_tf_named (info_resource,
|
||||
XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22);
|
||||
else if (G_APPROX_VALUE (eotf->gamma_exp, 2.8f, 0.0001f))
|
||||
xx_image_description_info_v4_send_tf_named (info_resource,
|
||||
XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28);
|
||||
else
|
||||
xx_image_description_info_v4_send_tf_power (info_resource,
|
||||
float_to_scaled_uint32 (eotf->gamma_exp));
|
||||
break;
|
||||
}
|
||||
|
||||
lum = clutter_color_state_get_luminance (color_state);
|
||||
xx_image_description_info_v4_send_luminances (info_resource,
|
||||
|
@ -861,6 +885,8 @@ creator_params_create (struct wl_client *client,
|
|||
MetaWaylandImageDescription *image_desc;
|
||||
ClutterColorspace colorspace;
|
||||
ClutterPrimaries *primaries;
|
||||
ClutterTransferFunction tf_name;
|
||||
float gamma_exp;
|
||||
|
||||
if (!creator_params->is_colorimetry_set || !creator_params->is_eotf_set)
|
||||
{
|
||||
|
@ -888,10 +914,23 @@ creator_params_create (struct wl_client *client,
|
|||
break;
|
||||
}
|
||||
|
||||
switch (creator_params->eotf.type)
|
||||
{
|
||||
case CLUTTER_EOTF_TYPE_NAMED:
|
||||
tf_name = creator_params->eotf.tf_name;
|
||||
gamma_exp = -1.0f;
|
||||
break;
|
||||
case CLUTTER_EOTF_TYPE_GAMMA:
|
||||
tf_name = CLUTTER_TRANSFER_FUNCTION_SRGB;
|
||||
gamma_exp = creator_params->eotf.gamma_exp;
|
||||
break;
|
||||
}
|
||||
|
||||
color_state = clutter_color_state_new_full (clutter_context,
|
||||
colorspace,
|
||||
creator_params->eotf.tf_name,
|
||||
tf_name,
|
||||
primaries,
|
||||
gamma_exp,
|
||||
creator_params->lum.min,
|
||||
creator_params->lum.max,
|
||||
creator_params->lum.ref);
|
||||
|
@ -944,9 +983,28 @@ creator_params_set_tf_power (struct wl_client *client,
|
|||
struct wl_resource *resource,
|
||||
uint32_t eexp)
|
||||
{
|
||||
wl_resource_post_error (resource,
|
||||
XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_TF,
|
||||
"Setting power based transfer characteristics is not supported");
|
||||
MetaWaylandCreatorParams *creator_params =
|
||||
wl_resource_get_user_data (resource);
|
||||
|
||||
if (creator_params->is_eotf_set)
|
||||
{
|
||||
wl_resource_post_error (resource,
|
||||
XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET,
|
||||
"The transfer characteristics were already set");
|
||||
return;
|
||||
}
|
||||
|
||||
if (eexp < 10000 || eexp > 100000)
|
||||
{
|
||||
wl_resource_post_error (resource,
|
||||
XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_TF,
|
||||
"The exponent must be between 1.0 and 10.0");
|
||||
return;
|
||||
}
|
||||
|
||||
creator_params->eotf.type = CLUTTER_EOTF_TYPE_GAMMA;
|
||||
creator_params->eotf.gamma_exp = scaled_uint32_to_float (eexp);
|
||||
creator_params->is_eotf_set = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1354,8 +1412,14 @@ color_manager_send_supported_events (struct wl_resource *resource)
|
|||
XX_COLOR_MANAGER_V4_FEATURE_PARAMETRIC);
|
||||
xx_color_manager_v4_send_supported_feature (resource,
|
||||
XX_COLOR_MANAGER_V4_FEATURE_SET_PRIMARIES);
|
||||
xx_color_manager_v4_send_supported_feature (resource,
|
||||
XX_COLOR_MANAGER_V4_FEATURE_SET_TF_POWER);
|
||||
xx_color_manager_v4_send_supported_feature (resource,
|
||||
XX_COLOR_MANAGER_V4_FEATURE_SET_LUMINANCES);
|
||||
xx_color_manager_v4_send_supported_tf_named (resource,
|
||||
XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22);
|
||||
xx_color_manager_v4_send_supported_tf_named (resource,
|
||||
XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28);
|
||||
xx_color_manager_v4_send_supported_tf_named (resource,
|
||||
XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB);
|
||||
xx_color_manager_v4_send_supported_tf_named (resource,
|
||||
|
|
Loading…
Reference in a new issue