color_management_v1: implement set_luminances

Add support for set_luminances in parametric image description creators.
Store explicit luminances in wlr_image_description_v1_data and use them
in preference to default transfer-function luminances. Also send
target_max_cll and target_max_fall when non-zero.
This commit is contained in:
Furkan Sahin 2026-05-08 15:33:26 -04:00
parent 34efe5fbea
commit 4f0b8e2a80
2 changed files with 57 additions and 6 deletions

View file

@ -33,6 +33,8 @@ struct wlr_image_description_v1_data {
bool has_primaries;
struct wlr_color_primaries primaries;
bool has_luminances;
struct wlr_color_luminances luminances;
};
struct wlr_color_manager_v1_features {

View file

@ -103,6 +103,15 @@ static bool img_desc_data_equal(const struct wlr_image_description_v1_data *a,
if (a->has_primaries && !primaries_equal(&a->primaries, &b->primaries)) {
return false;
}
if (a->has_luminances != b->has_luminances) {
return false;
}
if (a->has_luminances &&
(a->luminances.min != b->luminances.min ||
a->luminances.max != b->luminances.max ||
a->luminances.reference != b->luminances.reference)) {
return false;
}
if (a->has_mastering_display_primaries &&
!primaries_equal(&a->mastering_display_primaries, &b->mastering_display_primaries)) {
return false;
@ -156,8 +165,29 @@ static void image_desc_handle_get_information(struct wl_client *client,
}
struct wlr_color_luminances luminances;
wlr_color_transfer_function_get_default_luminance(
wlr_color_manager_v1_transfer_function_to_wlr(image_desc->data.tf_named), &luminances);
if (image_desc->data.has_luminances) {
luminances = image_desc->data.luminances;
} else {
wlr_color_transfer_function_get_default_luminance(
wlr_color_manager_v1_transfer_function_to_wlr(image_desc->data.tf_named),
&luminances);
}
wp_image_description_info_v1_send_luminances(resource,
round(luminances.min * 10000), round(luminances.max),
round(luminances.reference));
wp_image_description_info_v1_send_target_luminance(resource,
round(luminances.min * 10000), round(luminances.max));
if (image_desc->data.max_cll != 0) {
wp_image_description_info_v1_send_target_max_cll(resource,
image_desc->data.max_cll);
}
if (image_desc->data.max_fall != 0) {
wp_image_description_info_v1_send_target_max_fall(resource,
image_desc->data.max_fall);
}
if (image_desc->data.primaries_named != 0) {
wp_image_description_info_v1_send_primaries_named(resource,
@ -649,9 +679,29 @@ static void image_desc_creator_params_handle_set_primaries(struct wl_client *cli
static void image_desc_creator_params_handle_set_luminances(struct wl_client *client,
struct wl_resource *params_resource, uint32_t min_lum,
uint32_t max_lum, uint32_t reference_lum) {
wl_resource_post_error(params_resource,
WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_UNSUPPORTED_FEATURE,
"set_luminances is not supported");
struct wlr_image_description_creator_params_v1 *params =
image_desc_creator_params_from_resource(params_resource);
if(!params->manager->features.set_luminances) {
wl_resource_post_error(params_resource,
WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_UNSUPPORTED_FEATURE,
"set_luminances is not supported");
return;
}
if (params->data.has_luminances) {
wl_resource_post_error(params_resource,
WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_ALREADY_SET,
"luminances already set");
return;
}
params->data.has_luminances = true;
params->data.luminances = (struct wlr_color_luminances){
.min = (float)min_lum / 10000.0f,
.max = (float)max_lum / 10000.0f,
.reference = (float)reference_lum / 10000.0f,
};
}
static void image_desc_creator_params_handle_set_mastering_display_primaries(
@ -1012,7 +1062,6 @@ struct wlr_color_manager_v1 *wlr_color_manager_v1_create(struct wl_display *disp
// TODO: add support for all of these features
assert(!options->features.icc_v2_v4);
assert(!options->features.set_tf_power);
assert(!options->features.set_luminances);
assert(!options->features.extended_target_volume);
assert(!options->features.windows_scrgb);