gsk: Use the cicp convert shader

When we the image color state is not a default one, use the cicp
convert op to convert it to the ccs. And when the target color
state is a non-default one, use the shader in the reverse direction.
This commit is contained in:
Matthias Clasen 2024-07-16 23:53:25 -04:00
parent 226652edb0
commit e415ec9ca5
2 changed files with 70 additions and 15 deletions

View File

@ -38,6 +38,17 @@ gsk_gpu_color_states_create (GdkColorState *output_color_state,
(alt_is_premultiplied ? COLOR_SPACE_ALT_PREMULTIPLIED : 0);
}
static inline GskGpuColorStates
gsk_gpu_color_states_create_cicp (GdkColorState *output_color_state,
gboolean output_is_premultiplied,
gboolean cicp_is_premultiplied)
{
return (GDK_DEFAULT_COLOR_STATE_ID (output_color_state) << COLOR_SPACE_OUTPUT_SHIFT) |
(output_is_premultiplied ? COLOR_SPACE_OUTPUT_PREMULTIPLIED : 0) |
(GDK_DEFAULT_COLOR_STATE_ID (output_color_state) << COLOR_SPACE_ALT_SHIFT) |
(cicp_is_premultiplied ? COLOR_SPACE_ALT_PREMULTIPLIED : 0);
}
static inline GdkColorState *
gsk_gpu_color_states_get_output (GskGpuColorStates self)
{

View File

@ -16,6 +16,7 @@
#include "gskgpucoloropprivate.h"
#include "gskgpuconicgradientopprivate.h"
#include "gskgpuconvertopprivate.h"
#include "gskgpuconvertcicpopprivate.h"
#include "gskgpucrossfadeopprivate.h"
#include "gskgpudeviceprivate.h"
#include "gskgpuframeprivate.h"
@ -486,9 +487,29 @@ gsk_gpu_node_processor_image_op (GskGpuNodeProcessor *self,
straight_alpha = gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA;
if (straight_alpha ||
self->opacity < 1.0 ||
!gdk_color_state_equal (image_color_state, self->ccs))
if (!GDK_IS_DEFAULT_COLOR_STATE (image_color_state))
{
const GdkCicp *cicp = gdk_color_state_get_cicp (image_color_state);
g_assert (cicp != NULL);
gsk_gpu_convert_from_cicp_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, rect),
cicp,
gsk_gpu_color_states_create_cicp (self->ccs, TRUE, TRUE),
self->opacity,
straight_alpha,
&self->offset,
&(GskGpuShaderImage) {
image,
sampler,
rect,
tex_rect
});
}
else if (straight_alpha ||
self->opacity < 1.0 ||
!gdk_color_state_equal (image_color_state, self->ccs))
{
gsk_gpu_convert_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, rect),
@ -3910,18 +3931,41 @@ gsk_gpu_node_processor_process (GskGpuFrame *frame,
self.pending_globals |= GSK_GPU_GLOBAL_BLEND;
gsk_gpu_node_processor_sync_globals (&self, 0);
gsk_gpu_convert_op (self.frame,
gsk_gpu_clip_get_shader_clip (&self.clip, &self.offset, &node->bounds),
gsk_gpu_node_processor_color_states_explicit (&self, ccs, TRUE),
self.opacity,
FALSE,
&self.offset,
&(GskGpuShaderImage) {
image,
GSK_GPU_SAMPLER_DEFAULT,
&node->bounds,
&tex_rect
});
if (!GDK_IS_DEFAULT_COLOR_STATE (target_color_state))
{
const GdkCicp *cicp = gdk_color_state_get_cicp (target_color_state);
g_assert (cicp != NULL);
gsk_gpu_convert_to_cicp_op (self.frame,
gsk_gpu_clip_get_shader_clip (&self.clip, &self.offset, &node->bounds),
cicp,
gsk_gpu_color_states_create_cicp (self.ccs, TRUE, TRUE),
self.opacity,
FALSE,
&self.offset,
&(GskGpuShaderImage) {
image,
GSK_GPU_SAMPLER_DEFAULT,
&node->bounds,
&tex_rect
});
}
else
{
gsk_gpu_convert_op (self.frame,
gsk_gpu_clip_get_shader_clip (&self.clip, &self.offset, &node->bounds),
gsk_gpu_node_processor_color_states_explicit (&self, ccs, TRUE),
self.opacity,
FALSE,
&self.offset,
&(GskGpuShaderImage) {
image,
GSK_GPU_SAMPLER_DEFAULT,
&node->bounds,
&tex_rect
});
}
gsk_gpu_render_pass_end_op (frame,
target,