[RFC wayland-protocols v2 1/1] Add the color-management protocol

Pekka Paalanen ppaalanen at gmail.com
Tue Feb 26 15:48:15 UTC 2019


On Sun, 22 Jan 2017 13:31:35 +0100
Niels Ole Salscheider <niels_ole at salscheider-online.de> wrote:

> Signed-off-by: Niels Ole Salscheider <niels_ole at salscheider-online.de>

Hi Niels,

it is about high time I commented on this, sorry. I saw the color
management topic being picked up again with HDR. I wanted to review
this before I look at the latest proposal from Sebastian, because this
was there first, uncommented in its current form and not mentioned by
Sebastian at all from a very quick glance.

I think the fundamental idea here is exactly right: let a client
describe the content it delivers so that the compositor can display it
as correctly on any output as possible, while giving the client
information about the outputs (and compositor) so that it can optimise
its content and choice of color space.

My failing is that I haven't read about what ICC v4 definition actually
describes, does it characterise content or a device, or is it more
about defining a transformation from something to something without
saying what something is.

> ---
>  Makefile.am                                        |   1 +
>  unstable/color-management/README                   |   4 +
>  .../color-management-unstable-v1.xml               | 224 +++++++++++++++++++++
>  3 files changed, 229 insertions(+)
>  create mode 100644 unstable/color-management/README
>  create mode 100644 unstable/color-management/color-management-unstable-v1.xml
> 
> diff --git a/Makefile.am b/Makefile.am
> index e693afa..ff435d5 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -12,6 +12,7 @@ unstable_protocols =								\
>  	unstable/tablet/tablet-unstable-v2.xml			                \
>  	unstable/xdg-foreign/xdg-foreign-unstable-v1.xml			\
>  	unstable/idle-inhibit/idle-inhibit-unstable-v1.xml			\
> +	unstable/color-management/color-management-unstable-v1.xml		\
>  	$(NULL)
>  
>  stable_protocols =								\
> diff --git a/unstable/color-management/README b/unstable/color-management/README
> new file mode 100644
> index 0000000..3bd3e6c
> --- /dev/null
> +++ b/unstable/color-management/README
> @@ -0,0 +1,4 @@
> +Color management protocol
> +
> +Maintainers:
> +Niels Ole Salscheider <niels_ole at salscheider-online.de>
> diff --git a/unstable/color-management/color-management-unstable-v1.xml b/unstable/color-management/color-management-unstable-v1.xml
> new file mode 100644
> index 0000000..3fe6c93
> --- /dev/null
> +++ b/unstable/color-management/color-management-unstable-v1.xml
> @@ -0,0 +1,224 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<protocol name="color_management_unstable_v1">
> +
> +  <copyright>
> +    Copyright © 2014-2016 Niels Ole Salscheider
> +
> +    Permission to use, copy, modify, distribute, and sell this
> +    software and its documentation for any purpose is hereby granted
> +    without fee, provided that the above copyright notice appear in
> +    all copies and that both that copyright notice and this permission
> +    notice appear in supporting documentation, and that the name of
> +    the copyright holders not be used in advertising or publicity
> +    pertaining to distribution of the software without specific,
> +    written prior permission.  The copyright holders make no
> +    representations about the suitability of this software for any
> +    purpose.  It is provided "as is" without express or implied
> +    warranty.
> +
> +    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
> +    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
> +    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
> +    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
> +    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
> +    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
> +    THIS SOFTWARE.
> +  </copyright>
> +
> +  <interface name="zwp_color_management_v1" version="1">
> +    <description summary="allows attaching a color profile to a wl_surface">
> +      This interface allows to attach a color profile to a wl_surface. The
> +      compositor uses this information to display the colors correctly.

This is a global interface advertised through wl_registry, right?

> +
> +      This interface also provides requests to query the sRGB and the preferred
> +      color space. It further allows creation of a color profile object from an
> +      ICC profile. The client is informed by an event if the color profile of
> +      one of the outputs changes.
> +
> +      This protocol exposes two ways to attach color profiles to a surface.
> +      Most applications are expected to simply call set_color_profile to attach
> +      a color profile to a surface. The compositor then makes sure that the
> +      colors are converted to the correct ouput color space.

Typo: ouput

> +      If blending is performed, the compositor will convert all surfaces to a
> +      blending color space and perform blending. It will then convert the output
> +      surface to the color space of the output device.
> +
> +      If an application wants to perform gamut mapping on its own it must query
> +      the color profiles of the outputs. It can then create device link profiles
> +      that describe the transformation from input to output color space. These
> +      device link profiles can be attached to a surface by calling
> +      set_device_link_profile.
> +      When a device link profile is set for a given surface and output, the
> +      compositor will only apply this profile instead of the normal color
> +      transformation pipeline. Blending (if necessary) will be performed late in
> +      the output color space.
> +      The normal color transformation pipeline will be used for all outputs for
> +      which no device link profiles are available.
> +    </description>

This interface seems to be missing a destroy request.

> +
> +    <request name="set_color_profile">
> +      <description summary="set the color profile of a wl_surface">
> +        With this request, the color profile of a wl_surface can be set.
> +        The previously attached color profile will be replaced by the new one.
> +        Initially, the sRGB color profile is attached to a surface before
> +        set_color_profile is called for the first time.
> +        The color profile is applied after the next wl_surface.commit request.

The canonical language to spell that is:

"The color profile is double-buffered state, see wl_surface.commit."

The reason I prefer the exact wording from the wl_surface specification
is that the sub-surface specification modifies that behaviour, and we
don't want to override the sub-surface specification here.

> +      </description>
> +      <arg name="surface" type="object" interface="wl_surface"
> +           summary="the surface on which the color profile is attached" />
> +      <arg name="color_profile" type="object"
> +           interface="zwp_color_profile_v1" summary="the color profile" />

This is one way of designing this, wp_presentation.feedback works like
this.

The other way is that the global interface has a request that creates an
additional interface object for a given wl_surface, and then the
additional operations are done through the new object. If you want, you
can mandate that only one additional object can be created per
wl_surface, the existence of the additional object alone can already
trigger something, and you can remove the added effects by simply
destroying the object. The disadvantages are having yet another object
(but they are very cheap) and dealing with wl_surface being destroyed.

Since you may have use for resetting the wl_surface to a state before
the additional properties were applied, creating the extra object and
leveraging its destroy request would be convenient.

> +    </request>
> +
> +    <request name="set_device_link_profile">
> +      <description summary="set a device link profile for a wl_surface and wl_output">
> +        With this request, a device link profile can be attached to a
> +        wl_surface. For each output on which the surface is visible, the
> +        compositor will check if there is a device link profile. If there is one
> +        it will be used to directly convert the surface to the output color
> +        space. Blending of this surface (if necessary) will then be performed in
> +        the output color space and after the normal blending operations.

Are those blending rules actually implementable?

It is not generally possible to blend some surfaces into a temporary
buffer, convert that to the next color space, and then blend some more,
because the necessary order of blending operations depends on the
z-order of the surfaces.

What implications does this have on the CRTC color processing pipeline?

If a CRTC color processing pipeline, that is, the transformation from
framebuffer values to on-the-wire values for a monitor, is already set
up by the compositor's preference, what would a device link profile
look like? Does it produce on-the-wire or blending space?

If the transformation defined by the device link profile produced
values for the monitor wire, then the compositor will have to undo the
CRTC pipeline transformation during composition for this surface, or it
needs to reset CRTC pipeline setup to identity and apply it manually
for all other surfaces.

What is the use for a device link profile?

If the client says the content is according to a certain specification
(set_color_profile) and the compositor combines that with the output's
color profile to produce the on-the-wire pixel values, how would
setting a device link profile produce something different?

> +        The device link profile is applied after the next wl_surface.commit
> +        request.

"The device link profile is double-buffered state, see
wl_surface.commit."

> +      </description>
> +      <arg name="surface" type="object" interface="wl_surface"
> +           summary="the surface for which the device link profile should be used" />
> +      <arg name="output" type="object" interface="wl_output"
> +           summary="the output for which the device link profile was created" />
> +      <arg name="device_link_profile" type="object"
> +           interface="zwp_color_profile_v1" summary="the device link profile" />
> +    </request>
> +
> +    <request name="remove_device_link_profile">
> +      <description summary="removes a device link profile from a wl_surface">
> +        With this request, a device link profile for a given output can be
> +        removed from a wl_surface. If the surface is still visible on the
> +        output the color conversion will be done with the normal color profile
> +        attached to the surface.
> +        This request takes effect after the next wl_surface.commit request.

The canonical wording again, please.

> +      </description>
> +      <arg name="surface" type="object" interface="wl_surface"
> +           summary="the surface from which the device link should be removed" />
> +      <arg name="output" type="object" interface="wl_output"
> +           summary="the output for which the device link should be removed" />
> +    </request>
> +
> +    <request name="color_profile_from_fd">
> +      <description summary="creates a zwp_color_profile_v1 object from an ICC profile">
> +        This request allows to create a zwp_color_profile_v1 object from an ICC
> +        profile. The fd argument is the file descriptor to the ICC profile (ICC
> +        V2 or V4).
> +      </description>
> +      <arg name="fd" type="fd"
> +           summary="the file descriptor of the ICC profile data" />

I recall Daniel asked for size and maybe offset to accompany the fd.
wl_shm.create_pool has a precedent about size,
wl_shm_pool.create_buffer has the offset. wl_keyboard.keymap has size.

If there is only the fd, you can fstat() it to get a size, but that
may not be the exact size of the payload. Does the ICC data header or
such indicate the exact size of the payload?

> +      <arg name="id" type="new_id" interface="zwp_color_profile_v1"
> +           summary="the new color profile object" />
> +    </request>
> +
> +    <request name="output_color_profile">
> +      <description summary="create a color profile object for the requested output">
> +        This request returns a zwp_color_profile_v1 object for the requested
> +        output. A client can use this if it wants to know the color profile of
> +        an output (e. g. to create a device link profile).
> +      </description>
> +      <arg name="output" type="object" interface="wl_output"
> +           summary="the output for which a color profile object should be created" />
> +      <arg name="id" type="new_id" interface="zwp_color_profile_v1"
> +           summary="the new color profile object" />
> +    </request>
> +
> +    <request name="srgb_color_profile">
> +      <description summary="create a new sRGB color profile object">
> +        This request returns a zwp_color_profile_1 object for the sRGB color
> +        profile. The sRGB color profile is initially attached to all surfaces.
> +      </description>
> +      <arg name="id" type="new_id" interface="zwp_color_profile_v1"
> +           summary="the new color profile object" />
> +    </request>
> +
> +    <request name="preferred_color_space">
> +      <description summary="create a color profile object for the preferred color space">
> +        This request returns a zwp_color_profile_v1 object for the preferred
> +        color space of the compositor. This might be the blending color space
> +        of the compositor.
> +        A client should render in the color space returned by this request if it
> +        does any color conversion on its own. It might also want to use it as
> +        its blending space.
> +        Doing so might allow the compositor to skip one color conversion.
> +      </description>
> +      <arg name="id" type="new_id" interface="zwp_color_profile_v1"
> +           summary="the new color profile object" />
> +    </request>
> +
> +    <event name="output_color_profile_changed">
> +      <description summary="tells the client that the color profile of an output changed">
> +        This event will be sent when the color profile of an output changes.
> +      </description>
> +      <arg name="output" type="object" interface="wl_output"
> +           summary="the output of which the color profile changed" />
> +    </event>
> +
> +    <enum name="error">
> +      <entry name="invalid_profile" value="0"
> +             summary="the passed ICC data is invalid" />
> +    </enum>
> +  </interface>
> +
> +  <interface name="zwp_color_profile_v1" version="1">
> +    <description summary="represents a color profile">
> +      This interface represents a color profile that can be attached to
> +      surfaces. It is used by the zwp_color_management_v1 interface.
> +    </description>
> +
> +    <request name="destroy" type="destructor">
> +      <description summary="destroys the zwp_color_profile_v1 object">
> +        Informs the server that the client will not be using this protocol
> +        object anymore. It must not be attached to any surface anymore.

You need an error code for being still attached.

This will make destroying an sRGB color profile object interesting for
a client, because that profile is attached by default to all
wl_surfaces.

> +      </description>
> +    </request>
> +
> +    <request name="get_profile_fd">
> +      <description summary="get a file descriptor to the profile data">
> +        This request will cause a profile_fd event that returns a file
> +        descriptor to the ICC profile data.
> +      </description>
> +    </request>
> +
> +    <event name="profile_fd">
> +      <description summary="file descriptor to the profile data">
> +        This event occurs after a get_profile_fd request and returns the file
> +        descriptor to the ICC profile data.
> +      </description>
> +      <arg name="fd" type="fd" summary="ICC profile fd" />

The same comments about size or offset as further above.

> +    </event>
> +
> +    <request name="get_profile_md5">
> +      <description summary="get an MD5 checksum of the profile data">
> +        This request will cause a profile_md5 event that returns the MD5
> +        checksum of the ICC profile data.
> +      </description>
> +    </request>
> +
> +    <event name="profile_md5">
> +      <description summary="MD5 checksum of the profile data">
> +        This event occurs after a get_profile_md5 request and returns the MD5
> +        checksum of the ICC profile data. This MD5 checksum can be used to
> +        compare ICC profiles.
> +        The 128 bit MD5 checksum is calculated using the MD5 fingerprinting
> +        method as defined in Internet RFC 1321. In accordance with the ICC v4
> +        specification, the entire profile is used for this with the profile
> +        flags field, rendering intent field and profile ID field temporarily set
> +        to zeros.
> +      </description>
> +      <arg name="md5_3" type="uint"
> +           summary="highest 32 bit of the MD5 checksum" />
> +      <arg name="md5_2" type="uint"
> +           summary="second highest 32 bit of the MD5 checksum" />
> +      <arg name="md5_1" type="uint"
> +           summary="second lowest 32 bit of the MD5 checksum" />
> +      <arg name="md5_0" type="uint"
> +           summary="lowest 32 bit of the MD5 checksum" />
> +    </event>
> +  </interface>
> +</protocol>

Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20190226/21479e8c/attachment-0001.sig>


More information about the wayland-devel mailing list