diff --git a/gsk/gpu/gskgpuconicgradientop.c b/gsk/gpu/gskgpuconicgradientop.c index 42f5ea27ff..17ff0a03d0 100644 --- a/gsk/gpu/gskgpuconicgradientop.c +++ b/gsk/gpu/gskgpuconicgradientop.c @@ -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); diff --git a/gsk/gpu/gskgpuconicgradientopprivate.h b/gsk/gpu/gskgpuconicgradientopprivate.h index ab642c6e2e..620ce50ba5 100644 --- a/gsk/gpu/gskgpuconicgradientopprivate.h +++ b/gsk/gpu/gskgpuconicgradientopprivate.h @@ -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); diff --git a/gsk/gpu/gskgpulineargradientop.c b/gsk/gpu/gskgpulineargradientop.c index 9556444e87..d315a43f4a 100644 --- a/gsk/gpu/gskgpulineargradientop.c +++ b/gsk/gpu/gskgpulineargradientop.c @@ -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); diff --git a/gsk/gpu/gskgpulineargradientopprivate.h b/gsk/gpu/gskgpulineargradientopprivate.h index b191e469c0..fd55283cb8 100644 --- a/gsk/gpu/gskgpulineargradientopprivate.h +++ b/gsk/gpu/gskgpulineargradientopprivate.h @@ -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); diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index 7414947074..ab939b4267 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -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; } diff --git a/gsk/gpu/gskgpuradialgradientop.c b/gsk/gpu/gskgpuradialgradientop.c index 737a776a70..eb33fe1e3b 100644 --- a/gsk/gpu/gskgpuradialgradientop.c +++ b/gsk/gpu/gskgpuradialgradientop.c @@ -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); diff --git a/gsk/gpu/gskgpuradialgradientopprivate.h b/gsk/gpu/gskgpuradialgradientopprivate.h index 3c4dbfbdfb..4cbc3ca944 100644 --- a/gsk/gpu/gskgpuradialgradientopprivate.h +++ b/gsk/gpu/gskgpuradialgradientopprivate.h @@ -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); diff --git a/gsk/gpu/gskgpushaderopprivate.h b/gsk/gpu/gskgpushaderopprivate.h index 3276d1cdef..8b62b162ce 100644 --- a/gsk/gpu/gskgpushaderopprivate.h +++ b/gsk/gpu/gskgpushaderopprivate.h @@ -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 static inline void diff --git a/gsk/gpu/shaders/gradient.glsl b/gsk/gpu/shaders/gradient.glsl index 0fd2cb9649..60f8251d02 100644 --- a/gsk/gpu/shaders/gradient.glsl +++ b/gsk/gpu/shaders/gradient.glsl @@ -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; }