gpu: Add support for mask patterns

This commit is contained in:
Benjamin Otte 2023-09-20 02:49:16 +02:00
parent e01311a565
commit d47c8613b0
5 changed files with 125 additions and 2 deletions

View File

@ -1047,6 +1047,67 @@ gsk_gpu_node_processor_create_cross_fade_pattern (GskGpuPatternWriter *self,
return TRUE; return TRUE;
} }
static gboolean
gsk_gpu_node_processor_create_mask_pattern (GskGpuPatternWriter *self,
GskRenderNode *node)
{
GskRenderNode *source_child, *mask_child;
source_child = gsk_mask_node_get_source (node);
mask_child = gsk_mask_node_get_mask (node);
if (!gsk_gpu_node_processor_create_node_pattern (self, source_child))
return FALSE;
if (!gsk_rect_contains_rect (&source_child->bounds, &node->bounds))
{
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_CLIP);
gsk_gpu_buffer_writer_append_rect (&self->writer, &source_child->bounds, &self->offset);
}
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_PUSH_COLOR);
if (!gsk_gpu_pattern_writer_push_stack (self))
return FALSE;
if (!gsk_gpu_node_processor_create_node_pattern (self, mask_child))
{
gsk_gpu_pattern_writer_pop_stack (self);
return FALSE;
}
if (!gsk_rect_contains_rect (&mask_child->bounds, &node->bounds))
{
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_CLIP);
gsk_gpu_buffer_writer_append_rect (&self->writer, &mask_child->bounds, &self->offset);
}
switch (gsk_mask_node_get_mask_mode (node))
{
case GSK_MASK_MODE_ALPHA:
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_POP_MASK_ALPHA);
break;
case GSK_MASK_MODE_INVERTED_ALPHA:
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_POP_MASK_INVERTED_ALPHA);
break;
case GSK_MASK_MODE_LUMINANCE:
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_POP_MASK_LUMINANCE);
break;
case GSK_MASK_MODE_INVERTED_LUMINANCE:
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_POP_MASK_INVERTED_LUMINANCE);
break;
default:
g_return_val_if_reached (FALSE);
}
gsk_gpu_pattern_writer_pop_stack (self);
return TRUE;
}
static void static void
gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self, gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
GskRenderNode *node) GskRenderNode *node)
@ -1448,8 +1509,8 @@ static const struct
}, },
[GSK_MASK_NODE] = { [GSK_MASK_NODE] = {
0, 0,
NULL, gsk_gpu_node_processor_add_node_as_pattern,
NULL, gsk_gpu_node_processor_create_mask_pattern,
}, },
[GSK_FILL_NODE] = { [GSK_FILL_NODE] = {
0, 0,

View File

@ -47,5 +47,9 @@ typedef enum {
GSK_GPU_PATTERN_POSITION_POP, GSK_GPU_PATTERN_POSITION_POP,
GSK_GPU_PATTERN_PUSH_COLOR, GSK_GPU_PATTERN_PUSH_COLOR,
GSK_GPU_PATTERN_POP_CROSS_FADE, GSK_GPU_PATTERN_POP_CROSS_FADE,
GSK_GPU_PATTERN_POP_MASK_ALPHA,
GSK_GPU_PATTERN_POP_MASK_INVERTED_ALPHA,
GSK_GPU_PATTERN_POP_MASK_LUMINANCE,
GSK_GPU_PATTERN_POP_MASK_INVERTED_LUMINANCE,
} GskGpuPatternType; } GskGpuPatternType;

View File

@ -13,4 +13,10 @@ color_unpremultiply (vec4 color)
return color.a > 0.0 ? color / vec4 (color.aaa, 1.0) : color; return color.a > 0.0 ? color / vec4 (color.aaa, 1.0) : color;
} }
float
luminance (vec3 color)
{
return dot (vec3 (0.2126, 0.7152, 0.0722), color);
}
#endif /* _COLOR_ */ #endif /* _COLOR_ */

View File

@ -24,6 +24,10 @@
#define GSK_GPU_PATTERN_POSITION_POP 14u #define GSK_GPU_PATTERN_POSITION_POP 14u
#define GSK_GPU_PATTERN_PUSH_COLOR 15u #define GSK_GPU_PATTERN_PUSH_COLOR 15u
#define GSK_GPU_PATTERN_POP_CROSS_FADE 16u #define GSK_GPU_PATTERN_POP_CROSS_FADE 16u
#define GSK_GPU_PATTERN_POP_MASK_ALPHA 17u
#define GSK_GPU_PATTERN_POP_MASK_INVERTED_ALPHA 18u
#define GSK_GPU_PATTERN_POP_MASK_LUMINANCE 19u
#define GSK_GPU_PATTERN_POP_MASK_INVERTED_LUMINANCE 20u
#define TOP 0u #define TOP 0u
#define RIGHT 1u #define RIGHT 1u

View File

@ -150,6 +150,42 @@ cross_fade_pattern (inout uint reader,
color = mix (start, color, progress); color = mix (start, color, progress);
} }
void
mask_alpha_pattern (inout uint reader,
inout vec4 color)
{
vec4 source = stack_pop ();
color = source * color.a;
}
void
mask_inverted_alpha_pattern (inout uint reader,
inout vec4 color)
{
vec4 source = stack_pop ();
color = source * (1.0 - color.a);
}
void
mask_luminance_pattern (inout uint reader,
inout vec4 color)
{
vec4 source = stack_pop ();
color = source * luminance (color.rgb);
}
void
mask_inverted_luminance_pattern (inout uint reader,
inout vec4 color)
{
vec4 source = stack_pop ();
color = source * (color.a - luminance (color.rgb));
}
vec4 vec4
glyphs_pattern (inout uint reader, glyphs_pattern (inout uint reader,
vec2 pos) vec2 pos)
@ -311,6 +347,18 @@ pattern (uint reader,
case GSK_GPU_PATTERN_POP_CROSS_FADE: case GSK_GPU_PATTERN_POP_CROSS_FADE:
cross_fade_pattern (reader, color); cross_fade_pattern (reader, color);
break; break;
case GSK_GPU_PATTERN_POP_MASK_ALPHA:
mask_alpha_pattern (reader, color);
break;
case GSK_GPU_PATTERN_POP_MASK_INVERTED_ALPHA:
mask_inverted_alpha_pattern (reader, color);
break;
case GSK_GPU_PATTERN_POP_MASK_LUMINANCE:
mask_luminance_pattern (reader, color);
break;
case GSK_GPU_PATTERN_POP_MASK_INVERTED_LUMINANCE:
mask_inverted_luminance_pattern (reader, color);
break;
} }
} }
} }