gpu: Make color conversion extensible
Change the glsl convert_color function to proceed in stages: - first unpremultiply - then linearize - then transform linearly - then delinearize - then premultiply All the steps are only taken if needed.
This commit is contained in:
@@ -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,115 @@ 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;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
default:
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
default:
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
vec3
|
||||
convert_linear (vec3 color,
|
||||
uint from,
|
||||
uint to)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
uint
|
||||
linear_color_space (uint cs)
|
||||
{
|
||||
return GDK_COLOR_STATE_ID_SRGB_LINEAR;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user