color: update color-management protocol to xx-v4

The main differences is the split of cm_surface functionality with
cm_surface and cm_feedback_surface.

There can only be one cm_surface to set, unset image descriptions. When
cm_surface is destroyed, the image description is automatically unset.

There can be multiple feedback_surfaces for one surface though.
Now the "preferred_changed" signal can be an initial event.

Creator params now have a new request: set_luminances.

Signed-off-by: Joan Torres <joan.torres@suse.com>
This commit is contained in:
Joan Torres 2024-08-05 13:02:47 +02:00 committed by Leandro Ribeiro
parent 5fe02dc68e
commit 1b793b7acd
7 changed files with 907 additions and 613 deletions

View File

@ -91,7 +91,7 @@ struct display {
struct wl_data_device_manager *data_device_manager;
struct text_cursor_position *text_cursor_position;
struct xdg_wm_base *xdg_shell;
struct xx_color_manager_v2 *color_manager;
struct xx_color_manager_v4 *color_manager;
struct zwp_tablet_manager_v2 *tablet_manager;
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
struct zwp_pointer_constraints_v1 *pointer_constraints;
@ -217,7 +217,7 @@ struct surface {
struct wl_callback *frame_cb;
uint32_t last_time;
struct xx_color_management_surface_v2 *cm_surface;
struct xx_color_management_surface_v4 *cm_surface;
struct rectangle allocation;
struct rectangle server_allocation;
@ -480,7 +480,7 @@ struct shm_pool {
};
struct cm_image_description {
struct xx_image_description_v2 *image_desc;
struct xx_image_description_v4 *image_desc;
enum cm_image_desc_status {
CM_IMAGE_DESC_NOT_CREATED = 0,
CM_IMAGE_DESC_READY,
@ -493,27 +493,27 @@ render_intent_info_table[] = {
{
.intent = RENDER_INTENT_PERCEPTUAL,
.desc = "Perceptual",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_PERCEPTUAL,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL,
},
{
.intent = RENDER_INTENT_RELATIVE,
.desc = "Media-relative colorimetric",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_RELATIVE,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE,
},
{
.intent = RENDER_INTENT_RELATIVE_BPC,
.desc = "Media-relative colorimetric + black point compensation",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_RELATIVE_BPC,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE_BPC,
},
{
.intent = RENDER_INTENT_SATURATION,
.desc = "Saturation",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_SATURATION,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_SATURATION,
},
{
.intent = RENDER_INTENT_ABSOLUTE,
.desc = "ICC-absolute colorimetric",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_ABSOLUTE,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_ABSOLUTE,
},
};
@ -568,7 +568,7 @@ debug_print(void *proxy, int line, const char *func, const char *fmt, ...)
#endif
static void
cm_image_desc_ready(void *data, struct xx_image_description_v2 *xx_image_description_v2,
cm_image_desc_ready(void *data, struct xx_image_description_v4 *xx_image_description_v4,
uint32_t identity)
{
struct cm_image_description *cm_image_desc = data;
@ -577,7 +577,7 @@ cm_image_desc_ready(void *data, struct xx_image_description_v2 *xx_image_descrip
}
static void
cm_image_desc_failed(void *data, struct xx_image_description_v2 *xx_image_description_v2,
cm_image_desc_failed(void *data, struct xx_image_description_v4 *xx_image_description_v4,
uint32_t cause, const char *msg)
{
struct cm_image_description *cm_image_desc = data;
@ -588,7 +588,7 @@ cm_image_desc_failed(void *data, struct xx_image_description_v2 *xx_image_descri
cm_image_desc->status = CM_IMAGE_DESC_FAILED;
}
static const struct xx_image_description_v2_listener cm_image_desc_listener = {
static const struct xx_image_description_v4_listener cm_image_desc_listener = {
.ready = cm_image_desc_ready,
.failed = cm_image_desc_failed,
};
@ -610,10 +610,10 @@ widget_set_image_description_icc(struct widget *widget, int icc_fd,
uint32_t length, uint32_t offset,
enum render_intent intent, char **err_msg)
{
struct xx_image_description_creator_icc_v2 *icc_creator;
struct xx_image_description_creator_icc_v4 *icc_creator;
struct display *display = widget->window->display;
struct surface *surface = widget->surface;
struct xx_color_manager_v2 *color_manager_wrapper;
struct xx_color_manager_v4 *color_manager_wrapper;
struct wl_event_queue *queue;
struct cm_image_description cm_image_desc;
const struct render_intent_info *intent_info;
@ -623,11 +623,11 @@ widget_set_image_description_icc(struct widget *widget, int icc_fd,
str_printf(err_msg,
"%s extension not supported by the Wayland " \
"compositor, ignoring image color profile.",
xx_color_manager_v2_interface.name);
xx_color_manager_v4_interface.name);
return false;
}
if (!((display->color_manager_features >> XX_COLOR_MANAGER_V2_FEATURE_ICC_V2_V4) & 1)) {
if (!((display->color_manager_features >> XX_COLOR_MANAGER_V4_FEATURE_ICC_V2_V4) & 1)) {
str_printf(err_msg,
"Wayland compositor does not support creating image " \
"descriptions from ICC files, ignoring color profile.");
@ -650,15 +650,15 @@ widget_set_image_description_icc(struct widget *widget, int icc_fd,
wl_proxy_set_queue((struct wl_proxy *)color_manager_wrapper, queue);
/* Create ICC image description creator and set the ICC file. */
icc_creator = xx_color_manager_v2_new_icc_creator(color_manager_wrapper);
icc_creator = xx_color_manager_v4_new_icc_creator(color_manager_wrapper);
wl_proxy_wrapper_destroy(color_manager_wrapper);
xx_image_description_creator_icc_v2_set_icc_file(icc_creator,
xx_image_description_creator_icc_v4_set_icc_file(icc_creator,
icc_fd, offset, length);
/* Create the image description. It will also destroy the ICC creator. */
cm_image_desc.status = CM_IMAGE_DESC_NOT_CREATED;
cm_image_desc.image_desc = xx_image_description_creator_icc_v2_create(icc_creator);
xx_image_description_v2_add_listener(cm_image_desc.image_desc,
cm_image_desc.image_desc = xx_image_description_creator_icc_v4_create(icc_creator);
xx_image_description_v4_add_listener(cm_image_desc.image_desc,
&cm_image_desc_listener, &cm_image_desc);
/* Wait until compositor creates the image description or gracefully
@ -666,7 +666,7 @@ widget_set_image_description_icc(struct widget *widget, int icc_fd,
while (ret != -1 && cm_image_desc.status == CM_IMAGE_DESC_NOT_CREATED)
ret = wl_display_dispatch_queue(display->display, queue);
if (ret == -1) {
xx_image_description_v2_destroy(cm_image_desc.image_desc);
xx_image_description_v4_destroy(cm_image_desc.image_desc);
wl_event_queue_destroy(queue);
str_printf(err_msg,
"Disconnected from the Wayland compositor, " \
@ -677,7 +677,7 @@ widget_set_image_description_icc(struct widget *widget, int icc_fd,
/* Gracefully failed to create image description. Error already printed
* in the handler. */
if (cm_image_desc.status == CM_IMAGE_DESC_FAILED) {
xx_image_description_v2_destroy(cm_image_desc.image_desc);
xx_image_description_v4_destroy(cm_image_desc.image_desc);
wl_event_queue_destroy(queue);
str_printf(err_msg,
"Image description creation gracefully failed.");
@ -687,14 +687,14 @@ widget_set_image_description_icc(struct widget *widget, int icc_fd,
if (!surface->cm_surface)
surface->cm_surface =
xx_color_manager_v2_get_surface(display->color_manager,
xx_color_manager_v4_get_surface(display->color_manager,
surface->surface);
xx_color_management_surface_v2_set_image_description(surface->cm_surface,
xx_color_management_surface_v4_set_image_description(surface->cm_surface,
cm_image_desc.image_desc,
intent_info->protocol_intent);
xx_image_description_v2_destroy(cm_image_desc.image_desc);
xx_image_description_v4_destroy(cm_image_desc.image_desc);
wl_event_queue_destroy(queue);
return true;
@ -1578,7 +1578,7 @@ surface_destroy(struct surface *surface)
wp_viewport_destroy(surface->viewport);
if (surface->cm_surface)
xx_color_management_surface_v2_destroy(surface->cm_surface);
xx_color_management_surface_v4_destroy(surface->cm_surface);
wl_surface_destroy(surface->surface);
@ -6671,7 +6671,7 @@ display_bind_tablets(struct display *d, uint32_t id)
}
static void
cm_supported_intent(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
cm_supported_intent(void *data, struct xx_color_manager_v4 *xx_color_manager_v4,
uint32_t render_intent)
{
struct display *d = data;
@ -6680,7 +6680,7 @@ cm_supported_intent(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
}
static void
cm_supported_feature(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
cm_supported_feature(void *data, struct xx_color_manager_v4 *xx_color_manager_v4,
uint32_t feature)
{
struct display *d = data;
@ -6689,20 +6689,20 @@ cm_supported_feature(void *data, struct xx_color_manager_v2 *xx_color_manager_v2
}
static void
cm_supported_tf_named(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
cm_supported_tf_named(void *data, struct xx_color_manager_v4 *xx_color_manager_v4,
uint32_t tf_code)
{
/* unused in this file */
}
static void
cm_supported_primaries_named(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
cm_supported_primaries_named(void *data, struct xx_color_manager_v4 *xx_color_manager_v4,
uint32_t primaries_code)
{
/* unused in this file */
}
static const struct xx_color_manager_v2_listener cm_listener = {
static const struct xx_color_manager_v4_listener cm_listener = {
.supported_intent = cm_supported_intent,
.supported_feature = cm_supported_feature,
.supported_tf_named = cm_supported_tf_named,
@ -6777,11 +6777,11 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
&wp_viewporter_interface, 1);
} else if (strcmp(interface, "zwp_tablet_manager_v2") == 0) {
display_bind_tablets(d, id);
} else if (strcmp(interface, "xx_color_manager_v2") == 0) {
} else if (strcmp(interface, "xx_color_manager_v4") == 0) {
d->color_manager =
wl_registry_bind(registry, id,
&xx_color_manager_v2_interface, 1);
xx_color_manager_v2_add_listener(d->color_manager,
&xx_color_manager_v4_interface, 1);
xx_color_manager_v4_add_listener(d->color_manager,
&cm_listener, d);
}
@ -7005,7 +7005,7 @@ display_destroy(struct display *display)
xdg_wm_base_destroy(display->xdg_shell);
if (display->color_manager)
xx_color_manager_v2_destroy(display->color_manager);
xx_color_manager_v4_destroy(display->color_manager);
if (display->shm)
wl_shm_destroy(display->shm);

View File

@ -2049,11 +2049,12 @@ struct weston_surface {
struct weston_color_profile *preferred_color_profile;
const struct weston_render_intent_info *render_intent;
/* xx_color_manager_v1.get_color_management_surface
/* xx_color_manager_v1.get_feedback_color_management_surface
*
* When a client uses this request, we add the wl_resource we create to
* this list. */
struct wl_list cm_surface_resource_list;
struct wl_list cm_feedback_surface_resource_list;
struct wl_resource *cm_surface;
};
struct weston_subsurface {

View File

@ -111,13 +111,13 @@ weston_cm_send_icc_file(struct cm_image_desc_info *cm_image_desc_info,
return;
}
xx_image_description_info_v2_send_icc_file(cm_image_desc_info->owner,
xx_image_description_info_v4_send_icc_file(cm_image_desc_info->owner,
fd, len);
}
/**
* For a parametric image description, sends its
* enum xx_color_manager_v2_primaries code to the client.
* enum xx_color_manager_v4_primaries code to the client.
*
* This is a helper function that should be used by the color plugin
* that owns the color profile and has information about it.
@ -129,7 +129,7 @@ WL_EXPORT void
weston_cm_send_primaries_named(struct cm_image_desc_info *cm_image_desc_info,
const struct weston_color_primaries_info *primaries_info)
{
xx_image_description_info_v2_send_primaries_named(cm_image_desc_info->owner,
xx_image_description_info_v4_send_primaries_named(cm_image_desc_info->owner,
primaries_info->protocol_primaries);
}
@ -147,7 +147,7 @@ WL_EXPORT void
weston_cm_send_primaries(struct cm_image_desc_info *cm_image_desc_info,
const struct weston_color_gamut *color_gamut)
{
xx_image_description_info_v2_send_primaries(cm_image_desc_info->owner,
xx_image_description_info_v4_send_primaries(cm_image_desc_info->owner,
/* red */
round(color_gamut->primary[0].x * 10000),
round(color_gamut->primary[0].y * 10000),
@ -164,7 +164,7 @@ weston_cm_send_primaries(struct cm_image_desc_info *cm_image_desc_info,
/**
* For a parametric image description, sends its
* enum xx_color_manager_v2_transfer_function code to the client.
* enum xx_color_manager_v4_transfer_function code to the client.
*
* This is a helper function that should be used by the color plugin
* that owns the color profile and has information about it.
@ -176,7 +176,7 @@ WL_EXPORT void
weston_cm_send_tf_named(struct cm_image_desc_info *cm_image_desc_info,
const struct weston_color_tf_info *tf_info)
{
xx_image_description_info_v2_send_tf_named(cm_image_desc_info->owner,
xx_image_description_info_v4_send_tf_named(cm_image_desc_info->owner,
tf_info->protocol_tf);
}
@ -217,7 +217,7 @@ image_description_info_create(struct wl_client *client, uint32_t version,
cm_image_desc_info->compositor = compositor;
cm_image_desc_info->owner =
wl_resource_create(client, &xx_image_description_info_v2_interface,
wl_resource_create(client, &xx_image_description_info_v4_interface,
version, cm_image_desc_info_id);
if (!cm_image_desc_info->owner) {
free(cm_image_desc_info);
@ -249,7 +249,7 @@ image_description_get_information(struct wl_client *client,
* to create it. */
if (!cm_image_desc) {
wl_resource_post_error(cm_image_desc_res,
XX_IMAGE_DESCRIPTION_V2_ERROR_NOT_READY,
XX_IMAGE_DESCRIPTION_V4_ERROR_NOT_READY,
"we gracefully failed to create this image " \
"description");
return;
@ -258,7 +258,7 @@ image_description_get_information(struct wl_client *client,
/* Invalid image description for this request, as it isn't ready yet. */
if (!cm_image_desc->cprof) {
wl_resource_post_error(cm_image_desc_res,
XX_IMAGE_DESCRIPTION_V2_ERROR_NOT_READY,
XX_IMAGE_DESCRIPTION_V4_ERROR_NOT_READY,
"image description not ready yet");
return;
}
@ -267,7 +267,7 @@ image_description_get_information(struct wl_client *client,
* that get_information() request should be invalid. */
if (!cm_image_desc->supports_get_info) {
wl_resource_post_error(cm_image_desc_res,
XX_IMAGE_DESCRIPTION_V2_ERROR_NO_INFORMATION,
XX_IMAGE_DESCRIPTION_V4_ERROR_NO_INFORMATION,
"get_information is not allowed for this "
"image description");
return;
@ -289,7 +289,7 @@ image_description_get_information(struct wl_client *client,
success = cm_image_desc->cm->send_image_desc_info(cm_image_desc_info,
cm_image_desc->cprof);
if (success)
xx_image_description_info_v2_send_done(cm_image_desc_info->owner);
xx_image_description_info_v4_send_done(cm_image_desc_info->owner);
/* All info sent, so destroy the object. */
wl_resource_destroy(cm_image_desc_info->owner);
@ -327,7 +327,7 @@ image_description_resource_destroy(struct wl_resource *cm_image_desc_res)
cm_image_desc_destroy(cm_image_desc);
}
static const struct xx_image_description_v2_interface
static const struct xx_image_description_v4_interface
image_description_implementation = {
.destroy = image_description_destroy,
.get_information = image_description_get_information,
@ -348,7 +348,7 @@ cm_image_desc_create(struct weston_color_manager *cm,
cm_image_desc = xzalloc(sizeof(*cm_image_desc));
cm_image_desc->owner =
wl_resource_create(client, &xx_image_description_v2_interface,
wl_resource_create(client, &xx_image_description_v4_interface,
version, image_description_id);
if (!cm_image_desc->owner) {
free(cm_image_desc);
@ -400,7 +400,7 @@ cm_output_get_image_description(struct wl_client *client,
* create only the resource and send the failed event. */
if (!head) {
cm_image_desc_res =
wl_resource_create(client, &xx_image_description_v2_interface,
wl_resource_create(client, &xx_image_description_v4_interface,
version, image_description_id);
if (!cm_image_desc_res) {
wl_resource_post_no_memory(cm_output_res);
@ -411,8 +411,8 @@ cm_output_get_image_description(struct wl_client *client,
&image_description_implementation,
NULL, image_description_resource_destroy);
xx_image_description_v2_send_failed(cm_image_desc_res,
XX_IMAGE_DESCRIPTION_V2_CAUSE_NO_OUTPUT,
xx_image_description_v4_send_failed(cm_image_desc_res,
XX_IMAGE_DESCRIPTION_V4_CAUSE_NO_OUTPUT,
"the wl_output global no longer exists");
return;
}
@ -436,7 +436,7 @@ cm_output_get_image_description(struct wl_client *client,
return;
}
xx_image_description_v2_send_ready(cm_image_desc->owner,
xx_image_description_v4_send_ready(cm_image_desc->owner,
cm_image_desc->cprof->id);
}
@ -474,7 +474,7 @@ cm_output_resource_destroy(struct wl_resource *cm_output_res)
wl_list_remove(wl_resource_get_link(cm_output_res));
}
static const struct xx_color_management_output_v2_interface
static const struct xx_color_management_output_v4_interface
cm_output_implementation = {
.destroy = cm_output_destroy,
.get_image_description = cm_output_get_image_description,
@ -506,7 +506,7 @@ weston_output_send_image_description_changed(struct weston_output *output)
* notifies that the output image description changed. */
wl_list_for_each(head, &output->head_list, output_link) {
wl_resource_for_each(res, &head->cm_output_resource_list)
xx_color_management_output_v2_send_image_description_changed(res);
xx_color_management_output_v4_send_image_description_changed(res);
/* wl_output.done should be sent after collecting all the
* changes related to the output. But in Weston we are lacking
@ -536,7 +536,7 @@ cm_get_output(struct wl_client *client, struct wl_resource *cm_res,
uint32_t version = wl_resource_get_version(cm_res);
struct wl_resource *res;
res = wl_resource_create(client, &xx_color_management_output_v2_interface,
res = wl_resource_create(client, &xx_color_management_output_v4_interface,
version, cm_output_id);
if (!res) {
wl_resource_post_no_memory(cm_res);
@ -579,8 +579,9 @@ cm_surface_set_image_description(struct wl_client *client,
/* The surface might have been already gone, in such case cm_surface is
* inert. */
if (!surface) {
/* TODO: This error will be surface intert in the future */
wl_resource_post_error(cm_surface_res,
XX_COLOR_MANAGEMENT_SURFACE_V2_ERROR_INERT,
XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_IMAGE_DESCRIPTION,
"the wl_surface has already been destroyed");
return;
}
@ -597,10 +598,9 @@ cm_surface_set_image_description(struct wl_client *client,
/* Invalid image description for this request, as it isn't ready yet. */
if (!cm_image_desc->cprof) {
/* TODO: the version of the xx protocol that we are using still
* does not have an error for this. Fix when we update to the
* next version. */
wl_resource_post_no_memory(cm_surface_res);
wl_resource_post_error(cm_surface_res,
XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_IMAGE_DESCRIPTION,
"the image description is not ready");
return;
}
@ -610,14 +610,14 @@ cm_surface_set_image_description(struct wl_client *client,
protocol_render_intent);
if (!render_intent) {
wl_resource_post_error(cm_surface_res,
XX_COLOR_MANAGEMENT_SURFACE_V2_ERROR_RENDER_INTENT,
XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_RENDER_INTENT,
"unknown render intent");
return;
}
if (!((cm->supported_rendering_intents >> render_intent->intent) & 1)) {
wl_resource_post_error(cm_surface_res,
XX_COLOR_MANAGEMENT_SURFACE_V2_ERROR_RENDER_INTENT,
XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_RENDER_INTENT,
"unsupported render intent");
return;
}
@ -643,8 +643,9 @@ cm_surface_unset_image_description(struct wl_client *client,
/* The surface might have been already gone, in such case cm_surface is
* inert. */
if (!surface) {
/* TODO: This error will be surface intert in the future */
wl_resource_post_error(cm_surface_res,
XX_COLOR_MANAGEMENT_SURFACE_V2_ERROR_INERT,
XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_IMAGE_DESCRIPTION,
"the wl_surface has already been destroyed");
return;
}
@ -654,42 +655,6 @@ cm_surface_unset_image_description(struct wl_client *client,
surface->pending.render_intent = NULL;
}
/**
* Called by clients when they want to know the preferred image description of
* the surface.
*/
static void
cm_surface_get_preferred(struct wl_client *client, struct wl_resource *cm_surface_res,
uint32_t image_description_id)
{
struct weston_surface *surface = wl_resource_get_user_data(cm_surface_res);
uint32_t version = wl_resource_get_version(cm_surface_res);
struct weston_color_manager *cm;
struct cm_image_desc *cm_image_desc;
/* The surface might have been already gone, in such case cm_surface is
* inert. */
if (!surface) {
wl_resource_post_error(cm_surface_res,
XX_COLOR_MANAGEMENT_SURFACE_V2_ERROR_INERT,
"the wl_surface has already been destroyed");
return;
}
cm = surface->compositor->color_manager;
cm_image_desc = cm_image_desc_create(cm, surface->preferred_color_profile,
client, version, image_description_id,
YES_GET_INFO);
if (!cm_image_desc) {
wl_resource_post_no_memory(cm_surface_res);
return;
}
xx_image_description_v2_send_ready(cm_image_desc->owner,
cm_image_desc->cprof->id);
}
/**
* Client will not use the cm_surface anymore, so we destroy its resource.
*/
@ -715,46 +680,21 @@ cm_surface_resource_destroy(struct wl_resource *cm_surface_res)
if (!surface)
return;
/* We are destroying the cm_surface_res, so simply remove it from
* weston_surface::cm_surface_resource_list. */
wl_list_remove(wl_resource_get_link(cm_surface_res));
surface->cm_surface = NULL;
/* TODO: if wl_list_empty(&surface->cm_surface_resource_list), we need
* to unset_image_description for the surface. The protocol states that
* we need to do that after the last cm_surface object for a wl_surface
* is destroyed.
*
* We still didn't add the code for that because there are discussions
* on the protocol upstream to allow a single cm_surface per surface.
* Once that reaches a conclusion and the changes land on the xx version
* of the protocol, we need to update this.
*/
/* Do the same as unset_image_description */
weston_color_profile_unref(surface->pending.color_profile);
surface->pending.color_profile = NULL;
surface->pending.render_intent = NULL;
}
static const struct xx_color_management_surface_v2_interface
static const struct xx_color_management_surface_v4_interface
cm_surface_implementation = {
.destroy = cm_surface_destroy,
.set_image_description = cm_surface_set_image_description,
.unset_image_description = cm_surface_unset_image_description,
.get_preferred = cm_surface_get_preferred,
};
/**
* Notifies clients that their surface preferred image description changed.
*
* \param surface The surface that changed its preferred image description.
*/
void
weston_surface_send_preferred_image_description_changed(struct weston_surface *surface)
{
struct wl_resource *res;
/* For each resource, send the event that notifies that the surface
* preferred image description changed. */
wl_resource_for_each(res, &surface->cm_surface_resource_list)
xx_color_management_surface_v2_send_preferred_changed(res);
}
/**
* Client called get_surface(). We already have the backing object, so just
* create a resource for the client.
@ -767,7 +707,14 @@ cm_get_surface(struct wl_client *client, struct wl_resource *cm_res,
uint32_t version = wl_resource_get_version(cm_res);
struct wl_resource *res;
res = wl_resource_create(client, &xx_color_management_surface_v2_interface,
if (surface->cm_surface) {
wl_resource_post_error(cm_res,
XX_COLOR_MANAGER_V4_ERROR_SURFACE_EXISTS,
"surface already requested");
return;
}
res = wl_resource_create(client, &xx_color_management_surface_v4_interface,
version, cm_surface_id);
if (!res) {
wl_resource_post_no_memory(cm_res);
@ -776,7 +723,122 @@ cm_get_surface(struct wl_client *client, struct wl_resource *cm_res,
wl_resource_set_implementation(res, &cm_surface_implementation,
surface, cm_surface_resource_destroy);
wl_list_insert(&surface->cm_surface_resource_list, wl_resource_get_link(res));
surface->cm_surface = res;
}
/**
* Client will not use the cm_feedback_surface anymore, so we destroy its resource.
*/
static void
cm_feedback_surface_destroy(struct wl_client *client,
struct wl_resource *cm_feedback_surface_res)
{
wl_resource_destroy(cm_feedback_surface_res);
}
/**
* Called by clients when they want to know the preferred image description of
* the surface.
*/
static void
cm_feedback_surface_get_preferred(struct wl_client *client,
struct wl_resource *cm_feedback_surface_res,
uint32_t image_description_id)
{
struct weston_surface *surface = wl_resource_get_user_data(cm_feedback_surface_res);
uint32_t version = wl_resource_get_version(cm_feedback_surface_res);
struct weston_color_manager *cm;
struct cm_image_desc *cm_image_desc;
/* The surface might have been already gone, in such case cm_feedback_surface is
* inert. */
if (!surface) {
wl_resource_post_error(cm_feedback_surface_res,
XX_COLOR_MANAGEMENT_FEEDBACK_SURFACE_V4_ERROR_INERT,
"the wl_surface has already been destroyed");
return;
}
cm = surface->compositor->color_manager;
cm_image_desc = cm_image_desc_create(cm, surface->preferred_color_profile,
client, version, image_description_id,
YES_GET_INFO);
if (!cm_image_desc) {
wl_resource_post_no_memory(cm_feedback_surface_res);
return;
}
xx_image_description_v4_send_ready(cm_image_desc->owner,
cm_image_desc->cprof->id);
}
static const struct xx_color_management_feedback_surface_v4_interface
cm_feedback_surface_implementation = {
.destroy = cm_feedback_surface_destroy,
.get_preferred = cm_feedback_surface_get_preferred,
};
/**
* Resource destruction function for the cm_feedback_surface.
*/
static void
cm_feedback_surface_resource_destroy(struct wl_resource *cm_feedback_surface_res)
{
struct weston_surface *surface = wl_resource_get_user_data(cm_feedback_surface_res);
/* For inert cm_feedback_surface, we don't have to do anything.
*
* We already did what was necessary when cm_feedback_surface became
* inert, in the surface destruction process (in weston_surface_unref(),
* which is the surface destruction function). */
if (!surface)
return;
/* We are destroying the cm_feedback_surface_res, so simply remove it from
* weston_surface::cm_feedback_surface_resource_list. */
wl_list_remove(wl_resource_get_link(cm_feedback_surface_res));
}
/**
* Notifies clients that their surface preferred image description changed.
*
* \param surface The surface that changed its preferred image description.
*/
void
weston_surface_send_preferred_image_description_changed(struct weston_surface *surface)
{
struct wl_resource *res;
/* For each resource, send the event that notifies that the surface
* preferred image description changed. */
wl_resource_for_each(res, &surface->cm_feedback_surface_resource_list)
xx_color_management_feedback_surface_v4_send_preferred_changed(res);
}
/**
* Client called get_feedback_surface(). We already have the backing object, so just
* create a resource for the client.
*/
static void
cm_get_feedback_surface(struct wl_client *client, struct wl_resource *cm_res,
uint32_t cm_surface_id, struct wl_resource *surface_res)
{
struct weston_surface *surface = wl_resource_get_user_data(surface_res);
uint32_t version = wl_resource_get_version(cm_res);
struct wl_resource *res;
res = wl_resource_create(client, &xx_color_management_feedback_surface_v4_interface,
version, cm_surface_id);
if (!res) {
wl_resource_post_no_memory(cm_res);
return;
}
wl_resource_set_implementation(res, &cm_feedback_surface_implementation,
surface, cm_feedback_surface_resource_destroy);
wl_list_insert(&surface->cm_feedback_surface_resource_list, wl_resource_get_link(res));
}
/**
@ -794,14 +856,14 @@ cm_creator_icc_set_icc_file(struct wl_client *client,
const char *err_msg;
if (cm_creator_icc->icc_data_length > 0) {
err_code = XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_ALREADY_SET;
err_code = XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_ALREADY_SET;
err_msg = "ICC file was already set";
goto err;
}
/* Length should be in the (0, 4MB] interval */
if (length == 0 || length > (4 * 1024 * 1024)) {
err_code = XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_BAD_SIZE;
err_code = XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_BAD_SIZE;
err_msg = "invalid ICC file size";
goto err;
}
@ -809,14 +871,14 @@ cm_creator_icc_set_icc_file(struct wl_client *client,
/* Fd should be readable. */
flags = fcntl(icc_profile_fd, F_GETFL);
if ((flags & O_ACCMODE) == O_WRONLY) {
err_code = XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_BAD_FD;
err_code = XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_BAD_FD;
err_msg = "ICC fd is not readable";
goto err;
}
/* Fd should be seekable. */
if (lseek(icc_profile_fd, 0, SEEK_CUR) < 0) {
err_code = XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_BAD_FD;
err_code = XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_BAD_FD;
err_msg = "ICC fd is not seekable";
goto err;
}
@ -872,8 +934,8 @@ create_image_description_color_profile_from_icc_creator(struct cm_image_desc *cm
bool ret;
if (!do_length_and_offset_fit(cm_creator_icc)) {
xx_image_description_v2_send_failed(cm_image_desc->owner,
XX_IMAGE_DESCRIPTION_V2_CAUSE_OPERATING_SYSTEM,
xx_image_description_v4_send_failed(cm_image_desc->owner,
XX_IMAGE_DESCRIPTION_V4_CAUSE_OPERATING_SYSTEM,
"length + offset does not fit off_t");
return -1;
}
@ -907,8 +969,8 @@ create_image_description_color_profile_from_icc_creator(struct cm_image_desc *cm
/* Reading the ICC failed */
free(icc_prof_data);
str_printf(&err_msg, "failed to read ICC file: %s", strerror(errno));
xx_image_description_v2_send_failed(cm_image_desc->owner,
XX_IMAGE_DESCRIPTION_V2_CAUSE_OPERATING_SYSTEM,
xx_image_description_v4_send_failed(cm_image_desc->owner,
XX_IMAGE_DESCRIPTION_V4_CAUSE_OPERATING_SYSTEM,
err_msg);
free(err_msg);
return -1;
@ -919,7 +981,7 @@ create_image_description_color_profile_from_icc_creator(struct cm_image_desc *cm
* the given ICC file don't simply change. */
free(icc_prof_data);
wl_resource_post_error(cm_creator_icc->owner,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_OUT_OF_FILE,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_OUT_OF_FILE,
"tried to read ICC beyond EOF");
return -1;
}
@ -942,15 +1004,15 @@ create_image_description_color_profile_from_icc_creator(struct cm_image_desc *cm
* color-manager plugins and decide if we should gracefully fail
* or return a protocol error.
*/
xx_image_description_v2_send_failed(cm_image_desc->owner,
XX_IMAGE_DESCRIPTION_V2_CAUSE_UNSUPPORTED,
xx_image_description_v4_send_failed(cm_image_desc->owner,
XX_IMAGE_DESCRIPTION_V4_CAUSE_UNSUPPORTED,
err_msg);
free(err_msg);
return -1;
}
cm_image_desc->cprof = cprof;
xx_image_description_v2_send_ready(cm_image_desc->owner,
xx_image_description_v4_send_ready(cm_image_desc->owner,
cm_image_desc->cprof->id);
return 0;
}
@ -974,7 +1036,7 @@ cm_creator_icc_create(struct wl_client *client, struct wl_resource *resource,
if (cm_creator_icc->icc_data_length == 0) {
wl_resource_post_error(resource,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_INCOMPLETE_SET,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_INCOMPLETE_SET,
"trying to create image description before " \
"setting the ICC file");
return;
@ -1020,7 +1082,7 @@ cm_creator_icc_destructor(struct wl_resource *resource)
free(cm_creator_icc);
}
static const struct xx_image_description_creator_icc_v2_interface
static const struct xx_image_description_creator_icc_v4_interface
cm_creator_icc_implementation = {
.create = cm_creator_icc_create,
.set_icc_file = cm_creator_icc_set_icc_file,
@ -1039,7 +1101,7 @@ cm_new_image_description_creator_icc(struct wl_client *client, struct wl_resourc
uint32_t version = wl_resource_get_version(cm_res);
if (!((cm->supported_color_features >> WESTON_COLOR_FEATURE_ICC) & 1)) {
wl_resource_post_error(cm_res, XX_COLOR_MANAGER_V2_ERROR_UNSUPPORTED_FEATURE,
wl_resource_post_error(cm_res, XX_COLOR_MANAGER_V4_ERROR_UNSUPPORTED_FEATURE,
"creating ICC image description creator is " \
"still unsupported");
return;
@ -1051,7 +1113,7 @@ cm_new_image_description_creator_icc(struct wl_client *client, struct wl_resourc
cm_creator_icc->icc_profile_fd = -1;
cm_creator_icc->owner =
wl_resource_create(client, &xx_image_description_creator_icc_v2_interface,
wl_resource_create(client, &xx_image_description_creator_icc_v4_interface,
version, cm_creator_icc_id);
if (!cm_creator_icc->owner)
goto err;
@ -1074,7 +1136,7 @@ cm_new_image_description_creator_params(struct wl_client *client, struct wl_reso
uint32_t cm_creator_params_id)
{
/* Still unsupported. */
wl_resource_post_error(cm_res, XX_COLOR_MANAGER_V2_ERROR_UNSUPPORTED_FEATURE,
wl_resource_post_error(cm_res, XX_COLOR_MANAGER_V4_ERROR_UNSUPPORTED_FEATURE,
"creating parametric image description creator is " \
"still unsupported");
}
@ -1089,11 +1151,12 @@ cm_destroy(struct wl_client *client, struct wl_resource *cm_res)
wl_resource_destroy(cm_res);
}
static const struct xx_color_manager_v2_interface
static const struct xx_color_manager_v4_interface
color_manager_implementation = {
.destroy = cm_destroy,
.get_output = cm_get_output,
.get_surface = cm_get_surface,
.get_feedback_surface = cm_get_feedback_surface,
.new_icc_creator = cm_new_image_description_creator_icc,
.new_parametric_creator = cm_new_image_description_creator_params,
};
@ -1112,7 +1175,7 @@ bind_color_management(struct wl_client *client, void *data, uint32_t version,
const struct weston_render_intent_info *render_intent;
unsigned int i;
resource = wl_resource_create(client, &xx_color_manager_v2_interface,
resource = wl_resource_create(client, &xx_color_manager_v4_interface,
version, id);
if (!resource) {
wl_client_post_no_memory(client);
@ -1127,7 +1190,7 @@ bind_color_management(struct wl_client *client, void *data, uint32_t version,
if (!((cm->supported_color_features >> i) & 1))
continue;
feature_info = weston_color_feature_info_from(compositor, i);
xx_color_manager_v2_send_supported_feature(resource,
xx_color_manager_v4_send_supported_feature(resource,
feature_info->protocol_feature);
}
@ -1136,7 +1199,7 @@ bind_color_management(struct wl_client *client, void *data, uint32_t version,
if (!((cm->supported_rendering_intents >> i) & 1))
continue;
render_intent = weston_render_intent_info_from(compositor, i);
xx_color_manager_v2_send_supported_intent(resource,
xx_color_manager_v4_send_supported_intent(resource,
render_intent->protocol_intent);
}
}
@ -1144,7 +1207,7 @@ bind_color_management(struct wl_client *client, void *data, uint32_t version,
/** Advertise color-management support
*
* Calling this initializes the color-management protocol support, so that
* xx_color_manager_v2_interface will be advertised to clients. Essentially it
* xx_color_manager_v4_interface will be advertised to clients. Essentially it
* creates a global. Do not call this function multiple times in the
* compositor's lifetime. There is no way to deinit explicitly, globals will be
* reaped when the wl_display gets destroyed.
@ -1162,7 +1225,7 @@ weston_compositor_enable_color_management_protocol(struct weston_compositor *com
WESTON_RENDER_INTENT_PERCEPTUAL);
if (!wl_global_create(compositor->wl_display,
&xx_color_manager_v2_interface,
&xx_color_manager_v4_interface,
version, compositor, bind_color_management))
return -1;

View File

@ -50,32 +50,32 @@ static const struct weston_color_feature_info color_feature_info_table[] = {
.feature = WESTON_COLOR_FEATURE_ICC,
.desc = "Allow clients to use the new_icc_creator request " \
"from the CM&HDR protocol extension",
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_ICC_V2_V4,
.protocol_feature = XX_COLOR_MANAGER_V4_FEATURE_ICC_V2_V4,
},
{
.feature = WESTON_COLOR_FEATURE_PARAMETRIC,
.desc = "Allow clients to use the new_parametric_creator " \
"request from the CM&HDR protocol extension",
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_PARAMETRIC,
.protocol_feature = XX_COLOR_MANAGER_V4_FEATURE_PARAMETRIC,
},
{
.feature = WESTON_COLOR_FEATURE_SET_PRIMARIES,
.desc = "Allow clients to use the parametric set_primaries " \
"request from the CM&HDR protocol extension",
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_SET_PRIMARIES,
.protocol_feature = XX_COLOR_MANAGER_V4_FEATURE_SET_PRIMARIES,
},
{
.feature = WESTON_COLOR_FEATURE_SET_TF_POWER,
.desc = "Allow clients to use the parametric set_tf_power " \
"request from the CM&HDR protocol extension",
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_SET_TF_POWER,
.protocol_feature = XX_COLOR_MANAGER_V4_FEATURE_SET_TF_POWER,
},
{
.feature = WESTON_COLOR_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES,
.desc = "Allow clients to use the parametric " \
"set_mastering_display_primaries request from the " \
"CM&HDR protocol extension",
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES,
.protocol_feature = XX_COLOR_MANAGER_V4_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES,
},
{
.feature = WESTON_COLOR_FEATURE_EXTENDED_TARGET_VOLUME,
@ -84,7 +84,7 @@ static const struct weston_color_feature_info color_feature_info_table[] = {
"primary color volume. This can only be supported when feature " \
"WESTON_COLOR_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES " \
"is supported",
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_EXTENDED_TARGET_VOLUME,
.protocol_feature = XX_COLOR_MANAGER_V4_FEATURE_EXTENDED_TARGET_VOLUME,
},
};
@ -92,35 +92,35 @@ static const struct weston_render_intent_info render_intent_info_table[] = {
{
.intent = WESTON_RENDER_INTENT_PERCEPTUAL,
.desc = "Perceptual",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_PERCEPTUAL,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL,
LCMS_INTENT(INTENT_PERCEPTUAL),
.bps = false,
},
{
.intent = WESTON_RENDER_INTENT_RELATIVE,
.desc = "Media-relative colorimetric",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_RELATIVE,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE,
LCMS_INTENT(INTENT_RELATIVE_COLORIMETRIC),
.bps = false,
},
{
.intent = WESTON_RENDER_INTENT_SATURATION,
.desc = "Saturation",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_SATURATION,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_SATURATION,
LCMS_INTENT(INTENT_SATURATION),
.bps = false,
},
{
.intent = WESTON_RENDER_INTENT_ABSOLUTE,
.desc = "ICC-absolute colorimetric",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_ABSOLUTE,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_ABSOLUTE,
LCMS_INTENT(INTENT_ABSOLUTE_COLORIMETRIC),
.bps = false,
},
{
.intent = WESTON_RENDER_INTENT_RELATIVE_BPC,
.desc = "Media-relative colorimetric + black point compensation",
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_RELATIVE_BPC,
.protocol_intent = XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE_BPC,
LCMS_INTENT(INTENT_RELATIVE_COLORIMETRIC),
.bps = true,
},
@ -131,7 +131,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
.primaries = WESTON_PRIMARIES_CICP_SRGB,
.desc = "Color primaries for the sRGB color space as defined by " \
"the BT.709 standard",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_SRGB,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_SRGB,
.color_gamut = {
.primary = { { 0.64, 0.33 }, /* RGB order */
{ 0.30, 0.60 },
@ -143,7 +143,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
{
.primaries = WESTON_PRIMARIES_CICP_PAL_M,
.desc = "Color primaries for PAL-M as defined by the BT.470 standard",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_PAL_M,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_PAL_M,
.color_gamut = {
.primary = { { 0.67, 0.33 }, /* RGB order */
{ 0.21, 0.71 },
@ -155,7 +155,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
{
.primaries = WESTON_PRIMARIES_CICP_PAL,
.desc = "Color primaries for PAL as defined by the BT.601 standard",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_PAL,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_PAL,
.color_gamut = {
.primary = { { 0.64, 0.33 }, /* RGB order */
{ 0.29, 0.60 },
@ -167,7 +167,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
{
.primaries = WESTON_PRIMARIES_CICP_NTSC,
.desc = "Color primaries for NTSC as defined by the BT.601 standard",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_NTSC,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_NTSC,
.color_gamut = {
.primary = { { 0.630, 0.340 }, /* RGB order */
{ 0.310, 0.595 },
@ -179,7 +179,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
{
.primaries = WESTON_PRIMARIES_CICP_GENERIC_FILM,
.desc = "Generic film with color filters using Illuminant C",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_GENERIC_FILM,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_GENERIC_FILM,
.color_gamut = {
.primary = { { 0.681, 0.319 }, /* RGB order */
{ 0.243, 0.692 },
@ -192,7 +192,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
.primaries = WESTON_PRIMARIES_CICP_BT2020,
.desc = "Color primaries as defined by the BT.2020 and BT.2100 " \
"standard",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_BT2020,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_BT2020,
.color_gamut = {
.primary = { { 0.708, 0.292 }, /* RGB order */
{ 0.170, 0.797 },
@ -204,7 +204,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
{
.primaries = WESTON_PRIMARIES_CICP_CIE1931_XYZ,
.desc = "Color primaries of the full CIE 1931 XYZ color space",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_CIE1931_XYZ,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_CIE1931_XYZ,
.color_gamut = {
.primary = { { 1.0, 0.0 }, /* RGB order */
{ 0.0, 1.0 },
@ -217,7 +217,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
.primaries = WESTON_PRIMARIES_CICP_DCI_P3,
.desc = "Color primaries of the DCI P3 color space as defined by " \
"the SMPTE RP 431 standard",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_DCI_P3,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_DCI_P3,
.color_gamut = {
.primary = { { 0.680, 0.320 }, /* RGB order */
{ 0.265, 0.690 },
@ -230,7 +230,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
.primaries = WESTON_PRIMARIES_CICP_DISPLAY_P3,
.desc = "Color primaries of Display P3 variant of the DCI-P3 color " \
"space as defined by the SMPTE EG 432 standard",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_DISPLAY_P3,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_DISPLAY_P3,
.color_gamut = {
.primary = { { 0.680, 0.320 }, /* RGB order */
{ 0.265, 0.690 },
@ -243,7 +243,7 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
.primaries = WESTON_PRIMARIES_ADOBE_RGB,
.desc = "Color primaries of the Adobe RGB color space as defined " \
"by the ISO 12640 standard",
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_ADOBE_RGB,
.protocol_primaries = XX_COLOR_MANAGER_V4_PRIMARIES_ADOBE_RGB,
.color_gamut = {
.primary = { { 0.64, 0.33 }, /* RGB order */
{ 0.21, 0.71 },
@ -258,85 +258,85 @@ static const struct weston_color_tf_info color_tf_info_table[] = {
{
.tf = WESTON_TF_LINEAR,
.desc = "Linear transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LINEAR,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LINEAR,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_GAMMA22,
.desc = "Assumed display gamma 2.2 transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_GAMMA22,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_GAMMA28,
.desc = "Assumed display gamma 2.8 transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_GAMMA28,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_SRGB,
.desc = "sRGB piece-wise transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_SRGB,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_EXT_SRGB,
.desc = "Extended sRGB piece-wise transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_EXT_SRGB,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_EXT_SRGB,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_BT709,
.desc = "BT.709 transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_BT709,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT709,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_BT1361,
.desc = "BT.1361 extended transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_BT1361,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT1361,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_ST240,
.desc = "SMPTE ST 240 transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST240,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST240,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_ST428,
.desc = "SMPTE ST 428 transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST428,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST428,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_ST2084_PQ,
.desc = "Perceptual quantizer transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST2084_PQ,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_LOG_100,
.desc = "Logarithmic 100:1 transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LOG_100,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_100,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_LOG_316,
.desc = "Logarithmic (100*Sqrt(10) : 1) transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LOG_316,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_316,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_XVYCC,
.desc = "IEC 61966-2-4 transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_XVYCC,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_XVYCC,
.has_parameters = NO_PARAMETERS,
},
{
.tf = WESTON_TF_HLG,
.desc = "Hybrid log-gamma transfer function",
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_HLG,
.protocol_tf = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_HLG,
.has_parameters = NO_PARAMETERS,
},
{

View File

@ -1002,7 +1002,8 @@ weston_surface_create(struct weston_compositor *compositor)
surface->current_protection = WESTON_HDCP_DISABLE;
surface->protection_mode = WESTON_SURFACE_PROTECTION_MODE_RELAXED;
wl_list_init(&surface->cm_surface_resource_list);
wl_list_init(&surface->cm_feedback_surface_resource_list);
surface->cm_surface = NULL;
/* The surfaces start with no color profile and render intent. It's up
* to the color manager what to do with that. Later, clients are able to
@ -2705,7 +2706,7 @@ weston_surface_unref(struct weston_surface *surface)
struct wl_resource *cb, *next;
struct weston_view *ev, *nv;
struct weston_pointer_constraint *constraint, *next_constraint;
struct wl_resource *cm_surface_res, *cm_surface_res_tmp;
struct wl_resource *cm_feedback_surface_res, *cm_feedback_surface_res_tmp;
struct weston_paint_node *pnode, *pntmp;
if (!surface)
@ -2761,12 +2762,15 @@ weston_surface_unref(struct weston_surface *surface)
weston_color_profile_unref(surface->color_profile);
weston_color_profile_unref(surface->preferred_color_profile);
wl_resource_for_each_safe(cm_surface_res, cm_surface_res_tmp,
&surface->cm_surface_resource_list) {
wl_list_remove(wl_resource_get_link(cm_surface_res));
wl_list_init(wl_resource_get_link(cm_surface_res));
wl_resource_set_user_data(cm_surface_res, NULL);
wl_resource_for_each_safe(cm_feedback_surface_res,
cm_feedback_surface_res_tmp,
&surface->cm_feedback_surface_resource_list) {
wl_list_remove(wl_resource_get_link(cm_feedback_surface_res));
wl_list_init(wl_resource_get_link(cm_feedback_surface_res));
wl_resource_set_user_data(cm_feedback_surface_res, NULL);
}
if (surface->cm_surface)
wl_resource_set_user_data(surface->cm_surface, NULL);
free(surface);
}

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@ const struct lcms_pipeline pipeline_sRGB = {
};
struct image_description {
struct xx_image_description_v2 *xx_image_descr;
struct xx_image_description_v4 *xx_image_descr;
enum image_description_status {
CM_IMAGE_DESC_NOT_CREATED = 0,
@ -81,9 +81,9 @@ struct image_description {
uint32_t icc_size;
/* For parametric images descriptions. */
enum xx_color_manager_v2_primaries primaries_named;
enum xx_color_manager_v4_primaries primaries_named;
struct weston_color_gamut primaries;
enum xx_color_manager_v2_transfer_function tf_named;
enum xx_color_manager_v4_transfer_function tf_named;
float tf_power;
struct weston_color_gamut target_primaries;
float target_min_lum, target_max_lum;
@ -92,7 +92,7 @@ struct image_description {
};
struct image_description_info {
struct xx_image_description_info_v2 *xx_image_description_info;
struct xx_image_description_info_v4 *xx_image_description_info;
struct image_description *image_descr;
/* Bitfield that holds what events the compositor has sent us through
@ -102,10 +102,11 @@ struct image_description_info {
};
struct color_manager {
struct xx_color_manager_v2 *manager;
struct xx_color_manager_v4 *manager;
struct xx_color_management_output_v2 *output;
struct xx_color_management_surface_v2 *surface;
struct xx_color_management_output_v4 *output;
struct xx_color_management_surface_v4 *surface;
struct xx_color_management_feedback_surface_v4 *feedback_surface;
struct wl_list image_descr_list; /* image_description::link */
@ -130,12 +131,12 @@ static void
image_description_destroy(struct image_description *image_descr)
{
wl_list_remove(&image_descr->link);
xx_image_description_v2_destroy(image_descr->xx_image_descr);
xx_image_description_v4_destroy(image_descr->xx_image_descr);
free(image_descr);
}
static void
image_descr_ready(void *data, struct xx_image_description_v2 *xx_image_description_v2,
image_descr_ready(void *data, struct xx_image_description_v4 *xx_image_description_v4,
uint32_t identity)
{
struct image_description *image_descr = data;
@ -144,7 +145,7 @@ image_descr_ready(void *data, struct xx_image_description_v2 *xx_image_descripti
}
static void
image_descr_failed(void *data, struct xx_image_description_v2 *xx_image_description_v2,
image_descr_failed(void *data, struct xx_image_description_v4 *xx_image_description_v4,
uint32_t cause, const char *msg)
{
struct image_description *image_descr = data;
@ -155,7 +156,7 @@ image_descr_failed(void *data, struct xx_image_description_v2 *xx_image_descript
" cause: %u, msg: %s\n", cause, msg);
}
static const struct xx_image_description_v2_listener
static const struct xx_image_description_v4_listener
image_descr_iface = {
.ready = image_descr_ready,
.failed = image_descr_failed,
@ -173,9 +174,9 @@ image_descr_info_received(struct image_description_info *image_descr_info,
static void
image_descr_info_primaries(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
uint32_t r_x, uint32_t r_y, uint32_t g_x, uint32_t g_y,
uint32_t b_x, uint32_t b_y, uint32_t w_x, uint32_t w_y)
struct xx_image_description_info_v4 *xx_image_description_info_v4,
int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y,
int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y)
{
struct image_description_info *image_descr_info = data;
struct image_description *image_descr = image_descr_info->image_descr;
@ -196,7 +197,7 @@ image_descr_info_primaries(void *data,
static void
image_descr_info_primaries_named(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
struct xx_image_description_info_v4 *xx_image_description_info_v4,
uint32_t primaries)
{
struct image_description_info *image_descr_info = data;
@ -210,7 +211,7 @@ image_descr_info_primaries_named(void *data,
static void
image_descr_info_tf_named(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
struct xx_image_description_info_v4 *xx_image_description_info_v4,
uint32_t tf)
{
struct image_description_info *image_descr_info = data;
@ -224,7 +225,7 @@ image_descr_info_tf_named(void *data,
static void
image_descr_info_tf_power(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
struct xx_image_description_info_v4 *xx_image_description_info_v4,
uint32_t tf_power)
{
struct image_description_info *image_descr_info = data;
@ -238,9 +239,9 @@ image_descr_info_tf_power(void *data,
static void
image_descr_info_target_primaries(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
uint32_t r_x, uint32_t r_y, uint32_t g_x, uint32_t g_y,
uint32_t b_x, uint32_t b_y, uint32_t w_x, uint32_t w_y)
struct xx_image_description_info_v4 *xx_image_description_info_v4,
int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y,
int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y)
{
struct image_description_info *image_descr_info = data;
struct image_description *image_descr = image_descr_info->image_descr;
@ -260,7 +261,7 @@ image_descr_info_target_primaries(void *data,
static void
image_descr_info_target_luminance(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
struct xx_image_description_info_v4 *xx_image_description_info_v4,
uint32_t min_lum, uint32_t max_lum)
{
struct image_description_info *image_descr_info = data;
@ -275,7 +276,7 @@ image_descr_info_target_luminance(void *data,
static void
image_descr_info_target_max_cll(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
struct xx_image_description_info_v4 *xx_image_description_info_v4,
uint32_t maxCLL)
{
struct image_description_info *image_descr_info = data;
@ -289,7 +290,7 @@ image_descr_info_target_max_cll(void *data,
static void
image_descr_info_target_max_fall(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
struct xx_image_description_info_v4 *xx_image_description_info_v4,
uint32_t maxFALL)
{
struct image_description_info *image_descr_info = data;
@ -303,7 +304,7 @@ image_descr_info_target_max_fall(void *data,
static void
image_descr_info_icc_file_event(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2,
struct xx_image_description_info_v4 *xx_image_description_info_v4,
int32_t icc_fd, uint32_t icc_size)
{
struct image_description_info *image_descr_info = data;
@ -361,19 +362,19 @@ are_events_received_valid(struct image_description_info *image_descr_info)
/* If we received tf named and exp power, they must match. */
if (received_tf_named && received_tf_power) {
if (image_descr->tf_named != XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_GAMMA22 &&
image_descr->tf_named != XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_GAMMA28) {
if (image_descr->tf_named != XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22 &&
image_descr->tf_named != XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28) {
testlog(" Error: parametric image description tf " \
"named is not pure power-law, but still received " \
"tf power event\n");
return false;
} else if (image_descr->tf_named == XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_GAMMA22 &&
} else if (image_descr->tf_named == XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22 &&
image_descr->tf_power != 2.2f) {
testlog(" Error: parametric image description tf named " \
"is pure power-law 2.2, but tf power received is %f\n",
image_descr->tf_power);
return false;
} else if (image_descr->tf_named == XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_GAMMA28 &&
} else if (image_descr->tf_named == XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28 &&
image_descr->tf_power != 2.8f) {
testlog(" Error: parametric image description tf named " \
"is pure power-law 2.8, but tf power received is %f\n",
@ -390,12 +391,12 @@ are_events_received_valid(struct image_description_info *image_descr_info)
static void
image_descr_info_done(void *data,
struct xx_image_description_info_v2 *xx_image_description_info_v2)
struct xx_image_description_info_v4 *xx_image_description_info_v4)
{
struct image_description_info *image_descr_info = data;
struct image_description *image_descr = image_descr_info->image_descr;
testlog("Image description info %p done:\n", xx_image_description_info_v2);
testlog("Image description info %p done:\n", xx_image_description_info_v4);
assert(are_events_received_valid(image_descr_info));
@ -458,7 +459,7 @@ image_descr_info_done(void *data,
testlog(" Target maxFALL: %.4f\n", image_descr->target_max_fall);
}
static const struct xx_image_description_info_v2_listener
static const struct xx_image_description_info_v4_listener
image_descr_info_iface = {
.primaries = image_descr_info_primaries,
.primaries_named = image_descr_info_primaries_named,
@ -473,7 +474,7 @@ image_descr_info_iface = {
};
static void
cm_supported_intent(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
cm_supported_intent(void *data, struct xx_color_manager_v4 *xx_color_manager_v4,
uint32_t render_intent)
{
struct color_manager *cm = data;
@ -482,7 +483,7 @@ cm_supported_intent(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
}
static void
cm_supported_feature(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
cm_supported_feature(void *data, struct xx_color_manager_v4 *xx_color_manager_v4,
uint32_t feature)
{
struct color_manager *cm = data;
@ -491,7 +492,7 @@ cm_supported_feature(void *data, struct xx_color_manager_v2 *xx_color_manager_v2
}
static void
cm_supported_tf_named(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
cm_supported_tf_named(void *data, struct xx_color_manager_v4 *xx_color_manager_v4,
uint32_t tf_code)
{
/* only used to create image descriptions using parameters, which is
@ -499,14 +500,14 @@ cm_supported_tf_named(void *data, struct xx_color_manager_v2 *xx_color_manager_v
}
static void
cm_supported_primaries_named(void *data, struct xx_color_manager_v2 *xx_color_manager_v2,
cm_supported_primaries_named(void *data, struct xx_color_manager_v4 *xx_color_manager_v4,
uint32_t primaries_code)
{
/* only used to create image descriptions using parameters, which is
* still unsupported by Weston. */
}
static const struct xx_color_manager_v2_listener
static const struct xx_color_manager_v4_listener
cm_iface = {
.supported_intent = cm_supported_intent,
.supported_feature = cm_supported_feature,
@ -522,28 +523,32 @@ color_manager_init(struct color_manager *cm, struct client *client)
wl_list_init(&cm->image_descr_list);
cm->manager = bind_to_singleton_global(client,
&xx_color_manager_v2_interface,
&xx_color_manager_v4_interface,
1);
xx_color_manager_v2_add_listener(cm->manager, &cm_iface, cm);
xx_color_manager_v4_add_listener(cm->manager, &cm_iface, cm);
cm->output = xx_color_manager_v2_get_output(cm->manager,
cm->output = xx_color_manager_v4_get_output(cm->manager,
client->output->wl_output);
cm->surface = xx_color_manager_v2_get_surface(cm->manager,
cm->surface = xx_color_manager_v4_get_surface(cm->manager,
client->surface->wl_surface);
cm->feedback_surface =
xx_color_manager_v4_get_feedback_surface(cm->manager,
client->surface->wl_surface);
client_roundtrip(client);
/* For now, Weston only supports the ICC image description creator. All
* the parametric parts of the protocol are still unsupported. */
assert(cm->supported_features == (1 << XX_COLOR_MANAGER_V2_FEATURE_ICC_V2_V4));
assert(cm->supported_features == (1 << XX_COLOR_MANAGER_V4_FEATURE_ICC_V2_V4));
/* Weston supports all rendering intents. */
assert(cm->supported_rendering_intents == ((1 << XX_COLOR_MANAGER_V2_RENDER_INTENT_PERCEPTUAL) |
(1 << XX_COLOR_MANAGER_V2_RENDER_INTENT_RELATIVE) |
(1 << XX_COLOR_MANAGER_V2_RENDER_INTENT_SATURATION) |
(1 << XX_COLOR_MANAGER_V2_RENDER_INTENT_ABSOLUTE) |
(1 << XX_COLOR_MANAGER_V2_RENDER_INTENT_RELATIVE_BPC)));
assert(cm->supported_rendering_intents == ((1 << XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL) |
(1 << XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE) |
(1 << XX_COLOR_MANAGER_V4_RENDER_INTENT_SATURATION) |
(1 << XX_COLOR_MANAGER_V4_RENDER_INTENT_ABSOLUTE) |
(1 << XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE_BPC)));
}
static void
@ -554,9 +559,10 @@ color_manager_fini(struct color_manager *cm)
wl_list_for_each_safe(image_descr, tmp, &cm->image_descr_list, link)
image_description_destroy(image_descr);
xx_color_management_output_v2_destroy(cm->output);
xx_color_management_surface_v2_destroy(cm->surface);
xx_color_manager_v2_destroy(cm->manager);
xx_color_management_output_v4_destroy(cm->output);
xx_color_management_surface_v4_destroy(cm->surface);
xx_color_management_feedback_surface_v4_destroy(cm->feedback_surface);
xx_color_manager_v4_destroy(cm->manager);
}
static struct image_description *
@ -565,9 +571,9 @@ get_output_image_description(struct color_manager *cm)
struct image_description *image_descr = image_description_create();
image_descr->xx_image_descr =
xx_color_management_output_v2_get_image_description(cm->output);
xx_color_management_output_v4_get_image_description(cm->output);
xx_image_description_v2_add_listener(image_descr->xx_image_descr,
xx_image_description_v4_add_listener(image_descr->xx_image_descr,
&image_descr_iface, image_descr);
wl_list_insert(&cm->image_descr_list, &image_descr->link);
@ -581,9 +587,9 @@ get_surface_preferred_image_description(struct color_manager *cm)
struct image_description *image_descr = image_description_create();
image_descr->xx_image_descr =
xx_color_management_surface_v2_get_preferred(cm->surface);
xx_color_management_feedback_surface_v4_get_preferred(cm->feedback_surface);
xx_image_description_v2_add_listener(image_descr->xx_image_descr,
xx_image_description_v4_add_listener(image_descr->xx_image_descr,
&image_descr_iface, image_descr);
wl_list_insert(&cm->image_descr_list, &image_descr->link);
@ -593,7 +599,7 @@ get_surface_preferred_image_description(struct color_manager *cm)
static struct image_description *
create_icc_based_image_description(struct color_manager *cm,
struct xx_image_description_creator_icc_v2 *image_descr_creator_icc,
struct xx_image_description_creator_icc_v4 *image_descr_creator_icc,
const char *icc_path)
{
struct image_description *image_descr = image_description_create();
@ -605,12 +611,12 @@ create_icc_based_image_description(struct color_manager *cm,
assert(fstat(icc_fd, &st) == 0);
xx_image_description_creator_icc_v2_set_icc_file(image_descr_creator_icc,
xx_image_description_creator_icc_v4_set_icc_file(image_descr_creator_icc,
icc_fd, 0, st.st_size);
image_descr->xx_image_descr =
xx_image_description_creator_icc_v2_create(image_descr_creator_icc);
xx_image_description_creator_icc_v4_create(image_descr_creator_icc);
xx_image_description_v2_add_listener(image_descr->xx_image_descr,
xx_image_description_v4_add_listener(image_descr->xx_image_descr,
&image_descr_iface, image_descr);
wl_list_insert(&cm->image_descr_list, &image_descr->link);
@ -684,7 +690,7 @@ TEST(smoke_test)
static void
image_descr_info_destroy(struct image_description_info *image_descr_info)
{
xx_image_description_info_v2_destroy(image_descr_info->xx_image_description_info);
xx_image_description_info_v4_destroy(image_descr_info->xx_image_description_info);
free(image_descr_info);
}
@ -698,9 +704,9 @@ image_descr_get_information(struct image_description *image_descr)
image_descr_info->image_descr = image_descr;
image_descr_info->xx_image_description_info =
xx_image_description_v2_get_information(image_descr->xx_image_descr);
xx_image_description_v4_get_information(image_descr->xx_image_descr);
xx_image_description_info_v2_add_listener(image_descr_info->xx_image_description_info,
xx_image_description_info_v4_add_listener(image_descr_info->xx_image_description_info,
&image_descr_info_iface,
image_descr_info);
@ -767,17 +773,17 @@ TEST(create_parametric_image_description_creator_object)
{
struct client *client;
struct color_manager cm;
struct xx_image_description_creator_params_v2 *param_creator;
struct xx_image_description_creator_params_v4 *param_creator;
client = create_client_and_test_surface(100, 100, 100, 100);
color_manager_init(&cm, client);
/* Parametric image description creator is still unsupported */
param_creator = xx_color_manager_v2_new_parametric_creator(cm.manager);
expect_protocol_error(client, &xx_color_manager_v2_interface,
XX_COLOR_MANAGER_V2_ERROR_UNSUPPORTED_FEATURE);
param_creator = xx_color_manager_v4_new_parametric_creator(cm.manager);
expect_protocol_error(client, &xx_color_manager_v4_interface,
XX_COLOR_MANAGER_V4_ERROR_UNSUPPORTED_FEATURE);
xx_image_description_creator_params_v2_destroy(param_creator);
xx_image_description_creator_params_v4_destroy(param_creator);
color_manager_fini(&cm);
client_destroy(client);
}
@ -786,14 +792,14 @@ TEST(create_image_description_before_setting_icc_file)
{
struct client *client;
struct color_manager cm;
struct xx_image_description_creator_icc_v2 *image_descr_creator_icc;
struct xx_image_description_v2 *image_desc;
struct xx_image_description_creator_icc_v4 *image_descr_creator_icc;
struct xx_image_description_v4 *image_desc;
client = create_client_and_test_surface(100, 100, 100, 100);
color_manager_init(&cm, client);
image_descr_creator_icc =
xx_color_manager_v2_new_icc_creator(cm.manager);
xx_color_manager_v4_new_icc_creator(cm.manager);
/* Try creating image description based on ICC profile but without
* setting the ICC file, what should fail.
@ -801,11 +807,11 @@ TEST(create_image_description_before_setting_icc_file)
* We expect a protocol error from unknown object, because the
* image_descr_creator_icc wl_proxy will get destroyed with the create
* call below. It is a destructor request. */
image_desc = xx_image_description_creator_icc_v2_create(image_descr_creator_icc);
image_desc = xx_image_description_creator_icc_v4_create(image_descr_creator_icc);
expect_protocol_error(client, NULL,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_INCOMPLETE_SET);
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_INCOMPLETE_SET);
xx_image_description_v2_destroy(image_desc);
xx_image_description_v4_destroy(image_desc);
color_manager_fini(&cm);
client_destroy(client);
}
@ -814,7 +820,7 @@ TEST(set_unreadable_icc_fd)
{
struct client *client;
struct color_manager cm;
struct xx_image_description_creator_icc_v2 *image_descr_creator_icc;
struct xx_image_description_creator_icc_v4 *image_descr_creator_icc;
int32_t icc_fd;
struct stat st;
@ -822,7 +828,7 @@ TEST(set_unreadable_icc_fd)
color_manager_init(&cm, client);
image_descr_creator_icc =
xx_color_manager_v2_new_icc_creator(cm.manager);
xx_color_manager_v4_new_icc_creator(cm.manager);
/* The file is being open with WRITE, not READ permission. So the
* compositor should complain. */
@ -831,13 +837,13 @@ TEST(set_unreadable_icc_fd)
assert(fstat(icc_fd, &st) == 0);
/* Try setting the bad ICC file fd, it should fail. */
xx_image_description_creator_icc_v2_set_icc_file(image_descr_creator_icc,
xx_image_description_creator_icc_v4_set_icc_file(image_descr_creator_icc,
icc_fd, 0, st.st_size);
expect_protocol_error(client, &xx_image_description_creator_icc_v2_interface,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_BAD_FD);
expect_protocol_error(client, &xx_image_description_creator_icc_v4_interface,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_BAD_FD);
close(icc_fd);
xx_image_description_creator_icc_v2_destroy(image_descr_creator_icc);
xx_image_description_creator_icc_v4_destroy(image_descr_creator_icc);
color_manager_fini(&cm);
client_destroy(client);
}
@ -846,26 +852,26 @@ TEST(set_bad_icc_size_zero)
{
struct client *client;
struct color_manager cm;
struct xx_image_description_creator_icc_v2 *image_descr_creator_icc;
struct xx_image_description_creator_icc_v4 *image_descr_creator_icc;
int32_t icc_fd;
client = create_client_and_test_surface(100, 100, 100, 100);
color_manager_init(&cm, client);
image_descr_creator_icc =
xx_color_manager_v2_new_icc_creator(cm.manager);
xx_color_manager_v4_new_icc_creator(cm.manager);
icc_fd = open(srgb_icc_profile_path, O_RDONLY);
assert(icc_fd >= 0);
/* Try setting ICC file with a bad size, it should fail. */
xx_image_description_creator_icc_v2_set_icc_file(image_descr_creator_icc,
xx_image_description_creator_icc_v4_set_icc_file(image_descr_creator_icc,
icc_fd, 0, 0);
expect_protocol_error(client, &xx_image_description_creator_icc_v2_interface,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_BAD_SIZE);
expect_protocol_error(client, &xx_image_description_creator_icc_v4_interface,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_BAD_SIZE);
close(icc_fd);
xx_image_description_creator_icc_v2_destroy(image_descr_creator_icc);
xx_image_description_creator_icc_v4_destroy(image_descr_creator_icc);
color_manager_fini(&cm);
client_destroy(client);
}
@ -874,28 +880,28 @@ TEST(set_bad_icc_non_seekable)
{
struct client *client;
struct color_manager cm;
struct xx_image_description_creator_icc_v2 *image_descr_creator_icc;
struct xx_image_description_creator_icc_v4 *image_descr_creator_icc;
int32_t fds[2];
client = create_client_and_test_surface(100, 100, 100, 100);
color_manager_init(&cm, client);
image_descr_creator_icc =
xx_color_manager_v2_new_icc_creator(cm.manager);
xx_color_manager_v4_new_icc_creator(cm.manager);
/* We need a non-seekable file, and pipes are non-seekable. */
assert(pipe(fds) >= 0);
/* Pretend that it has a valid size of 1024 bytes. That still should
* fail because the fd is non-seekable. */
xx_image_description_creator_icc_v2_set_icc_file(image_descr_creator_icc,
xx_image_description_creator_icc_v4_set_icc_file(image_descr_creator_icc,
fds[0], 0, 1024);
expect_protocol_error(client, &xx_image_description_creator_icc_v2_interface,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_BAD_FD);
expect_protocol_error(client, &xx_image_description_creator_icc_v4_interface,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_BAD_FD);
close(fds[0]);
close(fds[1]);
xx_image_description_creator_icc_v2_destroy(image_descr_creator_icc);
xx_image_description_creator_icc_v4_destroy(image_descr_creator_icc);
color_manager_fini(&cm);
client_destroy(client);
}
@ -904,7 +910,7 @@ TEST(set_icc_twice)
{
struct client *client;
struct color_manager cm;
struct xx_image_description_creator_icc_v2 *image_descr_creator_icc;
struct xx_image_description_creator_icc_v4 *image_descr_creator_icc;
int32_t icc_fd;
struct stat st;
@ -912,24 +918,24 @@ TEST(set_icc_twice)
color_manager_init(&cm, client);
image_descr_creator_icc =
xx_color_manager_v2_new_icc_creator(cm.manager);
xx_color_manager_v4_new_icc_creator(cm.manager);
icc_fd = open(srgb_icc_profile_path, O_RDONLY);
assert(icc_fd >= 0);
assert(fstat(icc_fd, &st) == 0);
xx_image_description_creator_icc_v2_set_icc_file(image_descr_creator_icc,
xx_image_description_creator_icc_v4_set_icc_file(image_descr_creator_icc,
icc_fd, 0, st.st_size);
client_roundtrip(client);
/* Set the ICC again, what should fail. */
xx_image_description_creator_icc_v2_set_icc_file(image_descr_creator_icc,
xx_image_description_creator_icc_v4_set_icc_file(image_descr_creator_icc,
icc_fd, 0, st.st_size);
expect_protocol_error(client, &xx_image_description_creator_icc_v2_interface,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V2_ERROR_ALREADY_SET);
expect_protocol_error(client, &xx_image_description_creator_icc_v4_interface,
XX_IMAGE_DESCRIPTION_CREATOR_ICC_V4_ERROR_ALREADY_SET);
close(icc_fd);
xx_image_description_creator_icc_v2_destroy(image_descr_creator_icc);
xx_image_description_creator_icc_v4_destroy(image_descr_creator_icc);
color_manager_fini(&cm);
client_destroy(client);
}
@ -938,7 +944,7 @@ TEST(create_icc_image_description_no_info)
{
struct client *client;
struct color_manager cm;
struct xx_image_description_creator_icc_v2 *image_descr_creator_icc;
struct xx_image_description_creator_icc_v4 *image_descr_creator_icc;
struct image_description *image_descr;
struct image_description_info *image_descr_info;
@ -946,7 +952,7 @@ TEST(create_icc_image_description_no_info)
color_manager_init(&cm, client);
image_descr_creator_icc =
xx_color_manager_v2_new_icc_creator(cm.manager);
xx_color_manager_v4_new_icc_creator(cm.manager);
/* Create image description based on ICC profile */
image_descr = create_icc_based_image_description(&cm, image_descr_creator_icc,
@ -956,8 +962,8 @@ TEST(create_icc_image_description_no_info)
/* Get image description information, and that should fail. Images
* descriptions that we create do not accept this request. */
image_descr_info = image_descr_get_information(image_descr);
expect_protocol_error(client, &xx_image_description_v2_interface,
XX_IMAGE_DESCRIPTION_V2_ERROR_NO_INFORMATION);
expect_protocol_error(client, &xx_image_description_v4_interface,
XX_IMAGE_DESCRIPTION_V4_ERROR_NO_INFORMATION);
image_descr_info_destroy(image_descr_info);
color_manager_fini(&cm);
@ -968,14 +974,14 @@ TEST(set_surface_image_description)
{
struct client *client;
struct color_manager cm;
struct xx_image_description_creator_icc_v2 *image_descr_creator_icc;
struct xx_image_description_creator_icc_v4 *image_descr_creator_icc;
struct image_description *image_descr;
client = create_client_and_test_surface(100, 100, 100, 100);
color_manager_init(&cm, client);
image_descr_creator_icc =
xx_color_manager_v2_new_icc_creator(cm.manager);
xx_color_manager_v4_new_icc_creator(cm.manager);
/* Create image description based on ICC profile */
image_descr = create_icc_based_image_description(&cm, image_descr_creator_icc,
@ -983,9 +989,9 @@ TEST(set_surface_image_description)
wait_until_image_description_ready(client, image_descr);
/* Set surface image description */
xx_color_management_surface_v2_set_image_description(cm.surface,
xx_color_management_surface_v4_set_image_description(cm.surface,
image_descr->xx_image_descr,
XX_COLOR_MANAGER_V2_RENDER_INTENT_PERCEPTUAL);
XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL);
client_roundtrip(client);
color_manager_fini(&cm);