gpu: Add a color convert shader
This shader converts between two color states, by using the same functions that we use on the cpu. The conversion to perform is passed as an integer encoding the pair of color states. For now, the only possible color states are srgb and srgb-linear.
This commit is contained in:
86
gsk/gpu/gskgpucolorconvertop.c
Normal file
86
gsk/gpu/gskgpucolorconvertop.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskgpucolorconvertopprivate.h"
|
||||
|
||||
#include "gskgpuframeprivate.h"
|
||||
#include "gskgpuprintprivate.h"
|
||||
#include "gskrectprivate.h"
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
|
||||
#include "gpu/shaders/gskgpucolorconvertinstance.h"
|
||||
|
||||
typedef struct _GskGpuColorConvertOp GskGpuColorConvertOp;
|
||||
|
||||
struct _GskGpuColorConvertOp
|
||||
{
|
||||
GskGpuShaderOp op;
|
||||
};
|
||||
|
||||
static guint
|
||||
gsk_gpu_color_conversion (GdkColorState *from,
|
||||
GdkColorState *to)
|
||||
{
|
||||
if (from == to)
|
||||
return 0;
|
||||
|
||||
return GDK_DEFAULT_COLOR_STATE_ID (from) | (GDK_DEFAULT_COLOR_STATE_ID (to) << 16);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_color_convert_op_print_instance (GskGpuShaderOp *shader,
|
||||
gpointer instance_,
|
||||
GString *string)
|
||||
{
|
||||
GskGpuColorconvertInstance *instance = (GskGpuColorconvertInstance *) instance_;
|
||||
|
||||
gsk_gpu_print_rect (string, instance->rect);
|
||||
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
|
||||
gsk_gpu_print_color_conversion (string, shader->variation);
|
||||
}
|
||||
|
||||
static const GskGpuShaderOpClass GSK_GPU_COLOR_CONVERT_OP_CLASS = {
|
||||
{
|
||||
GSK_GPU_OP_SIZE (GskGpuColorConvertOp),
|
||||
GSK_GPU_STAGE_SHADER,
|
||||
gsk_gpu_shader_op_finish,
|
||||
gsk_gpu_shader_op_print,
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
gsk_gpu_shader_op_vk_command,
|
||||
#endif
|
||||
gsk_gpu_shader_op_gl_command
|
||||
},
|
||||
"gskgpucolorconvert",
|
||||
sizeof (GskGpuColorconvertInstance),
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
&gsk_gpu_colorconvert_info,
|
||||
#endif
|
||||
gsk_gpu_color_convert_op_print_instance,
|
||||
gsk_gpu_colorconvert_setup_attrib_locations,
|
||||
gsk_gpu_colorconvert_setup_vao
|
||||
};
|
||||
|
||||
void
|
||||
gsk_gpu_color_convert_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GdkColorState *from,
|
||||
GdkColorState *to,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect)
|
||||
{
|
||||
GskGpuColorconvertInstance *instance;
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_COLOR_CONVERT_OP_CLASS,
|
||||
gsk_gpu_color_conversion (from, to),
|
||||
clip,
|
||||
desc,
|
||||
&instance);
|
||||
|
||||
gsk_gpu_rect_to_float (rect, offset, instance->rect);
|
||||
gsk_gpu_rect_to_float (tex_rect, offset, instance->tex_rect);
|
||||
instance->tex_id = descriptor;
|
||||
}
|
||||
|
||||
21
gsk/gpu/gskgpucolorconvertopprivate.h
Normal file
21
gsk/gpu/gskgpucolorconvertopprivate.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskgpushaderopprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_color_convert_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GdkColorState *from,
|
||||
GdkColorState *to,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "gskgpuprintprivate.h"
|
||||
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
#include "gskgpudescriptorsprivate.h"
|
||||
#include "gskgpuimageprivate.h"
|
||||
|
||||
@@ -155,3 +157,11 @@ gsk_gpu_print_image_descriptor (GString *string,
|
||||
gsk_gpu_print_image (string, gsk_gpu_descriptors_get_image (desc, id));
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_print_color_conversion (GString *string,
|
||||
guint conversion)
|
||||
{
|
||||
g_string_append_printf (string, "%s->%s ",
|
||||
gdk_color_state_get_name_from_id (conversion & 0xffff),
|
||||
gdk_color_state_get_name_from_id (conversion >> 16));
|
||||
}
|
||||
|
||||
@@ -35,3 +35,5 @@ void gsk_gpu_print_image (GString
|
||||
void gsk_gpu_print_image_descriptor (GString *string,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor);
|
||||
void gsk_gpu_print_color_conversion (GString *string,
|
||||
guint conversion);
|
||||
|
||||
@@ -19,4 +19,4 @@ luminance (vec3 color)
|
||||
return dot (vec3 (0.2126, 0.7152, 0.0722), color);
|
||||
}
|
||||
|
||||
#endif /* _COLOR_ */
|
||||
#endif
|
||||
|
||||
116
gsk/gpu/shaders/gskgpucolorconvert.glsl
Normal file
116
gsk/gpu/shaders/gskgpucolorconvert.glsl
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "common.glsl"
|
||||
|
||||
PASS(0) vec2 _pos;
|
||||
PASS_FLAT(1) Rect _rect;
|
||||
PASS(2) vec2 _tex_coord;
|
||||
PASS_FLAT(3) uint _tex_id;
|
||||
|
||||
#ifdef GSK_VERTEX_SHADER
|
||||
|
||||
IN(0) vec4 in_rect;
|
||||
IN(1) vec4 in_tex_rect;
|
||||
IN(2) uint in_tex_id;
|
||||
|
||||
void
|
||||
run (out vec2 pos)
|
||||
{
|
||||
Rect r = rect_from_gsk (in_rect);
|
||||
|
||||
pos = rect_get_position (r);
|
||||
|
||||
_pos = pos;
|
||||
_rect = r;
|
||||
_tex_coord = rect_get_coord (rect_from_gsk (in_tex_rect), pos);
|
||||
_tex_id = in_tex_id;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef GSK_FRAGMENT_SHADER
|
||||
|
||||
float
|
||||
srgb_transfer_function (float v)
|
||||
{
|
||||
if (v >= 0.04045)
|
||||
return pow (((v + 0.055)/(1.0 + 0.055)), 2.4);
|
||||
else
|
||||
return v / 12.92;
|
||||
}
|
||||
|
||||
float
|
||||
srgb_inverse_transfer_function (float v)
|
||||
{
|
||||
if (v > 0.0031308)
|
||||
return 1.055 * pow (v, 1.0/2.4) - 0.055;
|
||||
else
|
||||
return 12.92 * v;
|
||||
}
|
||||
|
||||
vec4
|
||||
srgb_to_linear_srgb (vec4 color)
|
||||
{
|
||||
return vec4 (srgb_transfer_function (color.r),
|
||||
srgb_transfer_function (color.g),
|
||||
srgb_transfer_function (color.b),
|
||||
color.a);
|
||||
}
|
||||
|
||||
vec4
|
||||
linear_srgb_to_srgb (vec4 color)
|
||||
{
|
||||
return vec4 (srgb_inverse_transfer_function (color.r),
|
||||
srgb_inverse_transfer_function (color.g),
|
||||
srgb_inverse_transfer_function (color.b),
|
||||
color.a);
|
||||
}
|
||||
|
||||
#define RGB 0u
|
||||
#define LINRGB 1u
|
||||
|
||||
#define pair(u,v) ((u)|((v) << 16))
|
||||
#define first(p) ((p) & 0xffffu)
|
||||
#define second(p) ((p) >> 16)
|
||||
|
||||
bool
|
||||
do_conversion (in vec4 color, in uint f, out vec4 result)
|
||||
{
|
||||
switch (f)
|
||||
{
|
||||
case pair (RGB, LINRGB): result = srgb_to_linear_srgb (color); break;
|
||||
case pair (LINRGB, RGB): result = linear_srgb_to_srgb (color); break;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
vec4
|
||||
color_convert (in vec4 color, in uint f)
|
||||
{
|
||||
vec4 result;
|
||||
|
||||
if (f == 0u)
|
||||
return color;
|
||||
|
||||
do_conversion (color, f, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
run (out vec4 color,
|
||||
out vec2 position)
|
||||
{
|
||||
vec4 pixel = gsk_texture (_tex_id, _tex_coord);
|
||||
|
||||
pixel = color_unpremultiply (pixel);
|
||||
pixel = color_convert (pixel, GSK_VARIATION);
|
||||
|
||||
color = color_premultiply (pixel) * rect_coverage (_rect, _pos);
|
||||
position = _pos;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -18,6 +18,7 @@ gsk_private_gpu_shaders = files([
|
||||
'gskgpuborder.glsl',
|
||||
'gskgpuboxshadow.glsl',
|
||||
'gskgpucolor.glsl',
|
||||
'gskgpucolorconvert.glsl',
|
||||
'gskgpucolorize.glsl',
|
||||
'gskgpucolormatrix.glsl',
|
||||
'gskgpuconicgradient.glsl',
|
||||
|
||||
@@ -105,6 +105,7 @@ gsk_private_sources = files([
|
||||
'gpu/gskgpushaderop.c',
|
||||
'gpu/gskgpuscissorop.c',
|
||||
'gpu/gskgpustraightalphaop.c',
|
||||
'gpu/gskgpucolorconvertop.c',
|
||||
'gpu/gskgputextureop.c',
|
||||
'gpu/gskgpuuberop.c',
|
||||
'gpu/gskgpuuploadop.c',
|
||||
|
||||
Reference in New Issue
Block a user