gsk: Make non-default interpolation cs work

If the interpolation color state is not a default one, use the
offscreen we already for rendering big gradients, interpolate
the gradient into it, and then use a cicp convert shader to
convert the result to the ccs.
This commit is contained in:
Matthias Clasen
2024-08-09 14:51:20 -04:00
parent c44efc31ba
commit 4368583cbe

View File

@@ -2464,6 +2464,7 @@ gsk_gpu_node_processor_add_outset_shadow_node (GskGpuNodeProcessor *self,
}
typedef void (* GradientOpFunc) (GskGpuNodeProcessor *self,
GdkColorState *target,
GskRenderNode *node,
const GskColorStop2 *stops,
gsize n_stops);
@@ -2471,6 +2472,7 @@ typedef void (* GradientOpFunc) (GskGpuNodeProcessor *self,
static void
gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
GskRenderNode *node,
GdkColorState *ics,
const GskColorStop2 *stops,
gsize n_stops,
GradientOpFunc func)
@@ -2480,10 +2482,16 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
graphene_rect_t bounds;
gsize i, j;
GskGpuImage *image;
GdkColorState *target;
if (n_stops < 8)
if (GDK_IS_DEFAULT_COLOR_STATE (ics))
target = self->ccs;
else
target = ics;
if (n_stops < 8 && GDK_IS_DEFAULT_COLOR_STATE (ics))
{
func (self, node, stops, n_stops);
func (self, target, node, stops, n_stops);
return;
}
@@ -2539,33 +2547,57 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
j++;
}
func (&other, node, real_stops, j);
func (&other, target, node, real_stops, j);
}
gsk_gpu_node_processor_finish_draw (&other, image);
gsk_gpu_texture_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &bounds),
&self->offset,
&(GskGpuShaderImage) {
image,
GSK_GPU_SAMPLER_DEFAULT,
&node->bounds,
&bounds
});
if (GDK_IS_DEFAULT_COLOR_STATE (ics))
{
gsk_gpu_texture_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &bounds),
&self->offset,
&(GskGpuShaderImage) {
image,
GSK_GPU_SAMPLER_DEFAULT,
&node->bounds,
&bounds
});
}
else
{
const GdkCicp *cicp = gdk_color_state_get_cicp (ics);
g_assert (cicp != NULL);
gsk_gpu_convert_from_cicp_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &bounds),
cicp,
gsk_gpu_color_states_create_cicp (self->ccs, TRUE, TRUE),
1,
TRUE,
&self->offset,
&(GskGpuShaderImage) {
image,
GSK_GPU_SAMPLER_DEFAULT,
&node->bounds,
&bounds
});
}
g_object_unref (image);
}
static void
gsk_gpu_node_processor_linear_gradient_op (GskGpuNodeProcessor *self,
GdkColorState *target,
GskRenderNode *node,
const GskColorStop2 *stops,
gsize n_stops)
{
gsk_gpu_linear_gradient_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
self->ccs,
target,
self->opacity,
&self->offset,
gsk_linear_gradient_node_get_interpolation_color_state (node),
@@ -2584,6 +2616,7 @@ gsk_gpu_node_processor_add_linear_gradient_node (GskGpuNodeProcessor *self,
{
gsk_gpu_node_processor_add_gradient_node (self,
node,
gsk_linear_gradient_node_get_interpolation_color_state (node),
gsk_linear_gradient_node_get_color_stops2 (node),
gsk_linear_gradient_node_get_n_color_stops (node),
gsk_gpu_node_processor_linear_gradient_op);
@@ -2591,13 +2624,14 @@ gsk_gpu_node_processor_add_linear_gradient_node (GskGpuNodeProcessor *self,
static void
gsk_gpu_node_processor_radial_gradient_op (GskGpuNodeProcessor *self,
GdkColorState *target,
GskRenderNode *node,
const GskColorStop2 *stops,
gsize n_stops)
{
gsk_gpu_radial_gradient_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
self->ccs,
target,
self->opacity,
&self->offset,
gsk_radial_gradient_node_get_interpolation_color_state (node),
@@ -2621,6 +2655,7 @@ gsk_gpu_node_processor_add_radial_gradient_node (GskGpuNodeProcessor *self,
{
gsk_gpu_node_processor_add_gradient_node (self,
node,
gsk_radial_gradient_node_get_interpolation_color_state (node),
gsk_radial_gradient_node_get_color_stops2 (node),
gsk_radial_gradient_node_get_n_color_stops (node),
gsk_gpu_node_processor_radial_gradient_op);
@@ -2628,13 +2663,14 @@ gsk_gpu_node_processor_add_radial_gradient_node (GskGpuNodeProcessor *self,
static void
gsk_gpu_node_processor_conic_gradient_op (GskGpuNodeProcessor *self,
GdkColorState *target,
GskRenderNode *node,
const GskColorStop2 *stops,
gsize n_stops)
{
gsk_gpu_conic_gradient_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
self->ccs,
target,
self->opacity,
&self->offset,
gsk_conic_gradient_node_get_interpolation_color_state (node),
@@ -2652,6 +2688,7 @@ gsk_gpu_node_processor_add_conic_gradient_node (GskGpuNodeProcessor *self,
{
gsk_gpu_node_processor_add_gradient_node (self,
node,
gsk_conic_gradient_node_get_interpolation_color_state (node),
gsk_conic_gradient_node_get_color_stops2 (node),
gsk_conic_gradient_node_get_n_color_stops (node),
gsk_gpu_node_processor_conic_gradient_op);
@@ -4499,4 +4536,3 @@ gsk_gpu_node_processor_convert_image (GskGpuFrame *frame,
return converted;
}