Gradients for the pattern shader

This commit is contained in:
Matthias Clasen
2024-06-13 01:41:32 -04:00
parent 1f1e41bdaa
commit 0764cfe566
9 changed files with 117 additions and 56 deletions

View File

@@ -64,7 +64,7 @@ gsk_gpu_conic_gradient_op (GskGpuFrame *frame,
GdkColorState *in,
GdkColorState *target,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops)
{
GskGpuConicgradientInstance *instance;
@@ -80,23 +80,22 @@ gsk_gpu_conic_gradient_op (GskGpuFrame *frame,
NULL,
&instance);
/* FIXME: apply hue_interp */
gsk_gpu_rect_to_float (rect, offset, instance->rect);
gsk_gpu_point_to_float (center, offset, instance->center);
instance->angle = angle;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 6)].color, instance->color6);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 6)].color, instance->color6);
instance->offsets1[2] = stops[MIN (n_stops - 1, 6)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 5)].color, instance->color5);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 5)].color, instance->color5);
instance->offsets1[1] = stops[MIN (n_stops - 1, 5)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 4)].color, instance->color4);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 4)].color, instance->color4);
instance->offsets1[0] = stops[MIN (n_stops - 1, 4)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 3)].color, instance->color3);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 3)].color, instance->color3);
instance->offsets0[3] = stops[MIN (n_stops - 1, 3)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 2)].color, instance->color2);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 2)].color, instance->color2);
instance->offsets0[2] = stops[MIN (n_stops - 1, 2)].offset;
gsk_gpu_rgba_to_float (&stops[1].color, instance->color1);
gsk_gpu_color_to_float (&stops[1].color, instance->color1);
instance->offsets0[1] = stops[1].offset;
gsk_gpu_rgba_to_float (&stops[0].color, instance->color0);
gsk_gpu_color_to_float (&stops[0].color, instance->color0);
instance->offsets0[0] = stops[0].offset;
int hue_coord = gdk_color_state_get_hue_coord (in);

View File

@@ -17,7 +17,7 @@ void gsk_gpu_conic_gradient_op (GskGpuF
GdkColorState *in,
GdkColorState *target,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops);

View File

@@ -127,7 +127,7 @@ gsk_gpu_linear_gradient_op (GskGpuFrame *frame,
GdkColorState *in,
GdkColorState *target,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops)
{
GskGpuLineargradientInstance *instance;
@@ -147,19 +147,19 @@ gsk_gpu_linear_gradient_op (GskGpuFrame *frame,
gsk_gpu_rect_to_float (rect, offset, instance->rect);
gsk_gpu_point_to_float (start, offset, instance->startend);
gsk_gpu_point_to_float (end, offset, &instance->startend[2]);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 6)].color, instance->color6);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 6)].color, instance->color6);
instance->offsets1[2] = stops[MIN (n_stops - 1, 6)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 5)].color, instance->color5);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 5)].color, instance->color5);
instance->offsets1[1] = stops[MIN (n_stops - 1, 5)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 4)].color, instance->color4);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 4)].color, instance->color4);
instance->offsets1[0] = stops[MIN (n_stops - 1, 4)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 3)].color, instance->color3);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 3)].color, instance->color3);
instance->offsets0[3] = stops[MIN (n_stops - 1, 3)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 2)].color, instance->color2);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 2)].color, instance->color2);
instance->offsets0[2] = stops[MIN (n_stops - 1, 2)].offset;
gsk_gpu_rgba_to_float (&stops[1].color, instance->color1);
gsk_gpu_color_to_float (&stops[1].color, instance->color1);
instance->offsets0[1] = stops[1].offset;
gsk_gpu_rgba_to_float (&stops[0].color, instance->color0);
gsk_gpu_color_to_float (&stops[0].color, instance->color0);
instance->offsets0[0] = stops[0].offset;
int hue_coord = gdk_color_state_get_hue_coord (in);

View File

@@ -18,8 +18,8 @@ void gsk_gpu_linear_gradient_op (GskGpuF
GdkColorState *in,
GdkColorState *target,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
gsize n_stops);
const GskColorStop2 *stops,
gsize n_stops);
int gsk_get_hue_coord (GdkColorState *in);

View File

@@ -620,11 +620,32 @@ gsk_gpu_pattern_writer_append_rgba (GskGpuPatternWriter *self,
static void
gsk_gpu_pattern_writer_append_color_stops (GskGpuPatternWriter *self,
const GskColorStop *stops,
GdkColorState *color_state,
GskHueInterpolation hue_interp,
const GskColorStop2 *stops,
gsize n_stops)
{
GdkColor *colors;
int hue;
hue = gdk_color_state_get_hue_coord (color_state);
colors = g_newa (GdkColor, n_stops);
gsk_gpu_pattern_writer_append_uint (self, n_stops);
gsk_gpu_pattern_writer_append (self, G_ALIGNOF (float), (guchar *) stops, sizeof (GskColorStop) * n_stops);
for (int i = 0; i < n_stops; i++)
{
gdk_color_convert (&colors[i], color_state, &stops[i].color);
if (i > 0 && hue != -1)
gsk_adjust_hue (hue_interp, &colors[i-1].values[hue], &colors[i].values[hue]);
}
for (int i = 0; i < n_stops; i++)
{
gsk_gpu_pattern_writer_append (self, G_ALIGNOF (float), (guchar *) &stops[i].offset, sizeof (float));
gsk_gpu_pattern_writer_append (self, G_ALIGNOF (float), (guchar *) colors[i].values, sizeof (float) * 4);
}
}
static gboolean
@@ -2426,7 +2447,7 @@ typedef void (* GradientOpFunc) (GskGpuNodeProcessor *self,
GskRenderNode *node,
GdkColorState *in,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops);
static void
@@ -2434,11 +2455,11 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
GskRenderNode *node,
GdkColorState *in,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops,
GradientOpFunc func)
{
GskColorStop real_stops[7];
GskColorStop2 real_stops[7];
GskGpuNodeProcessor other;
graphene_rect_t bounds;
gsize i, j;
@@ -2452,7 +2473,8 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
for (i = 0; i < n_stops; i++)
{
real_stops[i].offset = stops[i].offset;
real_stops[i].color = GDK_RGBA_INIT_ALPHA (&stops[i].color, self->opacity);
gdk_color_convert (&real_stops[i].color, in, &stops[i].color);
real_stops[i].color.values[3] *= self->opacity;
}
stops = real_stops;
}
@@ -2485,32 +2507,37 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
if (i == 0)
{
real_stops[0].offset = stops[i].offset;
real_stops[0].color = GDK_RGBA_INIT_ALPHA (&stops[i].color, self->opacity);
gdk_color_convert (&real_stops[i].color, in, &stops[i].color);
real_stops[i].color.values[3] *= self->opacity;
i++;
}
else
{
real_stops[0].offset = stops[i-1].offset;
real_stops[0].color = GDK_RGBA_INIT_ALPHA (&stops[i-1].color, 0);
gdk_color_convert (&real_stops[0].color, in, &stops[i-1].color);
real_stops[i].color.values[3] = 0;
}
for (j = 1; j < 6 && i < n_stops; j++)
{
real_stops[j].offset = stops[i].offset;
real_stops[j].color = GDK_RGBA_INIT_ALPHA (&stops[i].color, self->opacity);
gdk_color_convert (&real_stops[j].color, in, &stops[i].color);
real_stops[j].color.values[3] *= self->opacity;
i++;
}
if (i == n_stops - 1)
{
g_assert (j == 6);
real_stops[j].offset = stops[i].offset;
real_stops[j].color = GDK_RGBA_INIT_ALPHA (&stops[i].color, self->opacity);
gdk_color_convert (&real_stops[j].color, in, &stops[i].color);
real_stops[j].color.values[3] *= self->opacity;
j++;
i++;
}
else if (i < n_stops)
{
real_stops[j].offset = stops[i].offset;
real_stops[j].color = GDK_RGBA_INIT_ALPHA (&stops[i].color, 0);
gdk_color_convert (&real_stops[j].color, in, &stops[i].color);
real_stops[j].color.values[3] = 0;
j++;
}
@@ -2537,7 +2564,7 @@ gsk_gpu_node_processor_linear_gradient_op (GskGpuNodeProcessor *self,
GskRenderNode *node,
GdkColorState *in,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops)
{
gsk_gpu_linear_gradient_op (self->frame,
@@ -2562,7 +2589,7 @@ gsk_gpu_node_processor_add_linear_gradient_node (GskGpuNodeProcessor *self,
node,
gsk_linear_gradient_node_get_color_state (node),
gsk_linear_gradient_node_get_hue_interpolation (node),
gsk_linear_gradient_node_get_color_stops (node, NULL),
gsk_linear_gradient_node_get_color_stops2 (node, NULL),
gsk_linear_gradient_node_get_n_color_stops (node),
gsk_gpu_node_processor_linear_gradient_op);
}
@@ -2571,11 +2598,17 @@ static gboolean
gsk_gpu_node_processor_create_linear_gradient_pattern (GskGpuPatternWriter *self,
GskRenderNode *node)
{
guint conversion;
if (gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE)
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_REPEATING_LINEAR_GRADIENT);
else
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_LINEAR_GRADIENT);
conversion = gsk_gpu_color_conversion (gsk_linear_gradient_node_get_color_state (node),
self->color_state);
gsk_gpu_pattern_writer_append_uint (self, conversion);
gsk_gpu_pattern_writer_append_point (self,
gsk_linear_gradient_node_get_start (node),
&self->offset);
@@ -2583,8 +2616,10 @@ gsk_gpu_node_processor_create_linear_gradient_pattern (GskGpuPatternWriter *self
gsk_linear_gradient_node_get_end (node),
&self->offset);
gsk_gpu_pattern_writer_append_color_stops (self,
gsk_linear_gradient_node_get_color_stops (node, NULL),
gsk_linear_gradient_node_get_n_color_stops (node));
gsk_linear_gradient_node_get_color_state (node),
gsk_linear_gradient_node_get_hue_interpolation (node),
gsk_linear_gradient_node_get_color_stops2 (node, NULL),
gsk_linear_gradient_node_get_n_color_stops (node));
return TRUE;
}
@@ -2594,7 +2629,7 @@ gsk_gpu_node_processor_radial_gradient_op (GskGpuNodeProcessor *self,
GskRenderNode *node,
GdkColorState *in,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops)
{
gsk_gpu_radial_gradient_op (self->frame,
@@ -2624,7 +2659,7 @@ gsk_gpu_node_processor_add_radial_gradient_node (GskGpuNodeProcessor *self,
node,
gsk_radial_gradient_node_get_color_state (node),
gsk_radial_gradient_node_get_hue_interpolation (node),
gsk_radial_gradient_node_get_color_stops (node, NULL),
gsk_radial_gradient_node_get_color_stops2 (node, NULL),
gsk_radial_gradient_node_get_n_color_stops (node),
gsk_gpu_node_processor_radial_gradient_op);
}
@@ -2633,11 +2668,17 @@ static gboolean
gsk_gpu_node_processor_create_radial_gradient_pattern (GskGpuPatternWriter *self,
GskRenderNode *node)
{
guint conversion;
if (gsk_render_node_get_node_type (node) == GSK_REPEATING_RADIAL_GRADIENT_NODE)
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_REPEATING_RADIAL_GRADIENT);
else
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_RADIAL_GRADIENT);
conversion = gsk_gpu_color_conversion (gsk_linear_gradient_node_get_color_state (node),
self->color_state);
gsk_gpu_pattern_writer_append_uint (self, conversion);
gsk_gpu_pattern_writer_append_point (self,
gsk_radial_gradient_node_get_center (node),
&self->offset);
@@ -2646,8 +2687,10 @@ gsk_gpu_node_processor_create_radial_gradient_pattern (GskGpuPatternWriter *self
gsk_gpu_pattern_writer_append_float (self, gsk_radial_gradient_node_get_start (node));
gsk_gpu_pattern_writer_append_float (self, gsk_radial_gradient_node_get_end (node));
gsk_gpu_pattern_writer_append_color_stops (self,
gsk_radial_gradient_node_get_color_stops (node, NULL),
gsk_radial_gradient_node_get_n_color_stops (node));
gsk_radial_gradient_node_get_color_state (node),
gsk_radial_gradient_node_get_hue_interpolation (node),
gsk_radial_gradient_node_get_color_stops2 (node, NULL),
gsk_radial_gradient_node_get_n_color_stops (node));
return TRUE;
}
@@ -2657,7 +2700,7 @@ gsk_gpu_node_processor_conic_gradient_op (GskGpuNodeProcessor *self,
GskRenderNode *node,
GdkColorState *in,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops)
{
gsk_gpu_conic_gradient_op (self->frame,
@@ -2681,7 +2724,7 @@ gsk_gpu_node_processor_add_conic_gradient_node (GskGpuNodeProcessor *self,
node,
gsk_conic_gradient_node_get_color_state (node),
gsk_conic_gradient_node_get_hue_interpolation (node),
gsk_conic_gradient_node_get_color_stops (node, NULL),
gsk_conic_gradient_node_get_color_stops2 (node, NULL),
gsk_conic_gradient_node_get_n_color_stops (node),
gsk_gpu_node_processor_conic_gradient_op);
}
@@ -2690,14 +2733,21 @@ static gboolean
gsk_gpu_node_processor_create_conic_gradient_pattern (GskGpuPatternWriter *self,
GskRenderNode *node)
{
guint conversion;
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_CONIC_GRADIENT);
conversion = gsk_gpu_color_conversion (gsk_linear_gradient_node_get_color_state (node),
self->color_state);
gsk_gpu_pattern_writer_append_uint (self, conversion);
gsk_gpu_pattern_writer_append_point (self,
gsk_conic_gradient_node_get_center (node),
&self->offset);
gsk_gpu_pattern_writer_append_float (self, gsk_conic_gradient_node_get_angle (node));
gsk_gpu_pattern_writer_append_color_stops (self,
gsk_conic_gradient_node_get_color_stops (node, NULL),
gsk_conic_gradient_node_get_n_color_stops (node));
gsk_conic_gradient_node_get_color_state (node),
gsk_conic_gradient_node_get_hue_interpolation (node),
gsk_conic_gradient_node_get_color_stops2 (node, NULL),
gsk_conic_gradient_node_get_n_color_stops (node));
return TRUE;
}

View File

@@ -71,7 +71,7 @@ gsk_gpu_radial_gradient_op (GskGpuFrame *frame,
GdkColorState *in,
GdkColorState *target,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops)
{
GskGpuRadialgradientInstance *instance;
@@ -94,19 +94,19 @@ gsk_gpu_radial_gradient_op (GskGpuFrame *frame,
gsk_gpu_point_to_float (radius, graphene_point_zero(), &instance->center_radius[2]);
instance->startend[0] = start;
instance->startend[1] = end;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 6)].color, instance->color6);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 6)].color, instance->color6);
instance->offsets1[2] = stops[MIN (n_stops - 1, 6)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 5)].color, instance->color5);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 5)].color, instance->color5);
instance->offsets1[1] = stops[MIN (n_stops - 1, 5)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 4)].color, instance->color4);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 4)].color, instance->color4);
instance->offsets1[0] = stops[MIN (n_stops - 1, 4)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 3)].color, instance->color3);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 3)].color, instance->color3);
instance->offsets0[3] = stops[MIN (n_stops - 1, 3)].offset;
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 2)].color, instance->color2);
gsk_gpu_color_to_float (&stops[MIN (n_stops - 1, 2)].color, instance->color2);
instance->offsets0[2] = stops[MIN (n_stops - 1, 2)].offset;
gsk_gpu_rgba_to_float (&stops[1].color, instance->color1);
gsk_gpu_color_to_float (&stops[1].color, instance->color1);
instance->offsets0[1] = stops[1].offset;
gsk_gpu_rgba_to_float (&stops[0].color, instance->color0);
gsk_gpu_color_to_float (&stops[0].color, instance->color0);
instance->offsets0[0] = stops[0].offset;
int hue_coord = gdk_color_state_get_hue_coord (in);

View File

@@ -20,7 +20,7 @@ void gsk_gpu_radial_gradient_op (GskGpuF
GdkColorState *in,
GdkColorState *target,
GskHueInterpolation hue_interp,
const GskColorStop *stops,
const GskColorStop2 *stops,
gsize n_stops);

View File

@@ -73,6 +73,16 @@ gsk_gpu_rgba_to_float (const GdkRGBA *rgba,
values[3] = rgba->alpha;
}
static inline void
gsk_gpu_color_to_float (const GdkColor *color,
float values[4])
{
values[0] = color->values[0];
values[1] = color->values[1];
values[2] = color->values[2];
values[3] = color->values[3];
}
#include <graphene.h>
static inline void

View File

@@ -9,6 +9,7 @@ struct Gradient
{
int n_stops;
uint offset;
uint conversion;
};
float
@@ -109,7 +110,7 @@ gradient_get_color_repeating (Gradient self,
}
c /= end - start;
return color_premultiply (c);
return color_premultiply (color_convert (c, self.conversion));
}
vec4
@@ -125,20 +126,21 @@ gradient_get_color (Gradient self,
if (end > start)
c /= end - start;
return color_premultiply (c);
return color_premultiply (color_convert (c, self.conversion));
}
uint
gradient_get_size (Gradient self)
{
return uint (self.n_stops) * 5u + 1u;
return uint (self.n_stops) * 5u + 2u;
}
Gradient
gradient_new (uint offset)
{
Gradient self = Gradient (gsk_get_int (offset),
offset + 1u);
offset + 1u,
offset + 2u);
return self;
}