wayland: Support explicit primaries

Use the new primaries color state support to handle the situation
where the compositor gives us numeric primaries instead of named
ones.
This commit is contained in:
Matthias Clasen 2024-08-13 21:46:39 -04:00
parent 0adb7b8924
commit 2a995a2f79

View File

@ -67,6 +67,18 @@ cicp_to_wl_transfer (uint tf)
return 0;
}
static inline float
wl_to_primary_coord (uint p)
{
return p / 10000.0;
}
static inline uint
wl_from_primary_coord (float p)
{
return p * 10000;
}
struct _GdkWaylandColor
{
GdkWaylandDisplay *display;
@ -281,50 +293,85 @@ create_image_desc (GdkWaylandColor *color,
gboolean sync)
{
CsImageDescListenerData data;
struct xx_image_description_creator_params_v4 *creator;
struct xx_image_description_creator_params_v4 *creator = NULL;
struct xx_image_description_v4 *desc;
const GdkCicp *cicp;
GdkCicp norm;
uint32_t primaries, tf;
cicp = gdk_color_state_get_cicp (cs);
if (!cicp)
if (cicp && cicp->color_primaries != 2)
{
GDK_DEBUG (MISC, "Unsupported color state %s: Not a CICP colorstate",
gdk_color_state_get_name (cs));
g_hash_table_insert (color->cs_to_desc, gdk_color_state_ref (cs), NULL);
return;
}
gdk_cicp_normalize (cicp, &norm);
primaries = cicp_to_wl_primaries (norm.color_primaries);
tf = cicp_to_wl_transfer (norm.transfer_function);
GdkCicp norm;
uint32_t primaries_named;
uint32_t tf_named;
if ((color->color_manager_supported.primaries & (1 << primaries)) == 0 ||
(color->color_manager_supported.transfers & (1 << tf)) == 0)
gdk_cicp_normalize (cicp, &norm);
primaries_named = cicp_to_wl_primaries (norm.color_primaries);
tf_named = cicp_to_wl_transfer (norm.transfer_function);
if ((color->color_manager_supported.primaries & (1 << primaries_named)) == 0 ||
(color->color_manager_supported.transfers & (1 << tf_named)) == 0)
{
GDK_DEBUG (MISC, "Unsupported color state %s: Primaries or transfer function unsupported",
gdk_color_state_get_name (cs));
g_hash_table_insert (color->cs_to_desc, gdk_color_state_ref (cs), NULL);
return;
}
creator = xx_color_manager_v4_new_parametric_creator (color->color_manager);
xx_image_description_creator_params_v4_set_primaries_named (creator, primaries_named);
xx_image_description_creator_params_v4_set_tf_named (creator, tf_named);
}
else if (cicp && cicp->color_primaries == 2)
{
GDK_DEBUG (MISC, "Unsupported color state %s: Primaries or transfer function unsupported",
const float *primaries = gdk_color_state_get_primaries (cs);
GdkCicp norm;
uint32_t tf_named;
gdk_cicp_normalize (cicp, &norm);
tf_named = cicp_to_wl_transfer (norm.transfer_function);
if ((color->color_manager_supported.features & (1 << XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_SET_PRIMARIES)) == 0 ||
(color->color_manager_supported.transfers & (1 << tf_named)) == 0)
{
GDK_DEBUG (MISC, "Unsupported color state %s: Primaries or transfer function unsupported",
gdk_color_state_get_name (cs));
g_hash_table_insert (color->cs_to_desc, gdk_color_state_ref (cs), NULL);
return;
}
creator = xx_color_manager_v4_new_parametric_creator (color->color_manager);
xx_image_description_creator_params_v4_set_primaries (creator,
wl_from_primary_coord (primaries[0]),
wl_from_primary_coord (primaries[1]),
wl_from_primary_coord (primaries[2]),
wl_from_primary_coord (primaries[3]),
wl_from_primary_coord (primaries[4]),
wl_from_primary_coord (primaries[5]),
wl_from_primary_coord (primaries[6]),
wl_from_primary_coord (primaries[7]));
xx_image_description_creator_params_v4_set_tf_named (creator, tf_named);
}
else
{
GDK_DEBUG (MISC, "Unsupported color state %s: Not a CICP colorstate and no primaries",
gdk_color_state_get_name (cs));
g_hash_table_insert (color->cs_to_desc, gdk_color_state_ref (cs), NULL);
return;
}
desc = xx_image_description_creator_params_v4_create (creator);
data.color = color;
data.color_state = cs;
data.sync = sync;
data.done = FALSE;
creator = xx_color_manager_v4_new_parametric_creator (color->color_manager);
xx_image_description_creator_params_v4_set_primaries_named (creator, primaries);
xx_image_description_creator_params_v4_set_tf_named (creator, tf);
desc = xx_image_description_creator_params_v4_create (creator);
if (sync)
{
struct wl_event_queue *event_queue;
event_queue = wl_display_create_queue (color->display->wl_display);
wl_proxy_set_queue ((struct wl_proxy *) desc, event_queue);
xx_image_description_v4_add_listener (desc, &cs_image_desc_listener, &data);
@ -478,8 +525,23 @@ gdk_color_state_from_image_description_bits (ImageDescription *desc)
return gdk_color_state_new_for_cicp (&cicp, NULL);
}
else
return NULL;
else if (desc->has_primaries && desc->has_tf_named)
{
float primaries[8];
primaries[0] = wl_to_primary_coord (desc->r_x);
primaries[1] = wl_to_primary_coord (desc->r_y);
primaries[2] = wl_to_primary_coord (desc->g_x);
primaries[3] = wl_to_primary_coord (desc->g_y);
primaries[4] = wl_to_primary_coord (desc->b_x);
primaries[5] = wl_to_primary_coord (desc->b_y);
primaries[6] = wl_to_primary_coord (desc->w_x);
primaries[7] = wl_to_primary_coord (desc->w_y);
return gdk_color_state_new_for_primaries (primaries, desc->tf_named, NULL);
}
return NULL;
}
static void