mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 05:31:07 +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_OPACITY (1u << 0)
|
||||||
#define VARIATION_ALPHA_ALL_CHANNELS (1u << 1)
|
#define VARIATION_STRAIGHT_ALPHA (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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_gpu_convert_op_print_instance (GskGpuShaderOp *shader,
|
gsk_gpu_convert_op_print_instance (GskGpuShaderOp *shader,
|
||||||
gpointer instance_,
|
gpointer instance_,
|
||||||
GString *string)
|
GString *string)
|
||||||
{
|
{
|
||||||
GskGpuConvertInstance *instance = (GskGpuConvertInstance *) instance_;
|
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_rect (string, instance->rect);
|
||||||
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
|
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
|
||||||
g_string_append_printf (string, "%s%s -> %s%s ",
|
if (shader->variation & VARIATION_STRAIGHT_ALPHA)
|
||||||
gdk_color_state_get_name (source),
|
gsk_gpu_print_string (string, "straight");
|
||||||
(shader->variation & VARIATION_SOURCE_UNPREMULTIPLY) ? "(p)" : "",
|
|
||||||
gdk_color_state_get_name (target),
|
|
||||||
(shader->variation & VARIATION_TARGET_PREMULTIPLY) ? "(p)" : "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GskGpuShaderOpClass GSK_GPU_CONVERT_OP_CLASS = {
|
static const GskGpuShaderOpClass GSK_GPU_CONVERT_OP_CLASS = {
|
||||||
@ -111,30 +56,22 @@ static const GskGpuShaderOpClass GSK_GPU_CONVERT_OP_CLASS = {
|
|||||||
void
|
void
|
||||||
gsk_gpu_convert_op (GskGpuFrame *frame,
|
gsk_gpu_convert_op (GskGpuFrame *frame,
|
||||||
GskGpuShaderClip clip,
|
GskGpuShaderClip clip,
|
||||||
GdkColorState *source,
|
GskGpuColorStates color_states,
|
||||||
gboolean source_premultiplied,
|
|
||||||
GdkColorState *target,
|
|
||||||
gboolean target_premultiplied,
|
|
||||||
float opacity,
|
float opacity,
|
||||||
GskGpuDescriptors *desc,
|
GskGpuDescriptors *desc,
|
||||||
guint32 descriptor,
|
guint32 descriptor,
|
||||||
|
gboolean straight_alpha,
|
||||||
const graphene_rect_t *rect,
|
const graphene_rect_t *rect,
|
||||||
const graphene_point_t *offset,
|
const graphene_point_t *offset,
|
||||||
const graphene_rect_t *tex_rect)
|
const graphene_rect_t *tex_rect)
|
||||||
{
|
{
|
||||||
GskGpuConvertInstance *instance;
|
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_shader_op_alloc (frame,
|
||||||
&GSK_GPU_CONVERT_OP_CLASS,
|
&GSK_GPU_CONVERT_OP_CLASS,
|
||||||
DEFAULT_COLOR_STATES,
|
color_states,
|
||||||
variation,
|
(opacity < 1.0 ? VARIATION_OPACITY : 0) |
|
||||||
|
(straight_alpha ? VARIATION_STRAIGHT_ALPHA : 0),
|
||||||
clip,
|
clip,
|
||||||
desc,
|
desc,
|
||||||
&instance);
|
&instance);
|
||||||
|
@ -8,13 +8,11 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
void gsk_gpu_convert_op (GskGpuFrame *frame,
|
void gsk_gpu_convert_op (GskGpuFrame *frame,
|
||||||
GskGpuShaderClip clip,
|
GskGpuShaderClip clip,
|
||||||
GdkColorState *from,
|
GskGpuColorStates color_states,
|
||||||
gboolean from_premultiplied,
|
|
||||||
GdkColorState *to,
|
|
||||||
gboolean to_premultiplied,
|
|
||||||
float opacity,
|
float opacity,
|
||||||
GskGpuDescriptors *desc,
|
GskGpuDescriptors *desc,
|
||||||
guint32 descriptor,
|
guint32 descriptor,
|
||||||
|
gboolean straight_alpha,
|
||||||
const graphene_rect_t *rect,
|
const graphene_rect_t *rect,
|
||||||
const graphene_point_t *offset,
|
const graphene_point_t *offset,
|
||||||
const graphene_rect_t *tex_rect);
|
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);
|
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
|
static guint32
|
||||||
gsk_gpu_node_processor_add_image (GskGpuNodeProcessor *self,
|
gsk_gpu_node_processor_add_image (GskGpuNodeProcessor *self,
|
||||||
GskGpuImage *image,
|
GskGpuImage *image,
|
||||||
@ -559,22 +567,22 @@ gsk_gpu_node_processor_image_op (GskGpuNodeProcessor *self,
|
|||||||
const graphene_rect_t *tex_rect)
|
const graphene_rect_t *tex_rect)
|
||||||
{
|
{
|
||||||
guint32 descriptor;
|
guint32 descriptor;
|
||||||
|
gboolean straight_alpha;
|
||||||
|
|
||||||
g_assert (self->pending_globals == 0);
|
g_assert (self->pending_globals == 0);
|
||||||
|
|
||||||
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
|
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_convert_op (self->frame,
|
||||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, rect),
|
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, rect),
|
||||||
GDK_COLOR_STATE_SRGB,
|
gsk_gpu_node_processor_color_states_self (self),
|
||||||
FALSE,
|
|
||||||
GDK_COLOR_STATE_SRGB,
|
|
||||||
TRUE,
|
|
||||||
self->opacity,
|
self->opacity,
|
||||||
self->desc,
|
self->desc,
|
||||||
descriptor,
|
descriptor,
|
||||||
|
straight_alpha,
|
||||||
rect,
|
rect,
|
||||||
&self->offset,
|
&self->offset,
|
||||||
tex_rect);
|
tex_rect);
|
||||||
|
@ -1,74 +1,10 @@
|
|||||||
#include "common.glsl"
|
#include "common.glsl"
|
||||||
|
|
||||||
#define VARIATION_OPACITY (1u << 0)
|
#define VARIATION_OPACITY (1u << 0)
|
||||||
#define VARIATION_ALPHA_ALL_CHANNELS (1u << 1)
|
#define VARIATION_STRAIGHT_ALPHA (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 HAS_VARIATION(var) ((GSK_VARIATION & var) == var)
|
#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(0) vec2 _pos;
|
||||||
PASS_FLAT(1) Rect _rect;
|
PASS_FLAT(1) Rect _rect;
|
||||||
PASS(2) vec2 _tex_coord;
|
PASS(2) vec2 _tex_coord;
|
||||||
@ -106,26 +42,19 @@ void
|
|||||||
run (out vec4 color,
|
run (out vec4 color,
|
||||||
out vec2 position)
|
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 = output_color_from_alt (pixel);
|
||||||
pixel = color_unpremultiply (pixel);
|
|
||||||
|
|
||||||
pixel = color_convert (pixel);
|
|
||||||
|
|
||||||
float alpha = rect_coverage (_rect, _pos);
|
float alpha = rect_coverage (_rect, _pos);
|
||||||
if (HAS_VARIATION (VARIATION_OPACITY))
|
if (HAS_VARIATION (VARIATION_OPACITY))
|
||||||
alpha *= _opacity;
|
alpha *= _opacity;
|
||||||
|
|
||||||
if (HAS_VARIATION (VARIATION_ALPHA_ALL_CHANNELS))
|
color = output_color_alpha (pixel, alpha);
|
||||||
pixel *= alpha;
|
|
||||||
else
|
|
||||||
pixel.a *= alpha;
|
|
||||||
|
|
||||||
if (HAS_VARIATION (VARIATION_TARGET_PREMULTIPLY))
|
|
||||||
color = color_premultiply (pixel);
|
|
||||||
else
|
|
||||||
color = pixel;
|
|
||||||
|
|
||||||
position = _pos;
|
position = _pos;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user