mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-06 02:40:07 +00:00
a78796f22c
This shader converts between two color states, by using the same functions that we use on the cpu. The conversion to perform is passed as part of the variation. As premultiplication is part of color states on the shader, we also encode the premultiplication in the shader. And because opacity is a useful optimization, we also allow setting opacity. For now, the only possible color states are srgb and srgb-linear.
152 lines
4.3 KiB
C
152 lines
4.3 KiB
C
#pragma once
|
|
|
|
#include "gdkcolorstate.h"
|
|
|
|
#include "gdkdebugprivate.h"
|
|
#include "gdkmemoryformatprivate.h"
|
|
#include "gdkrgba.h"
|
|
|
|
typedef enum
|
|
{
|
|
GDK_COLOR_STATE_ID_SRGB,
|
|
GDK_COLOR_STATE_ID_SRGB_LINEAR,
|
|
|
|
GDK_COLOR_STATE_N_IDS
|
|
} GdkColorStateId;
|
|
|
|
typedef struct _GdkColorStateClass GdkColorStateClass;
|
|
|
|
struct _GdkColorState
|
|
{
|
|
const GdkColorStateClass *klass;
|
|
gatomicrefcount ref_count;
|
|
|
|
GdkMemoryDepth depth;
|
|
GdkColorState *rendering_color_state;
|
|
};
|
|
|
|
typedef void (* GdkFloatColorConvert)(GdkColorState *self,
|
|
float (*values)[4],
|
|
gsize n_values);
|
|
|
|
struct _GdkColorStateClass
|
|
{
|
|
void (* free) (GdkColorState *self);
|
|
gboolean (* equal) (GdkColorState *self,
|
|
GdkColorState *other);
|
|
const char * (* get_name) (GdkColorState *self);
|
|
GdkColorState * (* get_no_srgb_tf) (GdkColorState *self);
|
|
GdkFloatColorConvert (* get_convert_to) (GdkColorState *self,
|
|
GdkColorState *target);
|
|
};
|
|
|
|
typedef struct _GdkDefaultColorState GdkDefaultColorState;
|
|
|
|
struct _GdkDefaultColorState
|
|
{
|
|
GdkColorState parent;
|
|
|
|
const char *name;
|
|
GdkColorState *no_srgb;
|
|
GdkFloatColorConvert convert_to[GDK_COLOR_STATE_N_IDS];
|
|
};
|
|
|
|
extern GdkDefaultColorState gdk_default_color_states[GDK_COLOR_STATE_N_IDS];
|
|
|
|
#define GDK_COLOR_STATE_SRGB ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB])
|
|
#define GDK_COLOR_STATE_SRGB_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB_LINEAR])
|
|
|
|
#define GDK_IS_DEFAULT_COLOR_STATE(c) ((GdkDefaultColorState *) (c) >= &gdk_default_color_states[0] && \
|
|
(GdkDefaultColorState *) (c) < &gdk_default_color_states[GDK_COLOR_STATE_N_IDS])
|
|
#define GDK_DEFAULT_COLOR_STATE_ID(c) ((GdkColorStateId) (((GdkDefaultColorState *) c) - gdk_default_color_states))
|
|
|
|
const char * gdk_color_state_get_name (GdkColorState *color_state);
|
|
GdkColorState * gdk_color_state_get_no_srgb_tf (GdkColorState *self);
|
|
|
|
static inline GdkColorState *
|
|
gdk_color_state_get_rendering_color_state (GdkColorState *self)
|
|
{
|
|
if (!GDK_DEBUG_CHECK (LINEAR))
|
|
return self;
|
|
|
|
return self->rendering_color_state;
|
|
}
|
|
|
|
static inline GdkMemoryDepth
|
|
gdk_color_state_get_depth (GdkColorState *self)
|
|
{
|
|
if (!GDK_DEBUG_CHECK (LINEAR) && self->depth == GDK_MEMORY_U8_SRGB)
|
|
return GDK_MEMORY_U8;
|
|
|
|
return self->depth;
|
|
}
|
|
|
|
static inline GdkColorState *
|
|
gdk_color_state_get_by_id (GdkColorStateId id)
|
|
{
|
|
return (GdkColorState *) &gdk_default_color_states[id];
|
|
}
|
|
|
|
#define gdk_color_state_ref(self) _gdk_color_state_ref (self)
|
|
static inline GdkColorState *
|
|
_gdk_color_state_ref (GdkColorState *self)
|
|
{
|
|
if (GDK_IS_DEFAULT_COLOR_STATE (self))
|
|
return self;
|
|
|
|
g_atomic_ref_count_inc (&self->ref_count);
|
|
|
|
return self;
|
|
}
|
|
|
|
#define gdk_color_state_unref(self) _gdk_color_state_unref (self)
|
|
static inline void
|
|
_gdk_color_state_unref (GdkColorState *self)
|
|
{
|
|
if (GDK_IS_DEFAULT_COLOR_STATE (self))
|
|
return;
|
|
|
|
if (g_atomic_ref_count_dec (&self->ref_count))
|
|
self->klass->free (self);
|
|
}
|
|
|
|
#define gdk_color_state_equal(a,b) _gdk_color_state_equal ((a), (b))
|
|
static inline gboolean
|
|
_gdk_color_state_equal (GdkColorState *self,
|
|
GdkColorState *other)
|
|
{
|
|
if (self == other)
|
|
return TRUE;
|
|
|
|
if (self->klass != other->klass)
|
|
return FALSE;
|
|
|
|
return self->klass->equal (self, other);
|
|
}
|
|
|
|
static inline GdkFloatColorConvert
|
|
gdk_color_state_get_convert_to (GdkColorState *self,
|
|
GdkColorState *target)
|
|
{
|
|
return self->klass->get_convert_to (self, target);
|
|
}
|
|
|
|
static inline void
|
|
gdk_color_state_from_rgba (GdkColorState *self,
|
|
const GdkRGBA *rgba,
|
|
float out_color[4])
|
|
{
|
|
GdkFloatColorConvert convert_to;
|
|
|
|
out_color[0] = rgba->red;
|
|
out_color[1] = rgba->green;
|
|
out_color[2] = rgba->blue;
|
|
out_color[3] = rgba->alpha;
|
|
|
|
if (gdk_color_state_equal (GDK_COLOR_STATE_SRGB, self))
|
|
return;
|
|
|
|
convert_to = gdk_color_state_get_convert_to (GDK_COLOR_STATE_SRGB, self);
|
|
convert_to (GDK_COLOR_STATE_SRGB, (float(*)[4]) out_color, 1);
|
|
}
|