vulkan: Make fill node handle multiple contours

We still only handle standard contours, but now we can do multiple.
This commit is contained in:
Benjamin Otte
2023-07-17 21:06:35 +02:00
parent 9f12c5df07
commit d2aa139e86
2 changed files with 44 additions and 8 deletions

View File

@@ -65,16 +65,31 @@ gsk_vulkan_fill_op_reserve_descriptor_sets (GskVulkanOp *op,
{
GskVulkanFillOp *self = (GskVulkanFillOp *) op;
const GskContour *contour;
gsize size, i, n;
guchar *mem;
//g_warn_if_fail (gsk_path_get_n_contours (self->path) == 1);
contour = gsk_path_get_contour (self->path, 0);
size = sizeof (guint32);
n = gsk_path_get_n_contours (self->path);
for (i = 0; i < n; i++)
{
contour = gsk_path_get_contour (self->path, i);
size += gsk_contour_get_shader_size (contour);
}
mem = gsk_vulkan_render_get_buffer_memory (render,
gsk_contour_get_shader_size (contour),
size,
G_ALIGNOF (float),
&self->buffer_offset);
gsk_contour_to_shader (contour, mem);
*(guint32*) mem = n;
mem += sizeof (guint32);
for (i = 0; i < n; i++)
{
contour = gsk_path_get_contour (self->path, i);
gsk_contour_to_shader (contour, mem);
mem += gsk_contour_get_shader_size (contour);
}
}
static const GskVulkanShaderOpClass GSK_VULKAN_FILL_OP_CLASS = {

View File

@@ -216,15 +216,16 @@ cubic_distance_squared (vec2 uv,
}
float
path_distance (vec2 p)
standard_contour_distance (vec2 p,
inout int path_idx,
inout int w)
{
int n_points = get_int (in_points_id);
int ops_idx = in_points_id + 1;
int n_points = get_int (path_idx);
int ops_idx = path_idx + 1;
int pts_idx = ops_idx + n_points;
vec2 start = get_point (pts_idx);
float d = dot (p - start, p - start);
int w = 0;
int op = GSK_PATH_MOVE;
for (int i = 1; i < n_points; i++)
@@ -273,6 +274,26 @@ path_distance (vec2 p)
d = min (d, line_distance_squared (p, start, end, w));
}
path_idx = pts_idx;
return d;
}
float
path_distance (vec2 p)
{
int path_idx = in_points_id;
int n = get_int (path_idx);
path_idx++;
int w = 0;
float d = 1e38;
while (n-- > 0)
{
d = min (d, standard_contour_distance (p, path_idx, w));
}
if (in_fill_rule == GSK_FILL_RULE_WINDING)
{
if (w == 0)