gsk: Change gradient op apis

Pass the ccs, opacity, interpolation color state and hue
interpolation explicitly, and change the argument order to
match other ops.

Since we now apply opacity in the op, change the node processor
to pass colors as-is. For now, it always passes GDK_COLOR_STATE_SRGB
for ics and GSK_HUE_INTERPOLATION_SHORTER for hue interpolation.
This commit is contained in:
Matthias Clasen
2024-08-05 15:32:20 -04:00
parent 1fe9918f3c
commit 9a7d84b441
8 changed files with 100 additions and 56 deletions

View File

@@ -52,24 +52,28 @@ static const GskGpuShaderOpClass GSK_GPU_CONIC_GRADIENT_OP_CLASS = {
void
gsk_gpu_conic_gradient_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GskGpuColorStates color_states,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GdkColorState *ics,
GskHueInterpolation hue_interp,
const graphene_rect_t *rect,
const graphene_point_t *center,
float angle,
const graphene_point_t *offset,
const GskColorStop *stops,
gsize n_stops)
{
GskGpuConicgradientInstance *instance;
GdkColorState *color_state = gsk_gpu_color_states_get_alt (color_states);
g_assert (n_stops > 1);
g_assert (n_stops <= 7);
g_assert (gsk_gpu_color_states_is_alt_premultiplied (color_states));
/* Note: we pass TRUE for alt-premultiplied because the
* vertex shader applies the alpha to the colors.
*/
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_CONIC_GRADIENT_OP_CLASS,
color_states,
gsk_gpu_color_states_create (ccs, TRUE, ics, TRUE),
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
clip,
NULL,
@@ -79,18 +83,18 @@ gsk_gpu_conic_gradient_op (GskGpuFrame *frame,
gsk_gpu_rect_to_float (rect, offset, instance->rect);
gsk_gpu_point_to_float (center, offset, instance->center);
instance->angle = angle;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 6)].color, instance->color6);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 6)].color, ics, opacity, instance->color6);
instance->offsets1[2] = stops[MIN (n_stops - 1, 6)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 5)].color, instance->color5);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 5)].color, ics, opacity, instance->color5);
instance->offsets1[1] = stops[MIN (n_stops - 1, 5)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 4)].color, instance->color4);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 4)].color, ics, opacity, instance->color4);
instance->offsets1[0] = stops[MIN (n_stops - 1, 4)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 3)].color, instance->color3);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 3)].color, ics, opacity, instance->color3);
instance->offsets0[3] = stops[MIN (n_stops - 1, 3)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 2)].color, instance->color2);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 2)].color, ics, opacity, instance->color2);
instance->offsets0[2] = stops[MIN (n_stops - 1, 2)].offset;
gdk_color_state_from_rgba (color_state, &stops[1].color, instance->color1);
gsk_gpu_rgba_to_float (&stops[1].color, ics, opacity, instance->color1);
instance->offsets0[1] = stops[1].offset;
gdk_color_state_from_rgba (color_state, &stops[0].color, instance->color0);
gsk_gpu_rgba_to_float (&stops[0].color, ics, opacity, instance->color0);
instance->offsets0[0] = stops[0].offset;
}

View File

@@ -2,7 +2,7 @@
#include "gskgpushaderopprivate.h"
#include "gskrendernode.h"
#include "gskrendernodeprivate.h"
#include <graphene.h>
@@ -10,11 +10,14 @@ G_BEGIN_DECLS
void gsk_gpu_conic_gradient_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GskGpuColorStates color_states,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GdkColorState *ics,
GskHueInterpolation hue_interp,
const graphene_rect_t *rect,
const graphene_point_t *center,
float angle,
const graphene_point_t *offset,
const GskColorStop *stops,
gsize n_stops);

View File

@@ -55,25 +55,29 @@ static const GskGpuShaderOpClass GSK_GPU_LINEAR_GRADIENT_OP_CLASS = {
void
gsk_gpu_linear_gradient_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GskGpuColorStates color_states,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GdkColorState *ics,
GskHueInterpolation hue_interp,
gboolean repeating,
const graphene_rect_t *rect,
const graphene_point_t *start,
const graphene_point_t *end,
const graphene_point_t *offset,
const GskColorStop *stops,
gsize n_stops)
{
GskGpuLineargradientInstance *instance;
GdkColorState *color_state = gsk_gpu_color_states_get_alt (color_states);
g_assert (n_stops > 1);
g_assert (n_stops <= 7);
g_assert (gsk_gpu_color_states_is_alt_premultiplied (color_states));
/* Note: we pass TRUE for alt-premultiplied because the
* vertex shader applies the alpha to the colors.
*/
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_LINEAR_GRADIENT_OP_CLASS,
color_states,
gsk_gpu_color_states_create (ccs, TRUE, ics, TRUE),
(repeating ? VARIATION_REPEATING : 0) |
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
clip,
@@ -84,18 +88,18 @@ 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]);
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 6)].color, instance->color6);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 6)].color, ics, opacity, instance->color6);
instance->offsets1[2] = stops[MIN (n_stops - 1, 6)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 5)].color, instance->color5);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 5)].color, ics, opacity, instance->color5);
instance->offsets1[1] = stops[MIN (n_stops - 1, 5)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 4)].color, instance->color4);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 4)].color, ics, opacity, instance->color4);
instance->offsets1[0] = stops[MIN (n_stops - 1, 4)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 3)].color, instance->color3);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 3)].color, ics, opacity, instance->color3);
instance->offsets0[3] = stops[MIN (n_stops - 1, 3)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 2)].color, instance->color2);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 2)].color, ics, opacity, instance->color2);
instance->offsets0[2] = stops[MIN (n_stops - 1, 2)].offset;
gdk_color_state_from_rgba (color_state, &stops[1].color, instance->color1);
gsk_gpu_rgba_to_float (&stops[1].color, ics, opacity, instance->color1);
instance->offsets0[1] = stops[1].offset;
gdk_color_state_from_rgba (color_state, &stops[0].color, instance->color0);
gsk_gpu_rgba_to_float (&stops[0].color, ics, opacity, instance->color0);
instance->offsets0[0] = stops[0].offset;
}

View File

@@ -2,7 +2,7 @@
#include "gskgpushaderopprivate.h"
#include "gskrendernode.h"
#include "gskrendernodeprivate.h"
#include <graphene.h>
@@ -10,12 +10,15 @@ G_BEGIN_DECLS
void gsk_gpu_linear_gradient_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GskGpuColorStates color_states,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GdkColorState *ics,
GskHueInterpolation hue_interp,
gboolean repeating,
const graphene_rect_t *rect,
const graphene_point_t *start,
const graphene_point_t *end,
const graphene_point_t *offset,
const GskColorStop *stops,
gsize n_stops);

View File

@@ -2488,11 +2488,11 @@ 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);
real_stops[i].color = stops[i].color;
}
stops = real_stops;
}
func (self, node, stops, n_stops);
return;
@@ -2519,7 +2519,7 @@ 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);
real_stops[0].color = stops[i].color;
i++;
}
else
@@ -2530,14 +2530,14 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
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);
real_stops[j].color = stops[i].color;
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);
real_stops[j].color = stops[i].color;
j++;
i++;
}
@@ -2574,12 +2574,15 @@ gsk_gpu_node_processor_linear_gradient_op (GskGpuNodeProcessor *self,
{
gsk_gpu_linear_gradient_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
gsk_gpu_node_processor_color_states_explicit (self, GDK_COLOR_STATE_SRGB, TRUE),
self->ccs,
self->opacity,
&self->offset,
GDK_COLOR_STATE_SRGB,
GSK_HUE_INTERPOLATION_SHORTER,
GSK_RENDER_NODE_TYPE (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE,
&node->bounds,
gsk_linear_gradient_node_get_start (node),
gsk_linear_gradient_node_get_end (node),
&self->offset,
stops,
n_stops);
}
@@ -2603,7 +2606,11 @@ gsk_gpu_node_processor_radial_gradient_op (GskGpuNodeProcessor *self,
{
gsk_gpu_radial_gradient_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
gsk_gpu_node_processor_color_states_explicit (self, GDK_COLOR_STATE_SRGB, TRUE),
self->ccs,
self->opacity,
&self->offset,
GDK_COLOR_STATE_SRGB,
GSK_HUE_INTERPOLATION_SHORTER,
GSK_RENDER_NODE_TYPE (node) == GSK_REPEATING_RADIAL_GRADIENT_NODE,
&node->bounds,
gsk_radial_gradient_node_get_center (node),
@@ -2613,7 +2620,6 @@ gsk_gpu_node_processor_radial_gradient_op (GskGpuNodeProcessor *self,
),
gsk_radial_gradient_node_get_start (node),
gsk_radial_gradient_node_get_end (node),
&self->offset,
stops,
n_stops);
}
@@ -2637,11 +2643,14 @@ gsk_gpu_node_processor_conic_gradient_op (GskGpuNodeProcessor *self,
{
gsk_gpu_conic_gradient_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
gsk_gpu_node_processor_color_states_explicit (self, GDK_COLOR_STATE_SRGB, TRUE),
self->ccs,
self->opacity,
&self->offset,
GDK_COLOR_STATE_SRGB,
GSK_HUE_INTERPOLATION_SHORTER,
&node->bounds,
gsk_conic_gradient_node_get_center (node),
gsk_conic_gradient_node_get_angle (node),
&self->offset,
stops,
n_stops);
}

View File

@@ -55,27 +55,31 @@ static const GskGpuShaderOpClass GSK_GPU_RADIAL_GRADIENT_OP_CLASS = {
void
gsk_gpu_radial_gradient_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GskGpuColorStates color_states,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GdkColorState *ics,
GskHueInterpolation hue_interp,
gboolean repeating,
const graphene_rect_t *rect,
const graphene_point_t *center,
const graphene_point_t *radius,
float start,
float end,
const graphene_point_t *offset,
const GskColorStop *stops,
gsize n_stops)
{
GskGpuRadialgradientInstance *instance;
GdkColorState *color_state = gsk_gpu_color_states_get_alt (color_states);
g_assert (n_stops > 1);
g_assert (n_stops <= 7);
g_assert (gsk_gpu_color_states_is_alt_premultiplied (color_states));
/* Note: we pass TRUE for alt-premultiplied because the
* vertex shader applies the alpha to the colors.
*/
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_RADIAL_GRADIENT_OP_CLASS,
color_states,
gsk_gpu_color_states_create (ccs, TRUE, ics, TRUE),
(repeating ? VARIATION_REPEATING : 0) |
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
clip,
@@ -88,18 +92,18 @@ 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;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 6)].color, instance->color6);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 6)].color, ics, opacity, instance->color6);
instance->offsets1[2] = stops[MIN (n_stops - 1, 6)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 5)].color, instance->color5);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 5)].color, ics, opacity, instance->color5);
instance->offsets1[1] = stops[MIN (n_stops - 1, 5)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 4)].color, instance->color4);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 4)].color, ics, opacity, instance->color4);
instance->offsets1[0] = stops[MIN (n_stops - 1, 4)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 3)].color, instance->color3);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 3)].color, ics, opacity, instance->color3);
instance->offsets0[3] = stops[MIN (n_stops - 1, 3)].offset;
gdk_color_state_from_rgba (color_state, &stops[MIN (n_stops - 1, 2)].color, instance->color2);
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 2)].color, ics, opacity, instance->color2);
instance->offsets0[2] = stops[MIN (n_stops - 1, 2)].offset;
gdk_color_state_from_rgba (color_state, &stops[1].color, instance->color1);
gsk_gpu_rgba_to_float (&stops[1].color, ics, opacity, instance->color1);
instance->offsets0[1] = stops[1].offset;
gdk_color_state_from_rgba (color_state, &stops[0].color, instance->color0);
gsk_gpu_rgba_to_float (&stops[0].color, ics, opacity, instance->color0);
instance->offsets0[0] = stops[0].offset;
}

View File

@@ -2,7 +2,7 @@
#include "gskgpushaderopprivate.h"
#include "gskrendernode.h"
#include "gskrendernodeprivate.h"
#include <graphene.h>
@@ -10,14 +10,17 @@ G_BEGIN_DECLS
void gsk_gpu_radial_gradient_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GskGpuColorStates color_states,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GdkColorState *ics,
GskHueInterpolation hue_interp,
gboolean repeating,
const graphene_rect_t *rect,
const graphene_point_t *center,
const graphene_point_t *radius,
float start,
float end,
const graphene_point_t *offset,
const GskColorStop *stops,
gsize n_stops);

View File

@@ -113,4 +113,18 @@ gsk_gpu_color_to_float (const GdkColor *color,
values[3] *= opacity;
}
static inline void
gsk_gpu_rgba_to_float (const GdkRGBA *rgba,
GdkColorState *target,
float opacity,
float values[4])
{
GdkColor color;
gdk_color_init_from_rgba (&color, rgba);
gdk_color_to_float (&color, target, values);
values[3] *= opacity;
gdk_color_finish (&color);
}
G_END_DECLS