weston/libweston/color.h
Pekka Paalanen dfba19abde color: simplify color manager API with weston_output_color_outcome
I am going to need to add yet another output property to be set by a
color manager: HDR Static Metadata Type 1. With the old color manager
API design, I would have needed to add the fourth function pointer to be
called always in the same group as the previous three. This seemed more
convoluted than it needs to be.

Therefore collapse the three existing function pointers in the API into
just one that is resposible for setting up all three things.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
2022-05-06 09:33:35 +00:00

358 lines
11 KiB
C

/*
* Copyright 2021 Collabora, Ltd.
* Copyright 2021 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef WESTON_COLOR_H
#define WESTON_COLOR_H
#include <stdbool.h>
#include <stdint.h>
#include <libweston/libweston.h>
/**
* Represents a color profile description (an ICC color profile)
*
* Sub-classed by the color manager that created this.
*/
struct weston_color_profile {
struct weston_color_manager *cm;
int ref_count;
char *description;
};
/** Type or formula for a curve */
enum weston_color_curve_type {
/** Identity function, no-op */
WESTON_COLOR_CURVE_TYPE_IDENTITY = 0,
/** Three-channel, one-dimensional look-up table */
WESTON_COLOR_CURVE_TYPE_LUT_3x1D,
};
/** LUT_3x1D parameters */
struct weston_color_curve_lut_3x1d {
/**
* Approximate a color curve with three 1D LUTs
*
* A 1D LUT is a mapping from [0.0, 1.0] to arbitrary values. The first
* element in the LUT corresponds to input value 0.0, and the last
* element corresponds to input value 1.0. The step from one element
* to the next in input space is 1.0 / (len - 1). When input value is
* between two elements, linear interpolation should be used.
*
* This function fills in the given array with the LUT values.
*
* \param xform This color transformation object.
* \param len The number of elements in each 1D LUT.
* \param values Array of 3 x len elements. First R channel
* LUT, immediately followed by G channel LUT, and then B channel LUT.
*/
void
(*fill_in)(struct weston_color_transform *xform,
float *values, unsigned len);
/** Optimal 1D LUT length for storage vs. precision */
unsigned optimal_len;
};
/**
* A scalar function for color encoding and decoding
*
* This object can represent a one-dimensional function that is applied
* independently to each of the color channels. Depending on the type and
* parameterization of the curve, all color channels may use the
* same function or each may have separate parameters.
*
* This is usually used for EOTF or EOTF^-1 and to optimize a 3D LUT size
* without sacrificing precision, both in one step.
*/
struct weston_color_curve {
/** Which member of 'u' defines the curve. */
enum weston_color_curve_type type;
/** Parameters for the curve. */
union {
/* identity: no parameters */
struct weston_color_curve_lut_3x1d lut_3x1d;
} u;
};
/** Type or formula for a color mapping */
enum weston_color_mapping_type {
/** Identity function, no-op */
WESTON_COLOR_MAPPING_TYPE_IDENTITY = 0,
/** 3D-dimensional look-up table */
WESTON_COLOR_MAPPING_TYPE_3D_LUT,
};
/**
* A three-dimensional look-up table
*
* A 3D LUT is a three-dimensional array where each element is an RGB triplet.
* A 3D LUT is usually an approximation of some arbitrary color mapping
* function that cannot be represented in any simpler form. The array contains
* samples from the approximated function, and values between samples are
* estimated by interpolation. The array is accessed with three indices, one
* for each input dimension (color channel).
*
* Color channel values in the range [0.0, 1.0] are mapped linearly to
* 3D LUT indices such that 0.0 maps exactly to the first element and 1.0 maps
* exactly to the last element in each dimension.
*
* This object represents a 3D LUT and offers an interface for realizing it
* as a data array with a custom size.
*/
struct weston_color_mapping_3dlut {
/**
* Create a 3D LUT data array
*
* \param xform This color transformation object.
* \param values Memory to hold the resulting data array.
* \param len The number of elements in each dimension.
*
* The array \c values must be at least 3 * len * len * len elements
* in size.
*
* Given the red index ri, green index gi and blue index bi, the
* corresponding array element index
*
* i = 3 * (len * len * bi + len * gi + ri) + c
*
* where
*
* c = 0 for red output value,
* c = 1 for green output value, and
* c = 2 for blue output value
*/
void
(*fill_in)(struct weston_color_transform *xform,
float *values, unsigned len);
/** Optimal 3D LUT size along each dimension */
unsigned optimal_len;
};
/**
* Color mapping function
*
* This object can represent a 3D LUT to do a color space conversion
*
*/
struct weston_color_mapping {
/** Which member of 'u' defines the color mapping type */
enum weston_color_mapping_type type;
/** Parameters for the color mapping function */
union {
/* identity: no parameters */
struct weston_color_mapping_3dlut lut3d;
} u;
};
/**
* Describes a color transformation formula
*
* Guaranteed unique, de-duplicated.
*
* Sub-classed by the color manager that created this.
*
* For a renderer to support WESTON_CAP_COLOR_OPS it must implement everything
* that this structure can represent.
*/
struct weston_color_transform {
struct weston_color_manager *cm;
int ref_count;
/* for renderer or backend to attach their own cached objects */
struct wl_signal destroy_signal;
/* Color transform is the series of steps: */
/** Step 1: color model change */
/* YCbCr→RGB conversion, but that is done elsewhere */
/** Step 2: color curve before color mapping */
struct weston_color_curve pre_curve;
/** Step 3: color mapping */
struct weston_color_mapping mapping;
/** Step 4: color curve after color mapping */
/* struct weston_color_curve post_curve; */
};
/**
* How content color needs to be transformed
*
* This object is specific to the color properties of the weston_surface and
* weston_output it was created for. It is automatically destroyed if any
* relevant color properties change.
*
* Fundamentally this contains the color transformation from content color
* space to an output's blending color space. This is stored in field
* 'transform' with NULL value corresponding to identity transformation.
*
* For graphics pipeline optimization purposes, the field 'identity_pipeline'
* indicates whether the combination of 'transform' here and the output's
* blending color space to monitor color space transformation total to
* identity transformation. This helps detecting cases where renderer bypass
* (direct scanout) is possible.
*/
struct weston_surface_color_transform {
/** Transformation from source to blending space */
struct weston_color_transform *transform;
/** True, if source colorspace is identical to monitor color space */
bool identity_pipeline;
};
struct weston_color_manager {
/** Identifies this CMS component */
const char *name;
/** This compositor instance */
struct weston_compositor *compositor;
/** Supports the Wayland CM&HDR protocol extension? */
bool supports_client_protocol;
/** Initialize color manager */
bool
(*init)(struct weston_color_manager *cm);
/** Destroy color manager */
void
(*destroy)(struct weston_color_manager *cm);
/** Destroy a color profile after refcount fell to zero */
void
(*destroy_color_profile)(struct weston_color_profile *cprof);
/** Create a color profile from ICC data
*
* \param cm The color manager.
* \param icc_data Pointer to the ICC binary data.
* \param icc_len Length of the ICC data in bytes.
* \param name_part A string to be used in describing the profile.
* \param cprof_out On success, the created object is returned here.
* On failure, untouched.
* \param errmsg On success, untouched. On failure, a pointer to a
* string describing the error is stored here. The string must be
* free()'d.
* \return True on success, false on failure.
*
* This may return a new reference to an existing color profile if
* that profile is identical to the one that would be created, apart
* from name_part.
*/
bool
(*get_color_profile_from_icc)(struct weston_color_manager *cm,
const void *icc_data,
size_t icc_len,
const char *name_part,
struct weston_color_profile **cprof_out,
char **errmsg);
/** Destroy a color transform after refcount fell to zero */
void
(*destroy_color_transform)(struct weston_color_transform *xform);
/** Get surface to output's blending space transformation
*
* \param cm The color manager.
* \param surface The surface for the source color space.
* \param output The output for the destination blending color space.
* \param surf_xform For storing the color transformation and
* additional information.
*
* The callee is responsible for increasing the reference count on the
* weston_color_transform it stores into surf_xform.
*/
bool
(*get_surface_color_transform)(struct weston_color_manager *cm,
struct weston_surface *surface,
struct weston_output *output,
struct weston_surface_color_transform *surf_xform);
/** Compute derived color properties for an output
*
* \param cm The color manager.
* \param output The output.
* \return A new color_outcome object on success, NULL on failure.
*
* The callee (color manager) must inspect the weston_output (color
* profile, EOTF mode, etc.) and create a fully populated
* weston_output_color_outcome object.
*/
struct weston_output_color_outcome *
(*create_output_color_outcome)(struct weston_color_manager *cm,
struct weston_output *output);
};
void
weston_color_profile_init(struct weston_color_profile *cprof,
struct weston_color_manager *cm);
struct weston_color_transform *
weston_color_transform_ref(struct weston_color_transform *xform);
void
weston_color_transform_unref(struct weston_color_transform *xform);
void
weston_color_transform_init(struct weston_color_transform *xform,
struct weston_color_manager *cm);
void
weston_surface_color_transform_copy(struct weston_surface_color_transform *dst,
const struct weston_surface_color_transform *src);
void
weston_surface_color_transform_fini(struct weston_surface_color_transform *surf_xform);
struct weston_paint_node;
void
weston_paint_node_ensure_color_transform(struct weston_paint_node *pnode);
struct weston_color_manager *
weston_color_manager_noop_create(struct weston_compositor *compositor);
/* DSO module entrypoint */
struct weston_color_manager *
weston_color_manager_create(struct weston_compositor *compositor);
const char *
weston_eotf_mode_to_str(enum weston_eotf_mode e);
char *
weston_eotf_mask_to_str(uint32_t eotf_mask);
void
weston_output_color_outcome_destroy(struct weston_output_color_outcome **pco);
#endif /* WESTON_COLOR_H */