gpu: Add color-matrix handling to pattern shader

This commit is contained in:
Benjamin Otte
2023-09-02 11:52:33 +02:00
parent 9224efd95e
commit 3809e6efb9
6 changed files with 88 additions and 3 deletions

View File

@@ -83,6 +83,28 @@ gsk_gpu_buffer_writer_append_uint (GskGpuBufferWriter *self,
gsk_gpu_buffer_writer_append (self, G_ALIGNOF (guint32), (guchar *) &u, sizeof (guint32));
}
void
gsk_gpu_buffer_writer_append_matrix (GskGpuBufferWriter *self,
const graphene_matrix_t *matrix)
{
float f[16];
graphene_matrix_to_float (matrix, f);
gsk_gpu_buffer_writer_append (self, G_ALIGNOF (float), (guchar *) f, sizeof (f));
}
void
gsk_gpu_buffer_writer_append_vec4 (GskGpuBufferWriter *self,
const graphene_vec4_t *vec4)
{
float f[4];
graphene_vec4_to_float (vec4, f);
gsk_gpu_buffer_writer_append (self, G_ALIGNOF (float), (guchar *) f, sizeof (f));
}
void
gsk_gpu_buffer_writer_append_rect (GskGpuBufferWriter *self,
const graphene_rect_t *rect,

View File

@@ -40,6 +40,10 @@ void gsk_gpu_buffer_writer_append_int (GskGpuB
gint32 i);
void gsk_gpu_buffer_writer_append_uint (GskGpuBufferWriter *self,
guint32 u);
void gsk_gpu_buffer_writer_append_matrix (GskGpuBufferWriter *self,
const graphene_matrix_t *matrix);
void gsk_gpu_buffer_writer_append_vec4 (GskGpuBufferWriter *self,
const graphene_vec4_t *vec4);
void gsk_gpu_buffer_writer_append_rect (GskGpuBufferWriter *self,
const graphene_rect_t *rect,
const graphene_point_t *offset);

View File

@@ -795,6 +795,29 @@ gsk_gpu_node_processor_create_opacity_pattern (GskGpuNodeProcessor *self,
return TRUE;
}
static gboolean
gsk_gpu_node_processor_create_color_matrix_pattern (GskGpuNodeProcessor *self,
GskGpuBufferWriter *writer,
GskRenderNode *node,
GskGpuShaderImage *images,
gsize n_images,
gsize *out_n_images)
{
if (!gsk_gpu_node_processor_create_node_pattern (self,
writer,
gsk_color_matrix_node_get_child (node),
images,
n_images,
out_n_images))
return FALSE;
gsk_gpu_buffer_writer_append_uint (writer, GSK_GPU_PATTERN_COLOR_MATRIX);
gsk_gpu_buffer_writer_append_matrix (writer, gsk_color_matrix_node_get_color_matrix (node));
gsk_gpu_buffer_writer_append_vec4 (writer, gsk_color_matrix_node_get_color_offset (node));
return TRUE;
}
static void
gsk_gpu_node_processor_add_container_node (GskGpuNodeProcessor *self,
GskRenderNode *node)
@@ -892,8 +915,8 @@ static const struct
},
[GSK_COLOR_MATRIX_NODE] = {
0,
NULL,
NULL,
gsk_gpu_node_processor_add_node_as_pattern,
gsk_gpu_node_processor_create_color_matrix_pattern
},
[GSK_REPEAT_NODE] = {
0,

View File

@@ -32,5 +32,6 @@ typedef enum {
GSK_GPU_PATTERN_COLOR,
GSK_GPU_PATTERN_OPACITY,
GSK_GPU_PATTERN_TEXTURE,
GSK_GPU_PATTERN_COLOR_MATRIX,
} GskGpuPatternType;

View File

@@ -9,5 +9,6 @@
#define GSK_GPU_PATTERN_COLOR 1u
#define GSK_GPU_PATTERN_OPACITY 2u
#define GSK_GPU_PATTERN_TEXTURE 3u
#define GSK_GPU_PATTERN_COLOR_MATRIX 4u
#endif

View File

@@ -27,6 +27,21 @@ read_vec4 (inout uint reader)
return vec4 (read_float (reader), read_float (reader), read_float (reader), read_float (reader));
}
mat4
read_mat4 (inout uint reader)
{
mat4 result = mat4 (gsk_get_float (reader + 0), gsk_get_float (reader + 1),
gsk_get_float (reader + 2), gsk_get_float (reader + 3),
gsk_get_float (reader + 4), gsk_get_float (reader + 5),
gsk_get_float (reader + 6), gsk_get_float (reader + 7),
gsk_get_float (reader + 8), gsk_get_float (reader + 9),
gsk_get_float (reader + 10), gsk_get_float (reader + 11),
gsk_get_float (reader + 12), gsk_get_float (reader + 13),
gsk_get_float (reader + 14), gsk_get_float (reader + 15));
reader += 16;
return result;
}
void
opacity_pattern (inout uint reader,
inout vec4 color,
@@ -37,6 +52,22 @@ opacity_pattern (inout uint reader,
color *= opacity;
}
void
color_matrix_pattern (inout uint reader,
inout vec4 color,
vec2 pos)
{
mat4 matrix = read_mat4 (reader);
vec4 offset = read_vec4 (reader);
color = color_unpremultiply (color);
color = matrix * color + offset;
color = clamp(color, 0.0, 1.0);
color = color_premultiply (color);
}
vec4
texture_pattern (inout uint reader,
vec2 pos)
@@ -44,7 +75,7 @@ texture_pattern (inout uint reader,
uint tex_id = read_uint (reader);
vec4 tex_rect = read_vec4 (reader);
return texture (gsk_get_texture (tex_id), (pos - tex_rect.xy) / tex_rect.zw);
return texture (gsk_get_texture (tex_id), (pos - push.scale * tex_rect.xy) / (push.scale * tex_rect.zw));
}
vec4
@@ -75,6 +106,9 @@ pattern (uint reader,
case GSK_GPU_PATTERN_TEXTURE:
color = texture_pattern (reader, pos);
break;
case GSK_GPU_PATTERN_COLOR_MATRIX:
color_matrix_pattern (reader, color, pos);
break;
case GSK_GPU_PATTERN_OPACITY:
opacity_pattern (reader, color, pos);
break;