summaryrefslogtreecommitdiff
path: root/libweston/color.h
blob: e0a40f5ecdd6e3788e151712a428874cec24a98e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/*
 * 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;

	/* Unique id to be used by the CM&HDR protocol extension. */
	uint32_t id;
};

/** 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,

	/** matrix */
	WESTON_COLOR_MAPPING_TYPE_MATRIX,
};

/**
 * 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;
};

/**
 * A 3x3 matrix and data is arranged as column major
 */
struct weston_color_mapping_matrix {
	float matrix[9];
};

/**
 * 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;
		struct weston_color_mapping_matrix mat;
	} 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;
	uint32_t id; /* For debug */

	/* 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 cm_image_desc_info;

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;

	/**
	 * Supported color features from Wayland CM&HDR protocol extension.
	 *
	 * If v (v being enum weston_color_feature v) is a supported color
	 * feature, the bit v of this will be set to 1.
	 */
	uint32_t supported_color_features;

	/**
	 * Supported rendering intents from Wayland CM&HDR protocol extension.
	 *
	 * If v (v being enum weston_render_intent v) is a supported rendering
	 * intent, the bit v of this will be set to 1.
	 */
	uint32_t supported_rendering_intents;

	/** 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);

	/** Gets a new reference to the stock sRGB color profile
	 *
	 * \param cm The color manager.
	 * \return A new reference to the stock sRGB profile, never returns NULL.
	 */
	struct weston_color_profile *
	(*ref_stock_sRGB_color_profile)(struct weston_color_manager *cm);

	/** 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);

	/** Send image description to clients.
	 *
	 * \param cm_image_desc_info The image description info object
	 * \param cprof_base The color profile that backs the image description
	 * \return True on success, false on failure
	 *
	 * This should be used only by the CM&HDR protocol extension
	 * implementation.
	 *
	 * The color manager implementing this function should use the helpers
	 * from color-management.c (weston_cm_send_primaries(), etc) to send the
	 * information to clients.
	 */
	bool
	(*send_image_desc_info)(struct cm_image_desc_info *cm_image_desc_info,
				struct weston_color_profile *cprof_base);

	/** 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);

char *
weston_color_transform_string(const struct weston_color_transform *xform);

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 */