mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-08 17:50:10 +00:00
Merge branch 'more-color-states' into 'main'
More color states See merge request GNOME/gtk!7445
This commit is contained in:
commit
926a651f12
@ -121,6 +121,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "offload", GDK_DEBUG_OFFLOAD, "Information about subsurfaces and graphics offload" },
|
||||
|
||||
{ "linear", GDK_DEBUG_LINEAR, "Enable linear rendering" },
|
||||
{ "hdr", GDK_DEBUG_HDR, "Force HDR rendering" },
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals" },
|
||||
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals" },
|
||||
{ "force-offload", GDK_DEBUG_FORCE_OFFLOAD, "Force graphics offload for all textures" },
|
||||
|
@ -82,6 +82,14 @@ void
|
||||
*
|
||||
* Returns the color state object representing the sRGB color space.
|
||||
*
|
||||
* This color state uses the primaries defined by BT.709-6 and the transfer function
|
||||
* defined by IEC 61966-2-1.
|
||||
*
|
||||
* It is equivalent to H.273 ColourPrimaries 1 with TransferCharacteristics 13 and MatrixCoefficients 0.
|
||||
*
|
||||
* See e.g. [the CSS Color Module](https://www.w3.org/TR/css-color-4/#predefined-sRGB)
|
||||
* for details about this colorstate.
|
||||
*
|
||||
* Returns: the color state object for sRGB
|
||||
*
|
||||
* Since: 4.16
|
||||
@ -97,6 +105,13 @@ gdk_color_state_get_srgb (void)
|
||||
*
|
||||
* Returns the color state object representing the linearized sRGB color space.
|
||||
*
|
||||
* This color state uses the primaries defined by BT.709-6 and a linear transfer function.
|
||||
*
|
||||
* It is equivalent to H.273 ColourPrimaries 1 with TransferCharacteristics 8 and MatrixCoefficients 0.
|
||||
*
|
||||
* See e.g. [the CSS Color Module](https://www.w3.org/TR/css-color-4/#predefined-sRGB-linear)
|
||||
* for details about this colorstate.
|
||||
*
|
||||
* Returns: the color state object for linearized sRGB
|
||||
*
|
||||
* Since: 4.16
|
||||
@ -107,6 +122,52 @@ gdk_color_state_get_srgb_linear (void)
|
||||
return GDK_COLOR_STATE_SRGB_LINEAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_state_get_rec2100_pq:
|
||||
*
|
||||
* Returns the color state object representing the rec2100-pq color space.
|
||||
*
|
||||
* This color state uses the primaries defined by BT.2020-2 and BT.2100-0 and the transfer
|
||||
* function defined by SMPTE ST 2084 and BT.2100-2.
|
||||
*
|
||||
* It is equivalent to H.273 ColourPrimaries code point 9 with TransferCharacteristics 16.
|
||||
*
|
||||
* See e.g. [the CSS HDR Module](https://drafts.csswg.org/css-color-hdr/#valdef-color-rec2100-pq)
|
||||
* for details about this colorstate.
|
||||
*
|
||||
* Returns: the color state object for rec2100-pq
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
GdkColorState *
|
||||
gdk_color_state_get_rec2100_pq (void)
|
||||
{
|
||||
return GDK_COLOR_STATE_REC2100_PQ;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_state_get_rec2100_linear:
|
||||
*
|
||||
* Returns the color state object representing the linear rec2100 color space.
|
||||
*
|
||||
* This color state uses the primaries defined by BT.2020-2 and BT.2100-0 and a linear
|
||||
* transfer function.
|
||||
*
|
||||
* It is equivalent to H.273 ColourPrimaries code point 9 with TransferCharacteristics 8.
|
||||
*
|
||||
* See e.g. [the CSS HDR Module](https://drafts.csswg.org/css-color-hdr/#valdef-color-rec2100-linear)
|
||||
* for details about this colorstate.
|
||||
*
|
||||
* Returns: the color state object for linearized rec2100
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
GdkColorState *
|
||||
gdk_color_state_get_rec2100_linear (void)
|
||||
{
|
||||
return GDK_COLOR_STATE_REC2100_LINEAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_state_equal:
|
||||
* @self: a `GdkColorState`
|
||||
@ -171,17 +232,30 @@ gdk_default_color_state_get_convert_to (GdkColorState *color_state,
|
||||
/* }}} */
|
||||
/* {{{ Conversion functions */
|
||||
|
||||
#define COORDINATE_TRANSFORM(name, tf) \
|
||||
#define TRANSFORM(name, eotf, matrix, oetf) \
|
||||
static void \
|
||||
name(GdkColorState *self, \
|
||||
float (*values)[4], \
|
||||
gsize n_values) \
|
||||
name (GdkColorState *self, \
|
||||
float (*values)[4], \
|
||||
gsize n_values) \
|
||||
{ \
|
||||
for (gsize i = 0; i < n_values; i++) \
|
||||
{ \
|
||||
values[i][0] = tf (values[i][0]); \
|
||||
values[i][1] = tf (values[i][1]); \
|
||||
values[i][2] = tf (values[i][2]); \
|
||||
values[i][0] = eotf (values[i][0]); \
|
||||
values[i][1] = eotf (values[i][1]); \
|
||||
values[i][2] = eotf (values[i][2]); \
|
||||
if ((float **)matrix != IDENTITY) \
|
||||
{ \
|
||||
float res[3]; \
|
||||
res[0] = matrix[0][0] * values[i][0] + matrix[0][1] * values[i][1] + matrix[0][2] * values[i][2]; \
|
||||
res[1] = matrix[1][0] * values[i][0] + matrix[1][1] * values[i][1] + matrix[1][2] * values[i][2]; \
|
||||
res[2] = matrix[2][0] * values[i][0] + matrix[2][1] * values[i][1] + matrix[2][2] * values[i][2]; \
|
||||
values[i][0] = res[0]; \
|
||||
values[i][1] = res[1]; \
|
||||
values[i][2] = res[2]; \
|
||||
} \
|
||||
values[i][0] = oetf (values[i][0]); \
|
||||
values[i][1] = oetf (values[i][1]); \
|
||||
values[i][2] = oetf (values[i][2]); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -203,8 +277,86 @@ srgb_eotf (float v)
|
||||
return v / 12.92f;
|
||||
}
|
||||
|
||||
COORDINATE_TRANSFORM(gdk_default_srgb_to_srgb_linear, srgb_eotf)
|
||||
COORDINATE_TRANSFORM(gdk_default_srgb_linear_to_srgb, srgb_oetf)
|
||||
static inline float
|
||||
pq_eotf (float v)
|
||||
{
|
||||
float ninv = (1 << 14) / 2610.0;
|
||||
float minv = (1 << 5) / 2523.0;
|
||||
float c1 = 3424.0 / (1 << 12);
|
||||
float c2 = 2413.0 / (1 << 7);
|
||||
float c3 = 2392.0 / (1 << 7);
|
||||
|
||||
float x = powf (MAX ((powf (v, minv) - c1), 0) / (c2 - (c3 * (powf (v, minv)))), ninv);
|
||||
|
||||
return x * 10000 / 203.0;
|
||||
}
|
||||
|
||||
static inline float
|
||||
pq_oetf (float v)
|
||||
{
|
||||
float x = v * 203.0 / 10000.0;
|
||||
float n = 2610.0 / (1 << 14);
|
||||
float m = 2523.0 / (1 << 5);
|
||||
float c1 = 3424.0 / (1 << 12);
|
||||
float c2 = 2413.0 / (1 << 7);
|
||||
float c3 = 2392.0 / (1 << 7);
|
||||
|
||||
return powf (((c1 + (c2 * powf (x, n))) / (1 + (c3 * powf (x, n)))), m);
|
||||
}
|
||||
|
||||
/* These matrices are derived by combining the standard abc_to_xyz onces:
|
||||
*
|
||||
* rec2020_to_srgb = srgb_to_xyz⁻¹ * rec2020_to_xyz
|
||||
* srgb_to_rec2020 = rec2020_to_xyz⁻¹ * srgb_to_xyz
|
||||
*
|
||||
* These values were used here:
|
||||
*
|
||||
* static const float srgb_to_xyz[3][3] = {
|
||||
* { 0.4125288, 0.3581642, 0.1774037 },
|
||||
* { 0.2127102, 0.7163284, 0.0709615 },
|
||||
* { 0.0193373, 0.1193881, 0.9343260 },
|
||||
* }
|
||||
*
|
||||
* static const float rec2020_to_xyz[3][3] = {
|
||||
* { 0.6369615, 0.1448079, 0.1663273 },
|
||||
* { 0.2627016, 0.6788934, 0.0584050 },
|
||||
* { 0.0000000, 0.0281098, 1.0449416 },
|
||||
* };
|
||||
*
|
||||
* See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
||||
* for how to derive the abc_to_xyz matrices from chromaticity coordinates.
|
||||
*/
|
||||
|
||||
static const float rec2020_to_srgb[3][3] = {
|
||||
{ 1.659944, -0.588220, -0.071724 },
|
||||
{ -0.124350, 1.132559, -0.008210 },
|
||||
{ -0.018466, -0.102459, 1.120924 },
|
||||
};
|
||||
|
||||
static const float srgb_to_rec2020[3][3] = {
|
||||
{ 0.627610, 0.329815, 0.042574 },
|
||||
{ 0.069029, 0.919817, 0.011154 },
|
||||
{ 0.016649, 0.089510, 0.893842 },
|
||||
};
|
||||
|
||||
#define IDENTITY ((float**)0)
|
||||
#define NONE(x) x
|
||||
|
||||
TRANSFORM(gdk_default_srgb_to_srgb_linear, srgb_eotf, IDENTITY, NONE);
|
||||
TRANSFORM(gdk_default_srgb_linear_to_srgb, NONE, IDENTITY, srgb_oetf)
|
||||
TRANSFORM(gdk_default_rec2100_pq_to_rec2100_linear, pq_eotf, IDENTITY, NONE)
|
||||
TRANSFORM(gdk_default_rec2100_linear_to_rec2100_pq, NONE, IDENTITY, pq_oetf)
|
||||
TRANSFORM(gdk_default_srgb_linear_to_rec2100_linear, NONE, srgb_to_rec2020, NONE)
|
||||
TRANSFORM(gdk_default_rec2100_linear_to_srgb_linear, NONE, rec2020_to_srgb, NONE)
|
||||
TRANSFORM(gdk_default_srgb_to_rec2100_linear, srgb_eotf, srgb_to_rec2020, NONE)
|
||||
TRANSFORM(gdk_default_rec2100_pq_to_srgb_linear, pq_eotf, rec2020_to_srgb, NONE)
|
||||
TRANSFORM(gdk_default_srgb_linear_to_rec2100_pq, NONE, srgb_to_rec2020, pq_oetf)
|
||||
TRANSFORM(gdk_default_rec2100_linear_to_srgb, NONE, rec2020_to_srgb, srgb_oetf)
|
||||
TRANSFORM(gdk_default_srgb_to_rec2100_pq, srgb_eotf, srgb_to_rec2020, pq_oetf)
|
||||
TRANSFORM(gdk_default_rec2100_pq_to_srgb, pq_eotf, rec2020_to_srgb, srgb_oetf)
|
||||
|
||||
#undef IDENTITY
|
||||
#undef NONE
|
||||
|
||||
/* }}} */
|
||||
|
||||
@ -229,6 +381,8 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
.no_srgb = GDK_COLOR_STATE_SRGB_LINEAR,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_srgb_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_to_rec2100_linear,
|
||||
},
|
||||
},
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = {
|
||||
@ -242,6 +396,38 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
.no_srgb = NULL,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_srgb_linear_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_linear_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_linear_to_rec2100_linear,
|
||||
},
|
||||
},
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = {
|
||||
.parent = {
|
||||
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
|
||||
.ref_count = 0,
|
||||
.depth = GDK_MEMORY_FLOAT16,
|
||||
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
|
||||
},
|
||||
.name = "rec2100-pq",
|
||||
.no_srgb = NULL,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_rec2100_pq_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_pq_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_rec2100_pq_to_rec2100_linear,
|
||||
},
|
||||
},
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = {
|
||||
.parent = {
|
||||
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
|
||||
.ref_count = 0,
|
||||
.depth = GDK_MEMORY_FLOAT16,
|
||||
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
|
||||
},
|
||||
.name = "rec2100-linear",
|
||||
.no_srgb = NULL,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_rec2100_linear_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_linear_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_rec2100_linear_to_rec2100_pq,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -43,6 +43,12 @@ GdkColorState * gdk_color_state_get_srgb (void);
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
GdkColorState * gdk_color_state_get_srgb_linear (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
GdkColorState * gdk_color_state_get_rec2100_pq (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
GdkColorState * gdk_color_state_get_rec2100_linear (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
gboolean gdk_color_state_equal (GdkColorState *self,
|
||||
GdkColorState *other);
|
||||
|
@ -10,6 +10,8 @@ typedef enum
|
||||
{
|
||||
GDK_COLOR_STATE_ID_SRGB,
|
||||
GDK_COLOR_STATE_ID_SRGB_LINEAR,
|
||||
GDK_COLOR_STATE_ID_REC2100_PQ,
|
||||
GDK_COLOR_STATE_ID_REC2100_LINEAR,
|
||||
|
||||
GDK_COLOR_STATE_N_IDS
|
||||
} GdkColorStateId;
|
||||
@ -53,8 +55,10 @@ struct _GdkDefaultColorState
|
||||
|
||||
extern GdkDefaultColorState gdk_default_color_states[GDK_COLOR_STATE_N_IDS];
|
||||
|
||||
#define GDK_COLOR_STATE_SRGB ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB])
|
||||
#define GDK_COLOR_STATE_SRGB_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB_LINEAR])
|
||||
#define GDK_COLOR_STATE_SRGB ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB])
|
||||
#define GDK_COLOR_STATE_SRGB_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB_LINEAR])
|
||||
#define GDK_COLOR_STATE_REC2100_PQ ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_PQ])
|
||||
#define GDK_COLOR_STATE_REC2100_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_LINEAR])
|
||||
|
||||
#define GDK_IS_DEFAULT_COLOR_STATE(c) ((GdkDefaultColorState *) (c) >= &gdk_default_color_states[0] && \
|
||||
(GdkDefaultColorState *) (c) < &gdk_default_color_states[GDK_COLOR_STATE_N_IDS])
|
||||
@ -66,6 +70,9 @@ GdkColorState * gdk_color_state_get_no_srgb_tf (GdkColorState
|
||||
static inline GdkColorState *
|
||||
gdk_color_state_get_rendering_color_state (GdkColorState *self)
|
||||
{
|
||||
if (GDK_DEBUG_CHECK (HDR))
|
||||
self = GDK_COLOR_STATE_REC2100_PQ;
|
||||
|
||||
if (!GDK_DEBUG_CHECK (LINEAR))
|
||||
return self;
|
||||
|
||||
|
@ -41,19 +41,20 @@ typedef enum {
|
||||
|
||||
/* flags below are influencing behavior */
|
||||
GDK_DEBUG_LINEAR = 1 << 13,
|
||||
GDK_DEBUG_PORTALS = 1 << 14,
|
||||
GDK_DEBUG_NO_PORTALS = 1 << 15,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 16,
|
||||
GDK_DEBUG_GL_NO_FRACTIONAL= 1 << 17,
|
||||
GDK_DEBUG_FORCE_OFFLOAD = 1 << 18,
|
||||
GDK_DEBUG_GL_DISABLE_GL = 1 << 19,
|
||||
GDK_DEBUG_GL_DISABLE_GLES = 1 << 20,
|
||||
GDK_DEBUG_GL_PREFER_GL = 1 << 21,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 22,
|
||||
GDK_DEBUG_GL_EGL = 1 << 23,
|
||||
GDK_DEBUG_GL_GLX = 1 << 24,
|
||||
GDK_DEBUG_GL_WGL = 1 << 25,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 26,
|
||||
GDK_DEBUG_HDR = 1 << 14,
|
||||
GDK_DEBUG_PORTALS = 1 << 15,
|
||||
GDK_DEBUG_NO_PORTALS = 1 << 16,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 17,
|
||||
GDK_DEBUG_GL_NO_FRACTIONAL= 1 << 18,
|
||||
GDK_DEBUG_FORCE_OFFLOAD = 1 << 19,
|
||||
GDK_DEBUG_GL_DISABLE_GL = 1 << 20,
|
||||
GDK_DEBUG_GL_DISABLE_GLES = 1 << 21,
|
||||
GDK_DEBUG_GL_PREFER_GL = 1 << 22,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 23,
|
||||
GDK_DEBUG_GL_EGL = 1 << 24,
|
||||
GDK_DEBUG_GL_GLX = 1 << 25,
|
||||
GDK_DEBUG_GL_WGL = 1 << 26,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 27,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 28,
|
||||
GDK_DEBUG_HIGH_DEPTH = 1 << 29,
|
||||
GDK_DEBUG_NO_VSYNC = 1 << 30,
|
||||
|
@ -598,7 +598,8 @@ gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame,
|
||||
|
||||
image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
|
||||
FALSE,
|
||||
gsk_render_node_get_preferred_depth (node),
|
||||
gdk_memory_depth_merge (gdk_color_state_get_depth (ccs),
|
||||
gsk_render_node_get_preferred_depth (node)),
|
||||
area.width, area.height);
|
||||
if (image == NULL)
|
||||
return NULL;
|
||||
@ -1065,7 +1066,8 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel
|
||||
mask_image = gsk_gpu_node_processor_init_draw (&other,
|
||||
self->frame,
|
||||
self->ccs,
|
||||
gsk_render_node_get_preferred_depth (node),
|
||||
gdk_memory_depth_merge (gdk_color_state_get_depth (self->ccs),
|
||||
gsk_render_node_get_preferred_depth (node)),
|
||||
&self->scale,
|
||||
&clip_bounds);
|
||||
gsk_gpu_node_processor_sync_globals (&other, 0);
|
||||
@ -2277,7 +2279,8 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
|
||||
image = gsk_gpu_node_processor_init_draw (&other,
|
||||
self->frame,
|
||||
self->ccs,
|
||||
gsk_render_node_get_preferred_depth (node),
|
||||
gdk_memory_depth_merge (gdk_color_state_get_depth (self->ccs),
|
||||
gsk_render_node_get_preferred_depth (node)),
|
||||
&self->scale,
|
||||
&bounds);
|
||||
|
||||
|
@ -24,24 +24,6 @@ color_unpremultiply (vec4 color)
|
||||
return color.a > 0.0 ? color / vec4 (color.aaa, 1.0) : color;
|
||||
}
|
||||
|
||||
float
|
||||
srgb_eotf (float v)
|
||||
{
|
||||
if (v >= 0.04045)
|
||||
return pow (((v + 0.055) / (1.0 + 0.055)), 2.4);
|
||||
else
|
||||
return v / 12.92;
|
||||
}
|
||||
|
||||
float
|
||||
srgb_oetf (float v)
|
||||
{
|
||||
if (v > 0.0031308)
|
||||
return 1.055 * pow (v, 1.0 / 2.4) - 0.055;
|
||||
else
|
||||
return 12.92 * v;
|
||||
}
|
||||
|
||||
vec4
|
||||
alt_color_alpha (vec4 color,
|
||||
float alpha)
|
||||
@ -62,82 +44,186 @@ output_color_alpha (vec4 color,
|
||||
return vec4 (color.rgb, color.a * alpha);
|
||||
}
|
||||
|
||||
vec4
|
||||
alt_color_from_output (vec4 color)
|
||||
float
|
||||
srgb_eotf (float v)
|
||||
{
|
||||
if (OUTPUT_COLOR_SPACE == ALT_COLOR_SPACE)
|
||||
{
|
||||
if (OUTPUT_PREMULTIPLIED && !ALT_PREMULTIPLIED)
|
||||
return color_unpremultiply (color);
|
||||
else if (!OUTPUT_PREMULTIPLIED && ALT_PREMULTIPLIED)
|
||||
return color_premultiply (color);
|
||||
else
|
||||
return color;
|
||||
}
|
||||
if (v >= 0.04045)
|
||||
return pow (((v + 0.055) / (1.0 + 0.055)), 2.4);
|
||||
else
|
||||
return v / 12.92;
|
||||
}
|
||||
|
||||
if (OUTPUT_PREMULTIPLIED)
|
||||
float
|
||||
srgb_oetf (float v)
|
||||
{
|
||||
if (v > 0.0031308)
|
||||
return 1.055 * pow (v, 1.0 / 2.4) - 0.055;
|
||||
else
|
||||
return 12.92 * v;
|
||||
}
|
||||
|
||||
float
|
||||
pq_eotf (float v)
|
||||
{
|
||||
const float ninv = 16384.0 / 2610.0;
|
||||
const float minv = 32.0 / 2523.0;
|
||||
const float c1 = 3424.0 / 4096.0;
|
||||
const float c2 = 2413.0 / 128.0;
|
||||
const float c3 = 2392.0 / 128.0;
|
||||
|
||||
float x = pow (max ((pow (v, minv) - c1), 0.0) / (c2 - (c3 * (pow (v, minv)))), ninv);
|
||||
|
||||
return x * 10000.0 / 203.0;
|
||||
}
|
||||
|
||||
float
|
||||
pq_oetf (float v)
|
||||
{
|
||||
const float n = 2610.0 / 16384.0;
|
||||
const float m = 2523.0 / 32.0;
|
||||
const float c1 = 3424.0 / 4096.0;
|
||||
const float c2 = 2413.0 / 128.0;
|
||||
const float c3 = 2392.0 / 128.0;
|
||||
|
||||
float x = v * 203.0 / 10000.0;
|
||||
|
||||
return pow (((c1 + (c2 * pow (x, n))) / (1.0 + (c3 * pow (x, n)))), m);
|
||||
}
|
||||
|
||||
vec3
|
||||
apply_eotf (vec3 color,
|
||||
uint cs)
|
||||
{
|
||||
switch (cs)
|
||||
{
|
||||
case GDK_COLOR_STATE_ID_SRGB:
|
||||
return vec3 (srgb_eotf (color.r),
|
||||
srgb_eotf (color.g),
|
||||
srgb_eotf (color.b));
|
||||
|
||||
case GDK_COLOR_STATE_ID_REC2100_PQ:
|
||||
return vec3 (pq_eotf (color.r),
|
||||
pq_eotf (color.g),
|
||||
pq_eotf (color.b));
|
||||
|
||||
case GDK_COLOR_STATE_ID_SRGB_LINEAR:
|
||||
case GDK_COLOR_STATE_ID_REC2100_LINEAR:
|
||||
return color;
|
||||
|
||||
default:
|
||||
return vec3(1.0, 0.0, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
vec3
|
||||
apply_oetf (vec3 color,
|
||||
uint cs)
|
||||
{
|
||||
switch (cs)
|
||||
{
|
||||
case GDK_COLOR_STATE_ID_SRGB:
|
||||
return vec3 (srgb_oetf (color.r),
|
||||
srgb_oetf (color.g),
|
||||
srgb_oetf (color.b));
|
||||
|
||||
case GDK_COLOR_STATE_ID_REC2100_PQ:
|
||||
return vec3 (pq_oetf (color.r),
|
||||
pq_oetf (color.g),
|
||||
pq_oetf (color.b));
|
||||
|
||||
case GDK_COLOR_STATE_ID_SRGB_LINEAR:
|
||||
case GDK_COLOR_STATE_ID_REC2100_LINEAR:
|
||||
return color;
|
||||
|
||||
default:
|
||||
return vec3(0.0, 1.0, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that these matrices are transposed from the C version */
|
||||
const mat3 srgb_from_rec2020 = mat3(
|
||||
1.659944, -0.124350, -0.018466,
|
||||
-0.588220, 1.132559, -0.102459,
|
||||
-0.071724, -0.008210, 1.120924
|
||||
);
|
||||
|
||||
const mat3 rec2020_from_srgb = mat3(
|
||||
0.627610, 0.069029, 0.016649,
|
||||
0.329815, 0.919817, 0.089510,
|
||||
0.042574, 0.011154, 0.893842
|
||||
);
|
||||
|
||||
vec3
|
||||
convert_linear (vec3 color,
|
||||
uint from,
|
||||
uint to)
|
||||
{
|
||||
if (to == GDK_COLOR_STATE_ID_REC2100_LINEAR && from == GDK_COLOR_STATE_ID_SRGB_LINEAR)
|
||||
return rec2020_from_srgb * color;
|
||||
else if (to == GDK_COLOR_STATE_ID_SRGB_LINEAR && from == GDK_COLOR_STATE_ID_REC2100_LINEAR)
|
||||
return srgb_from_rec2020 * color;
|
||||
else
|
||||
return vec3(0.8, 1.0, 0.0);
|
||||
}
|
||||
|
||||
uint
|
||||
linear_color_space (uint cs)
|
||||
{
|
||||
switch (cs)
|
||||
{
|
||||
case GDK_COLOR_STATE_ID_SRGB: return GDK_COLOR_STATE_ID_SRGB_LINEAR;
|
||||
case GDK_COLOR_STATE_ID_SRGB_LINEAR: return GDK_COLOR_STATE_ID_SRGB_LINEAR;
|
||||
case GDK_COLOR_STATE_ID_REC2100_PQ: return GDK_COLOR_STATE_ID_REC2100_LINEAR;
|
||||
case GDK_COLOR_STATE_ID_REC2100_LINEAR: return GDK_COLOR_STATE_ID_REC2100_LINEAR;
|
||||
default: return 0u;
|
||||
};
|
||||
}
|
||||
|
||||
vec4
|
||||
convert_color (vec4 color,
|
||||
uint from,
|
||||
bool from_premul,
|
||||
uint to,
|
||||
bool to_premul)
|
||||
{
|
||||
if (from_premul && (!to_premul || from != to))
|
||||
color = color_unpremultiply (color);
|
||||
|
||||
if (OUTPUT_COLOR_SPACE == GDK_COLOR_STATE_ID_SRGB &&
|
||||
ALT_COLOR_SPACE == GDK_COLOR_STATE_ID_SRGB_LINEAR)
|
||||
if (from != to)
|
||||
{
|
||||
color = vec4 (srgb_eotf (color.r),
|
||||
srgb_eotf (color.g),
|
||||
srgb_eotf (color.b),
|
||||
color.a);
|
||||
}
|
||||
else if (OUTPUT_COLOR_SPACE == GDK_COLOR_STATE_ID_SRGB_LINEAR &&
|
||||
ALT_COLOR_SPACE == GDK_COLOR_STATE_ID_SRGB)
|
||||
{
|
||||
color = vec4 (srgb_oetf (color.r),
|
||||
srgb_oetf (color.g),
|
||||
srgb_oetf (color.b),
|
||||
color.a);
|
||||
uint from_linear = linear_color_space (from);
|
||||
uint to_linear = linear_color_space (to);
|
||||
|
||||
if (from_linear != from)
|
||||
color.rgb = apply_eotf (color.rgb, from);
|
||||
|
||||
if (from_linear != to_linear)
|
||||
color.rgb = convert_linear (color.rgb, from_linear, to_linear);
|
||||
|
||||
if (to_linear != to)
|
||||
color.rgb = apply_oetf (color.rgb, to);
|
||||
}
|
||||
|
||||
if (ALT_PREMULTIPLIED)
|
||||
if (to_premul && (!from_premul || from != to))
|
||||
color = color_premultiply (color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4
|
||||
alt_color_from_output (vec4 color)
|
||||
{
|
||||
return convert_color (color,
|
||||
OUTPUT_COLOR_SPACE, OUTPUT_PREMULTIPLIED,
|
||||
ALT_COLOR_SPACE, ALT_PREMULTIPLIED);
|
||||
}
|
||||
|
||||
vec4
|
||||
output_color_from_alt (vec4 color)
|
||||
{
|
||||
if (OUTPUT_COLOR_SPACE == ALT_COLOR_SPACE)
|
||||
{
|
||||
if (ALT_PREMULTIPLIED && !OUTPUT_PREMULTIPLIED)
|
||||
return color_unpremultiply (color);
|
||||
else if (!ALT_PREMULTIPLIED && OUTPUT_PREMULTIPLIED)
|
||||
return color_premultiply (color);
|
||||
else
|
||||
return color;
|
||||
}
|
||||
|
||||
if (ALT_PREMULTIPLIED)
|
||||
color = color_unpremultiply (color);
|
||||
|
||||
if (ALT_COLOR_SPACE == GDK_COLOR_STATE_ID_SRGB &&
|
||||
OUTPUT_COLOR_SPACE == GDK_COLOR_STATE_ID_SRGB_LINEAR)
|
||||
{
|
||||
color = vec4 (srgb_eotf (color.r),
|
||||
srgb_eotf (color.g),
|
||||
srgb_eotf (color.b),
|
||||
color.a);
|
||||
}
|
||||
else if (ALT_COLOR_SPACE == GDK_COLOR_STATE_ID_SRGB_LINEAR &&
|
||||
OUTPUT_COLOR_SPACE == GDK_COLOR_STATE_ID_SRGB)
|
||||
{
|
||||
color = vec4 (srgb_oetf (color.r),
|
||||
srgb_oetf (color.g),
|
||||
srgb_oetf (color.b),
|
||||
color.a);
|
||||
}
|
||||
|
||||
if (OUTPUT_PREMULTIPLIED)
|
||||
color = color_premultiply (color);
|
||||
|
||||
return color;
|
||||
return convert_color (color,
|
||||
ALT_COLOR_SPACE, ALT_PREMULTIPLIED,
|
||||
OUTPUT_COLOR_SPACE, OUTPUT_PREMULTIPLIED);
|
||||
}
|
||||
|
||||
float
|
||||
|
@ -54,6 +54,8 @@
|
||||
|
||||
#define GDK_COLOR_STATE_ID_SRGB 0u
|
||||
#define GDK_COLOR_STATE_ID_SRGB_LINEAR 1u
|
||||
#define GDK_COLOR_STATE_ID_REC2100_PQ 2u
|
||||
#define GDK_COLOR_STATE_ID_REC2100_LINEAR 3u
|
||||
|
||||
#define TOP 0u
|
||||
#define RIGHT 1u
|
||||
|
Loading…
Reference in New Issue
Block a user