mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 13:11:13 +00:00
gpu: Port convert op to GskGpuColorStates
Make it handle straight alpha, too, by checking if the alt colorspace is premultiplied - which is the colorspace of the source.
This commit is contained in:
parent
88dc49a5b6
commit
f65d4914e4
@ -17,74 +17,19 @@ struct _GskGpuConvertOp
|
||||
};
|
||||
|
||||
#define VARIATION_OPACITY (1u << 0)
|
||||
#define VARIATION_ALPHA_ALL_CHANNELS (1u << 1)
|
||||
#define VARIATION_SOURCE_UNPREMULTIPLY (1u << 2)
|
||||
#define VARIATION_TARGET_PREMULTIPLY (1u << 3)
|
||||
#define VARIATION_SOURCE_SHIFT 8u
|
||||
#define VARIATION_TARGET_SHIFT 16u
|
||||
#define VARIATION_COLOR_STATE_MASK 0xFFu
|
||||
|
||||
static guint
|
||||
gsk_gpu_convert_encode_variation (GdkColorState *source,
|
||||
gboolean source_premultiplied,
|
||||
GdkColorState *target,
|
||||
gboolean target_premultiplied,
|
||||
gboolean opacity)
|
||||
{
|
||||
guint conversion;
|
||||
|
||||
if (source == target)
|
||||
{
|
||||
if (source_premultiplied == target_premultiplied)
|
||||
{
|
||||
/* no changes should be caught before running a shader */
|
||||
g_assert (opacity);
|
||||
if (source_premultiplied)
|
||||
conversion = VARIATION_ALPHA_ALL_CHANNELS;
|
||||
else
|
||||
conversion = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (source_premultiplied)
|
||||
conversion = VARIATION_SOURCE_UNPREMULTIPLY;
|
||||
else
|
||||
conversion = VARIATION_TARGET_PREMULTIPLY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
conversion = GDK_DEFAULT_COLOR_STATE_ID (source) << VARIATION_SOURCE_SHIFT;
|
||||
conversion |= GDK_DEFAULT_COLOR_STATE_ID (target) << VARIATION_TARGET_SHIFT;
|
||||
if (source_premultiplied)
|
||||
conversion |= VARIATION_SOURCE_UNPREMULTIPLY;
|
||||
if (target_premultiplied)
|
||||
conversion |= VARIATION_TARGET_PREMULTIPLY;
|
||||
}
|
||||
|
||||
if (opacity)
|
||||
conversion |= VARIATION_OPACITY;
|
||||
|
||||
return conversion;
|
||||
}
|
||||
#define VARIATION_STRAIGHT_ALPHA (1u << 1)
|
||||
|
||||
static void
|
||||
gsk_gpu_convert_op_print_instance (GskGpuShaderOp *shader,
|
||||
gpointer instance_,
|
||||
GString *string)
|
||||
gpointer instance_,
|
||||
GString *string)
|
||||
{
|
||||
GskGpuConvertInstance *instance = (GskGpuConvertInstance *) instance_;
|
||||
GdkColorState *source, *target;
|
||||
|
||||
source = gdk_color_state_get_by_id ((shader->variation >> VARIATION_SOURCE_SHIFT) & VARIATION_COLOR_STATE_MASK);
|
||||
target = gdk_color_state_get_by_id ((shader->variation >> VARIATION_TARGET_SHIFT) & VARIATION_COLOR_STATE_MASK);
|
||||
gsk_gpu_print_rect (string, instance->rect);
|
||||
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
|
||||
g_string_append_printf (string, "%s%s -> %s%s ",
|
||||
gdk_color_state_get_name (source),
|
||||
(shader->variation & VARIATION_SOURCE_UNPREMULTIPLY) ? "(p)" : "",
|
||||
gdk_color_state_get_name (target),
|
||||
(shader->variation & VARIATION_TARGET_PREMULTIPLY) ? "(p)" : "");
|
||||
if (shader->variation & VARIATION_STRAIGHT_ALPHA)
|
||||
gsk_gpu_print_string (string, "straight");
|
||||
}
|
||||
|
||||
static const GskGpuShaderOpClass GSK_GPU_CONVERT_OP_CLASS = {
|
||||
@ -111,30 +56,22 @@ static const GskGpuShaderOpClass GSK_GPU_CONVERT_OP_CLASS = {
|
||||
void
|
||||
gsk_gpu_convert_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GdkColorState *source,
|
||||
gboolean source_premultiplied,
|
||||
GdkColorState *target,
|
||||
gboolean target_premultiplied,
|
||||
GskGpuColorStates color_states,
|
||||
float opacity,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
gboolean straight_alpha,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect)
|
||||
{
|
||||
GskGpuConvertInstance *instance;
|
||||
guint variation;
|
||||
|
||||
variation = gsk_gpu_convert_encode_variation (source,
|
||||
source_premultiplied,
|
||||
target,
|
||||
target_premultiplied,
|
||||
opacity < 1.0);
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_CONVERT_OP_CLASS,
|
||||
DEFAULT_COLOR_STATES,
|
||||
variation,
|
||||
color_states,
|
||||
(opacity < 1.0 ? VARIATION_OPACITY : 0) |
|
||||
(straight_alpha ? VARIATION_STRAIGHT_ALPHA : 0),
|
||||
clip,
|
||||
desc,
|
||||
&instance);
|
||||
|
@ -8,13 +8,11 @@ G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_convert_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GdkColorState *from,
|
||||
gboolean from_premultiplied,
|
||||
GdkColorState *to,
|
||||
gboolean to_premultiplied,
|
||||
GskGpuColorStates color_states,
|
||||
float opacity,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
gboolean straight_alpha,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect);
|
||||
|
@ -247,6 +247,14 @@ gsk_gpu_node_processor_sync_globals (GskGpuNodeProcessor *self,
|
||||
gsk_gpu_node_processor_emit_blend_op (self);
|
||||
}
|
||||
|
||||
static inline GskGpuColorStates
|
||||
gsk_gpu_node_processor_color_states_self (GskGpuNodeProcessor *self)
|
||||
{
|
||||
return gsk_gpu_color_states_create (self->ccs,
|
||||
TRUE,
|
||||
self->ccs,
|
||||
TRUE);
|
||||
}
|
||||
static guint32
|
||||
gsk_gpu_node_processor_add_image (GskGpuNodeProcessor *self,
|
||||
GskGpuImage *image,
|
||||
@ -559,22 +567,22 @@ gsk_gpu_node_processor_image_op (GskGpuNodeProcessor *self,
|
||||
const graphene_rect_t *tex_rect)
|
||||
{
|
||||
guint32 descriptor;
|
||||
gboolean straight_alpha;
|
||||
|
||||
g_assert (self->pending_globals == 0);
|
||||
|
||||
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
|
||||
straight_alpha = gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA;
|
||||
|
||||
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA)
|
||||
if (straight_alpha)
|
||||
{
|
||||
gsk_gpu_convert_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, rect),
|
||||
GDK_COLOR_STATE_SRGB,
|
||||
FALSE,
|
||||
GDK_COLOR_STATE_SRGB,
|
||||
TRUE,
|
||||
gsk_gpu_node_processor_color_states_self (self),
|
||||
self->opacity,
|
||||
self->desc,
|
||||
descriptor,
|
||||
straight_alpha,
|
||||
rect,
|
||||
&self->offset,
|
||||
tex_rect);
|
||||
|
@ -1,74 +1,10 @@
|
||||
#include "common.glsl"
|
||||
|
||||
#define VARIATION_OPACITY (1u << 0)
|
||||
#define VARIATION_ALPHA_ALL_CHANNELS (1u << 1)
|
||||
#define VARIATION_SOURCE_UNPREMULTIPLY (1u << 2)
|
||||
#define VARIATION_TARGET_PREMULTIPLY (1u << 3)
|
||||
#define VARIATION_SOURCE_SHIFT 8u
|
||||
#define VARIATION_TARGET_SHIFT 16u
|
||||
#define VARIATION_COLOR_STATE_MASK 0xFFu
|
||||
#define VARIATION_STRAIGHT_ALPHA (1u << 1)
|
||||
|
||||
#define HAS_VARIATION(var) ((GSK_VARIATION & var) == var)
|
||||
|
||||
#define SOURCE_COLOR_STATE ((GSK_VARIATION >> VARIATION_SOURCE_SHIFT) & VARIATION_COLOR_STATE_MASK)
|
||||
#define TARGET_COLOR_STATE ((GSK_VARIATION >> VARIATION_TARGET_SHIFT) & VARIATION_COLOR_STATE_MASK)
|
||||
|
||||
vec4
|
||||
srgb_to_linear_srgb (vec4 color)
|
||||
{
|
||||
return vec4 (srgb_eotf (color.r),
|
||||
srgb_eotf (color.g),
|
||||
srgb_eotf (color.b),
|
||||
color.a);
|
||||
}
|
||||
|
||||
vec4
|
||||
linear_srgb_to_srgb (vec4 color)
|
||||
{
|
||||
return vec4 (srgb_oetf (color.r),
|
||||
srgb_oetf (color.g),
|
||||
srgb_oetf (color.b),
|
||||
color.a);
|
||||
}
|
||||
|
||||
#define PAIR(_from_cs, _to_cs) ((_from_cs) << 16 | (_to_cs))
|
||||
|
||||
bool
|
||||
do_conversion (vec4 color,
|
||||
uint from_cs,
|
||||
uint to_cs,
|
||||
out vec4 result)
|
||||
{
|
||||
switch (PAIR (from_cs, to_cs))
|
||||
{
|
||||
case PAIR (GDK_COLOR_STATE_ID_SRGB, GDK_COLOR_STATE_ID_SRGB_LINEAR):
|
||||
result = srgb_to_linear_srgb (color);
|
||||
break;
|
||||
case PAIR (GDK_COLOR_STATE_ID_SRGB_LINEAR, GDK_COLOR_STATE_ID_SRGB):
|
||||
result = linear_srgb_to_srgb (color);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
vec4
|
||||
color_convert (vec4 color)
|
||||
{
|
||||
vec4 result;
|
||||
|
||||
if (SOURCE_COLOR_STATE == TARGET_COLOR_STATE)
|
||||
return color;
|
||||
|
||||
if (!do_conversion (color, SOURCE_COLOR_STATE, TARGET_COLOR_STATE, result))
|
||||
result = vec4 (1.0, 0.0, 0.8, 1.0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PASS(0) vec2 _pos;
|
||||
PASS_FLAT(1) Rect _rect;
|
||||
PASS(2) vec2 _tex_coord;
|
||||
@ -106,26 +42,19 @@ void
|
||||
run (out vec4 color,
|
||||
out vec2 position)
|
||||
{
|
||||
vec4 pixel = gsk_texture (_tex_id, _tex_coord);
|
||||
vec4 pixel;
|
||||
if (HAS_VARIATION (VARIATION_STRAIGHT_ALPHA))
|
||||
pixel = gsk_texture_straight_alpha (_tex_id, _tex_coord);
|
||||
else
|
||||
pixel = gsk_texture (_tex_id, _tex_coord);
|
||||
|
||||
if (HAS_VARIATION (VARIATION_SOURCE_UNPREMULTIPLY))
|
||||
pixel = color_unpremultiply (pixel);
|
||||
|
||||
pixel = color_convert (pixel);
|
||||
pixel = output_color_from_alt (pixel);
|
||||
|
||||
float alpha = rect_coverage (_rect, _pos);
|
||||
if (HAS_VARIATION (VARIATION_OPACITY))
|
||||
alpha *= _opacity;
|
||||
|
||||
if (HAS_VARIATION (VARIATION_ALPHA_ALL_CHANNELS))
|
||||
pixel *= alpha;
|
||||
else
|
||||
pixel.a *= alpha;
|
||||
|
||||
if (HAS_VARIATION (VARIATION_TARGET_PREMULTIPLY))
|
||||
color = color_premultiply (pixel);
|
||||
else
|
||||
color = pixel;
|
||||
color = output_color_alpha (pixel, alpha);
|
||||
|
||||
position = _pos;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user