Merge branch 'wayland-color-states' into 'main'

Wayland color management

See merge request GNOME/gtk!7444
This commit is contained in:
Benjamin Otte
2024-07-14 19:46:56 +00:00
11 changed files with 1920 additions and 3 deletions

View File

@@ -52,6 +52,7 @@
#include "gdkprofilerprivate.h"
#include "gdkdihedralprivate.h"
#include "gdktoplevel-wayland-private.h"
#include "gdkwaylandcolor-private.h"
#include <wayland/pointer-gestures-unstable-v1-client-protocol.h>
#include "tablet-unstable-v2-client-protocol.h"
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
@@ -533,6 +534,10 @@ gdk_registry_handle_global (void *data,
&wp_presentation_interface,
MIN (version, 1));
}
else if (strcmp (interface, "xx_color_manager_v2") == 0)
{
display_wayland->color = gdk_wayland_color_new (registry, id, version);
}
else if (strcmp (interface, wp_single_pixel_buffer_manager_v1_interface.name) == 0)
{
display_wayland->single_pixel_buffer =
@@ -693,6 +698,12 @@ _gdk_wayland_display_open (const char *display_name)
return NULL;
}
if (display_wayland->color)
{
if (!gdk_wayland_color_prepare (display_wayland->color))
g_clear_pointer (&display_wayland->color, gdk_wayland_color_free );
}
gdk_display_emit_opened (display);
return display;
@@ -753,6 +764,7 @@ gdk_wayland_display_dispose (GObject *object)
g_clear_pointer (&display_wayland->single_pixel_buffer, wp_single_pixel_buffer_manager_v1_destroy);
g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
g_clear_pointer (&display_wayland->dmabuf_formats_info, dmabuf_formats_info_free);
g_clear_pointer (&display_wayland->color, gdk_wayland_color_free);
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);

View File

@@ -59,6 +59,7 @@ G_BEGIN_DECLS
#define GDK_ZWP_POINTER_GESTURES_V1_VERSION 3
typedef struct _GdkWaylandColor GdkWaylandColor;
typedef struct _GdkWaylandSelection GdkWaylandSelection;
typedef struct {
@@ -123,6 +124,7 @@ struct _GdkWaylandDisplay
struct wp_viewporter *viewporter;
struct wp_presentation *presentation;
struct wp_single_pixel_buffer_manager_v1 *single_pixel_buffer;
GdkWaylandColor *color;
GList *async_roundtrips;

View File

@@ -2,6 +2,7 @@
#include "gdksubsurfaceprivate.h"
#include "gdkwaylandcolor-private.h"
#include "wayland-client-protocol.h"
typedef struct _GdkWaylandSubsurface GdkWaylandSubsurface;
@@ -20,6 +21,7 @@ struct _GdkWaylandSubsurface
struct wl_surface *surface;
struct wl_subsurface *subsurface;
struct wp_viewport *viewport;
GdkWaylandColorSurface *color;
GdkTexture *texture;
cairo_rectangle_int_t dest;

View File

@@ -48,6 +48,7 @@ gdk_wayland_subsurface_finalize (GObject *object)
g_clear_pointer (&self->frame_callback, wl_callback_destroy);
g_clear_pointer (&self->opaque_region, wl_region_destroy);
g_clear_pointer (&self->viewport, wp_viewport_destroy);
g_clear_pointer (&self->color, gdk_wayland_color_surface_free);
g_clear_pointer (&self->subsurface, wl_subsurface_destroy);
g_clear_pointer (&self->surface, wl_surface_destroy);
g_clear_pointer (&self->bg_viewport, wp_viewport_destroy);
@@ -411,6 +412,7 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
gboolean needs_commit = FALSE;
gboolean background_changed = FALSE;
gboolean needs_bg_commit = FALSE;
gboolean color_state_changed = FALSE;
if (sibling)
will_be_above = sibling->above_parent;
@@ -542,6 +544,14 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
"[%p] 🗙 Texture has background, but no single-pixel buffer support",
self);
}
else if (self->color &&
!gdk_wayland_color_surface_can_set_color_state (self->color, gdk_texture_get_color_state (texture)))
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
"[%p] 🗙 Texture colorstate %s not supported",
self,
gdk_color_state_get_name (gdk_texture_get_color_state (texture)));
}
else
{
gboolean was_transparent;
@@ -551,6 +561,12 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
else
was_transparent = FALSE;
if (self->texture && texture)
color_state_changed = !gdk_color_state_equal (gdk_texture_get_color_state (self->texture),
gdk_texture_get_color_state (texture));
else
color_state_changed = TRUE;
if (g_set_object (&self->texture, texture))
{
buffer = get_wl_buffer (self, texture);
@@ -568,7 +584,7 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
}
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
"[%p] %s Attaching %s (%dx%d) at %d %d %d %d%s%s%s",
"[%p] %s Attaching %s (%dx%d, %s) at %d %d %d %d%s%s%s",
self,
G_OBJECT_TYPE_NAME (texture),
will_be_above
@@ -576,11 +592,12 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
: (has_background ? "" : ""),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
gdk_color_state_get_name (gdk_texture_get_color_state (texture)),
self->dest.x, self->dest.y,
self->dest.width, self->dest.height,
transform != GDK_DIHEDRAL_NORMAL ? " (" : "",
transform != GDK_DIHEDRAL_NORMAL ? gdk_dihedral_get_name (transform) : "",
transform != GDK_DIHEDRAL_NORMAL ? " )" : ""
transform != GDK_DIHEDRAL_NORMAL ? ")" : ""
);
result = TRUE;
}
@@ -643,6 +660,10 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
0, 0,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
if (self->color && color_state_changed)
gdk_wayland_color_surface_set_color_state (self->color, gdk_texture_get_color_state (texture));
needs_commit = TRUE;
}
@@ -891,6 +912,9 @@ gdk_wayland_surface_create_subsurface (GdkSurface *surface)
sub->subsurface = wl_subcompositor_get_subsurface (disp->subcompositor,
sub->surface,
impl->display_server.wl_surface);
if (disp->color)
sub->color = gdk_wayland_color_surface_new (disp->color, sub->surface, NULL, NULL);
sub->viewport = wp_viewporter_get_viewport (disp->viewporter, sub->surface);
/* No input, please */

View File

@@ -18,6 +18,7 @@
#pragma once
#include "gdkprivate-wayland.h"
#include "gdkwaylandcolor-private.h"
typedef enum _PopupState
{
@@ -39,6 +40,7 @@ struct _GdkWaylandSurface
struct wl_egl_window *egl_window;
struct wp_fractional_scale_v1 *fractional_scale;
struct wp_viewport *viewport;
GdkWaylandColorSurface *color;
} display_server;
struct wl_event_queue *event_queue;

View File

@@ -56,7 +56,6 @@
#include "gsk/gskrectprivate.h"
/**
* GdkWaylandSurface:
*
@@ -906,6 +905,14 @@ static const struct wl_surface_listener surface_listener = {
surface_preferred_buffer_transform,
};
static void
preferred_changed (GdkWaylandColorSurface *color,
GdkColorState *color_state,
gpointer data)
{
gdk_surface_set_color_state (GDK_SURFACE (data), color_state);
}
static void
gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
{
@@ -930,6 +937,12 @@ gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
wp_viewporter_get_viewport (display_wayland->viewporter, wl_surface);
}
if (display_wayland->color)
self->display_server.color = gdk_wayland_color_surface_new (display_wayland->color,
wl_surface,
preferred_changed,
self);
self->display_server.wl_surface = wl_surface;
}
@@ -983,6 +996,7 @@ gdk_wayland_surface_destroy_wl_surface (GdkWaylandSurface *self)
g_clear_pointer (&self->display_server.viewport, wp_viewport_destroy);
g_clear_pointer (&self->display_server.fractional_scale, wp_fractional_scale_v1_destroy);
g_clear_pointer (&self->display_server.color, gdk_wayland_color_surface_free);
g_clear_pointer (&self->display_server.wl_surface, wl_surface_destroy);

View File

@@ -0,0 +1,37 @@
#pragma once
#include "gdkcolorstateprivate.h"
#include <wayland-client.h>
typedef struct _GdkWaylandColor GdkWaylandColor;
GdkWaylandColor * gdk_wayland_color_new (struct wl_registry *registry,
uint32_t id,
uint32_t version);
void gdk_wayland_color_free (GdkWaylandColor *color);
gboolean gdk_wayland_color_prepare (GdkWaylandColor *color);
struct wl_proxy * gdk_wayland_color_get_color_manager (GdkWaylandColor *color);
typedef struct _GdkWaylandColorSurface GdkWaylandColorSurface;
typedef void (* GdkColorStateChanged) (GdkWaylandColorSurface *self,
GdkColorState *cs,
gpointer data);
GdkWaylandColorSurface *
gdk_wayland_color_surface_new (GdkWaylandColor *color,
struct wl_surface *wl_surface,
GdkColorStateChanged callback,
gpointer data);
void gdk_wayland_color_surface_free (GdkWaylandColorSurface *self);
void gdk_wayland_color_surface_set_color_state (GdkWaylandColorSurface *self,
GdkColorState *cs);
gboolean gdk_wayland_color_surface_can_set_color_state (GdkWaylandColorSurface *self,
GdkColorState *cs);

View File

@@ -0,0 +1,583 @@
#include "config.h"
#include "gdkwaylandcolor-private.h"
#include "gdksurface-wayland-private.h"
#include <gdk/wayland/xx-color-management-v2-client-protocol.h>
struct _GdkWaylandColor
{
struct xx_color_manager_v2 *color_manager;
struct {
unsigned int intents;
unsigned int features;
unsigned int transfers;
unsigned int primaries;
} color_manager_supported;
struct xx_image_description_v2 *srgb;
struct xx_image_description_v2 *srgb_linear;
struct xx_image_description_v2 *rec2100_pq;
struct xx_image_description_v2 *rec2100_linear;
};
static void
xx_color_manager_v2_supported_intent (void *data,
struct xx_color_manager_v2 *xx_color_manager_v2,
uint32_t render_intent)
{
GdkWaylandColor *color = data;
color->color_manager_supported.intents |= (1 << render_intent);
}
static void
xx_color_manager_v2_supported_feature (void *data,
struct xx_color_manager_v2 *xx_color_manager_v2,
uint32_t feature)
{
GdkWaylandColor *color = data;
color->color_manager_supported.features |= (1 << feature);
}
static void
xx_color_manager_v2_supported_tf_named (void *data,
struct xx_color_manager_v2 *xx_color_manager_v2,
uint32_t tf)
{
GdkWaylandColor *color = data;
color->color_manager_supported.transfers |= (1 << tf);
}
static void
xx_color_manager_v2_supported_primaries_named (void *data,
struct xx_color_manager_v2 *xx_color_manager_v2,
uint32_t primaries)
{
GdkWaylandColor *color = data;
color->color_manager_supported.primaries |= (1 << primaries);
}
static struct xx_color_manager_v2_listener color_manager_listener = {
xx_color_manager_v2_supported_intent,
xx_color_manager_v2_supported_feature,
xx_color_manager_v2_supported_tf_named,
xx_color_manager_v2_supported_primaries_named,
};
GdkWaylandColor *
gdk_wayland_color_new (struct wl_registry *registry,
uint32_t id,
uint32_t version)
{
GdkWaylandColor *color;
color = g_new0 (GdkWaylandColor, 1);
color->color_manager = wl_registry_bind (registry,
id,
&xx_color_manager_v2_interface,
MIN (version, 2));
xx_color_manager_v2_add_listener (color->color_manager,
&color_manager_listener,
color);
return color;
}
void
gdk_wayland_color_free (GdkWaylandColor *color)
{
g_clear_pointer (&color->color_manager, xx_color_manager_v2_destroy);
g_clear_pointer (&color->srgb, xx_image_description_v2_destroy);
g_clear_pointer (&color->srgb_linear, xx_image_description_v2_destroy);
g_clear_pointer (&color->rec2100_pq, xx_image_description_v2_destroy);
g_clear_pointer (&color->rec2100_linear, xx_image_description_v2_destroy);
g_free (color);
}
struct wl_proxy *
gdk_wayland_color_get_color_manager (GdkWaylandColor *color)
{
return (struct wl_proxy *) color->color_manager;
}
static void
std_image_desc_failed (void *data,
struct xx_image_description_v2 *desc,
uint32_t cause,
const char *msg)
{
g_warning ("Failed to get one of the standard image descriptions: %s", msg);
xx_image_description_v2_destroy (desc);
}
static void
std_image_desc_ready (void *data,
struct xx_image_description_v2 *desc,
uint32_t identity)
{
struct xx_image_description_v2 **ptr = data;
*ptr = desc;
}
static struct xx_image_description_v2_listener std_image_desc_listener = {
std_image_desc_failed,
std_image_desc_ready,
};
static void
create_image_desc (GdkWaylandColor *color,
uint32_t primaries,
uint32_t tf,
struct xx_image_description_v2 **out_desc)
{
struct xx_image_description_creator_params_v2 *creator;
struct xx_image_description_v2 *desc;
creator = xx_color_manager_v2_new_parametric_creator (color->color_manager);
xx_image_description_creator_params_v2_set_primaries_named (creator, primaries);
xx_image_description_creator_params_v2_set_tf_named (creator, tf);
desc = xx_image_description_creator_params_v2_create (creator);
xx_image_description_v2_add_listener (desc, &std_image_desc_listener, out_desc);
}
gboolean
gdk_wayland_color_prepare (GdkWaylandColor *color)
{
if (color->color_manager)
{
const char *intents[] = {
"perceptual", "relative", "saturation", "absolute", "relative-bpc"
};
const char *features[] = {
"icc-v2-v4", "parametric", "set-primaries", "set-tf-power",
"set-mastering-display-primaries", "extended-target-volume"
};
const char *tf[] = {
"bt709", "gamma22", "gamma28", "st240", "linear", "log100",
"log316", "xvycc", "bt1361", "srgb", "ext-srgb", "pq", "st428", "hlg"
};
const char *primaries[] = {
"srgb", "pal-m", "pal", "ntsc", "generic-film", "bt2020", "xyz",
"dci-p3", "display-p3", "adobe-rgb",
};
for (int i = 0; i < G_N_ELEMENTS (intents); i++)
{
GDK_DEBUG (MISC, "Rendering intent %d (%s): %s",
i, intents[i], color->color_manager_supported.intents & (1 << i) ? "" : "");
}
for (int i = 0; i < G_N_ELEMENTS (features); i++)
{
GDK_DEBUG (MISC, "Feature %d (%s): %s",
i, features[i], color->color_manager_supported.features & (1 << i) ? "" : "");
}
for (int i = 0; i < G_N_ELEMENTS (tf); i++)
{
GDK_DEBUG (MISC, "Transfer function %d (%s): %s",
i, tf[i], color->color_manager_supported.transfers & (1 << i) ? "" : "");
}
for (int i = 0; i < G_N_ELEMENTS (primaries); i++)
{
GDK_DEBUG (MISC, "Primaries %d (%s): %s",
i, primaries[i], color->color_manager_supported.primaries& (1 << i) ? "" : "");
}
}
if (color->color_manager &&
!(color->color_manager_supported.intents & (1 << XX_COLOR_MANAGER_V2_RENDER_INTENT_PERCEPTUAL)))
{
GDK_DEBUG (MISC, "Not using color management: Missing perceptual render intent");
g_clear_pointer (&color->color_manager, xx_color_manager_v2_destroy);
}
if (color->color_manager &&
(!(color->color_manager_supported.features & (1 << XX_COLOR_MANAGER_V2_FEATURE_PARAMETRIC)) ||
!(color->color_manager_supported.transfers & (1 << XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_SRGB)) ||
!(color->color_manager_supported.primaries & (1 << XX_COLOR_MANAGER_V2_PRIMARIES_SRGB))))
{
GDK_DEBUG (MISC, "Not using color management: Can't create srgb image description");
g_clear_pointer (&color->color_manager, xx_color_manager_v2_destroy);
}
if (color->color_manager)
{
create_image_desc (color,
XX_COLOR_MANAGER_V2_PRIMARIES_SRGB,
XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_SRGB,
&color->srgb);
if (color->color_manager_supported.transfers & (1 << XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LINEAR))
create_image_desc (color,
XX_COLOR_MANAGER_V2_PRIMARIES_SRGB,
XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LINEAR,
&color->srgb_linear);
if (color->color_manager_supported.primaries & (1 << XX_COLOR_MANAGER_V2_PRIMARIES_BT2020))
{
if (color->color_manager_supported.transfers & (1 << XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST2084_PQ))
create_image_desc (color,
XX_COLOR_MANAGER_V2_PRIMARIES_BT2020,
XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST2084_PQ,
&color->rec2100_pq);
if (color->color_manager_supported.transfers & (1 << XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LINEAR))
create_image_desc (color,
XX_COLOR_MANAGER_V2_PRIMARIES_BT2020,
XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LINEAR,
&color->rec2100_linear);
}
}
return color->color_manager != NULL;
}
struct _GdkWaylandColorSurface
{
GdkWaylandColor *color;
struct xx_color_management_surface_v2 *surface;
GdkColorStateChanged callback;
gpointer data;
};
typedef struct
{
GdkWaylandColorSurface *surface;
struct xx_image_description_v2 *image_desc;
struct xx_image_description_info_v2 *info;
int32_t icc;
uint32_t icc_size;
uint32_t r_x, r_y, g_x, g_y, b_x, b_y, w_x, w_y;
uint32_t primaries;
uint32_t tf_power;
uint32_t tf_named;
uint32_t target_r_x, target_r_y, target_g_x, target_g_y, target_b_x, target_b_y, target_w_x, target_w_y;
uint32_t target_min_lum, target_max_lum;
uint32_t target_max_cll, target_max_fall;
unsigned int has_icc : 1;
unsigned int has_primaries : 1;
unsigned int has_primaries_named : 1;
unsigned int has_tf_power : 1;
unsigned int has_tf_named : 1;
unsigned int has_target_primaries : 1;
unsigned int has_target_luminance : 1;
unsigned int has_target_max_cll : 1;
unsigned int has_target_max_fall : 1;
} ImageDescription;
static GdkColorState *
gdk_color_state_from_image_description_bits (ImageDescription *desc)
{
GdkColorState *cs = GDK_COLOR_STATE_SRGB;
if (desc->has_primaries_named && desc->has_tf_named)
{
if (desc->primaries == XX_COLOR_MANAGER_V2_PRIMARIES_SRGB &&
desc->tf_named == XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_SRGB)
{
cs = GDK_COLOR_STATE_SRGB;
}
else if (desc->primaries == XX_COLOR_MANAGER_V2_PRIMARIES_SRGB &&
desc->tf_named == XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LINEAR)
{
cs = GDK_COLOR_STATE_SRGB_LINEAR;
}
else if (desc->primaries == XX_COLOR_MANAGER_V2_PRIMARIES_BT2020 &&
desc->tf_named == XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST2084_PQ)
{
cs = GDK_COLOR_STATE_REC2100_PQ;
}
else if (desc->primaries == XX_COLOR_MANAGER_V2_PRIMARIES_BT2020 &&
desc->tf_named == XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LINEAR)
{
cs = GDK_COLOR_STATE_REC2100_LINEAR;
}
}
return cs;
}
static void
image_desc_info_done (void *data,
struct xx_image_description_info_v2 *info)
{
ImageDescription *desc = data;
GdkWaylandColorSurface *self = desc->surface;
GdkColorState *cs;
cs = gdk_color_state_from_image_description_bits (desc);
if (self->callback)
self->callback (desc->surface, cs, self->data);
gdk_color_state_unref (cs);
xx_image_description_v2_destroy (desc->image_desc);
xx_image_description_info_v2_destroy (desc->info);
g_free (desc);
}
static void
image_desc_info_icc_file (void *data,
struct xx_image_description_info_v2 *info,
int32_t icc,
uint32_t icc_size)
{
ImageDescription *desc = data;
desc->icc = icc;
desc->icc_size = icc_size;
desc->has_icc = 1;
}
static void
image_desc_info_primaries (void *data,
struct xx_image_description_info_v2 *info,
uint32_t r_x, uint32_t r_y,
uint32_t g_x, uint32_t g_y,
uint32_t b_x, uint32_t b_y,
uint32_t w_x, uint32_t w_y)
{
ImageDescription *desc = data;
desc->r_x = r_x; desc->r_y = r_y;
desc->g_x = g_x; desc->r_y = g_y;
desc->b_x = b_x; desc->r_y = b_y;
desc->w_x = w_x; desc->r_y = w_y;
desc->has_primaries = 1;
}
static void
image_desc_info_primaries_named (void *data,
struct xx_image_description_info_v2 *info,
uint32_t primaries)
{
ImageDescription *desc = data;
desc->primaries = primaries;
desc->has_primaries_named = 1;
}
static void
image_desc_info_tf_power (void *data,
struct xx_image_description_info_v2 *info,
uint32_t tf_power)
{
ImageDescription *desc = data;
desc->tf_power = tf_power;
desc->has_tf_power = 1;
}
static void
image_desc_info_tf_named (void *data,
struct xx_image_description_info_v2 *info,
uint32_t tf)
{
ImageDescription *desc = data;
desc->tf_named = tf;
desc->has_tf_named = 1;
}
static void
image_desc_info_target_primaries (void *data,
struct xx_image_description_info_v2 *info,
uint32_t r_x, uint32_t r_y,
uint32_t g_x, uint32_t g_y,
uint32_t b_x, uint32_t b_y,
uint32_t w_x, uint32_t w_y)
{
ImageDescription *desc = data;
desc->target_r_x = r_x; desc->target_r_y = r_y;
desc->target_g_x = g_x; desc->target_r_y = g_y;
desc->target_b_x = b_x; desc->target_r_y = b_y;
desc->target_w_x = w_x; desc->target_r_y = w_y;
desc->has_target_primaries = 1;
}
static void
image_desc_info_target_luminance (void *data,
struct xx_image_description_info_v2 *info,
uint32_t min_lum,
uint32_t max_lum)
{
ImageDescription *desc = data;
desc->target_min_lum = min_lum;
desc->target_max_lum = max_lum;
desc->has_target_luminance = 1;
}
static void
image_desc_info_target_max_cll (void *data,
struct xx_image_description_info_v2 *info,
uint32_t max_cll)
{
ImageDescription *desc = data;
desc->target_max_cll = max_cll;
desc->has_target_max_cll = 1;
}
static void
image_desc_info_target_max_fall (void *data,
struct xx_image_description_info_v2 *info,
uint32_t max_fall)
{
ImageDescription *desc = data;
desc->target_max_fall = max_fall;
desc->has_target_max_fall = 1;
}
static struct xx_image_description_info_v2_listener info_listener = {
image_desc_info_done,
image_desc_info_icc_file,
image_desc_info_primaries,
image_desc_info_primaries_named,
image_desc_info_tf_power,
image_desc_info_tf_named,
image_desc_info_target_primaries,
image_desc_info_target_luminance,
image_desc_info_target_max_cll,
image_desc_info_target_max_fall,
};
static void
image_desc_failed (void *data,
struct xx_image_description_v2 *image_desc,
uint32_t cause,
const char *msg)
{
ImageDescription *desc = data;
GdkWaylandColorSurface *self = desc->surface;
self->callback (self, GDK_COLOR_STATE_SRGB, self->data);
xx_image_description_v2_destroy (desc->image_desc);
g_free (desc);
}
static void
image_desc_ready (void *data,
struct xx_image_description_v2 *image_desc,
uint32_t identity)
{
ImageDescription *desc = data;
desc->info = xx_image_description_v2_get_information (image_desc);
xx_image_description_info_v2_add_listener (desc->info, &info_listener, desc);
}
static const struct xx_image_description_v2_listener image_desc_listener = {
image_desc_failed,
image_desc_ready
};
static void
preferred_changed (void *data,
struct xx_color_management_surface_v2 *color_mgmt_surface)
{
GdkWaylandColorSurface *self = data;
ImageDescription *desc;
desc = g_new0 (ImageDescription, 1);
desc->surface = self;
desc->image_desc = xx_color_management_surface_v2_get_preferred (self->surface);
xx_image_description_v2_add_listener (desc->image_desc, &image_desc_listener, desc);
}
static const struct xx_color_management_surface_v2_listener color_listener = {
preferred_changed,
};
GdkWaylandColorSurface *
gdk_wayland_color_surface_new (GdkWaylandColor *color,
struct wl_surface *wl_surface,
GdkColorStateChanged callback,
gpointer data)
{
GdkWaylandColorSurface *self;
self = g_new0 (GdkWaylandColorSurface, 1);
self->color = color;
self->surface = xx_color_manager_v2_get_surface (color->color_manager, wl_surface);
self->callback = callback;
self->data = data;
xx_color_management_surface_v2_add_listener (self->surface, &color_listener, self);
return self;
}
void
gdk_wayland_color_surface_free (GdkWaylandColorSurface *self)
{
xx_color_management_surface_v2_destroy (self->surface);
g_free (self);
}
static struct xx_image_description_v2 *
gdk_wayland_color_get_image_description (GdkWaylandColor *color,
GdkColorState *cs)
{
if (gdk_color_state_equal (cs, GDK_COLOR_STATE_SRGB))
return color->srgb;
else if (gdk_color_state_equal (cs, GDK_COLOR_STATE_SRGB_LINEAR))
return color->srgb_linear;
else if (gdk_color_state_equal (cs, GDK_COLOR_STATE_REC2100_PQ))
return color->rec2100_pq;
else if (gdk_color_state_equal (cs, GDK_COLOR_STATE_REC2100_LINEAR))
return color->rec2100_linear;
else
return color->srgb;
}
void
gdk_wayland_color_surface_set_color_state (GdkWaylandColorSurface *self,
GdkColorState *cs)
{
struct xx_image_description_v2 *desc;
desc = gdk_wayland_color_get_image_description (self->color, cs);
if (desc)
xx_color_management_surface_v2_set_image_description (self->surface,
desc,
XX_COLOR_MANAGER_V2_RENDER_INTENT_PERCEPTUAL);
else
xx_color_management_surface_v2_unset_image_description (self->surface);
}
gboolean
gdk_wayland_color_surface_can_set_color_state (GdkWaylandColorSurface *self,
GdkColorState *cs)
{
return gdk_wayland_color_get_image_description (self->color, cs) != NULL;
}

View File

@@ -23,6 +23,7 @@ gdk_wayland_sources = files([
'gdktoplevel-wayland.c',
'gdkpopup-wayland.c',
'gdkvulkancontext-wayland.c',
'gdkwaylandcolor.c',
'gdkwaylandpresentationtime.c',
'wm-button-layout-translation.c',
])
@@ -145,6 +146,11 @@ proto_sources = [
'stability': 'staging',
'version': 1,
},
{
'name': 'xx-color-management',
'stability': 'private',
'version': 2,
},
]
gdk_wayland_gen_headers = []

File diff suppressed because it is too large Load Diff

View File

@@ -67,6 +67,7 @@
#include <epoxy/egl.h>
#include <xkbcommon/xkbcommon.h>
#include "wayland/gdkdisplay-wayland.h"
#include "wayland/gdkwaylandcolor-private.h"
#endif
#ifdef GDK_WINDOWING_BROADWAY
@@ -695,6 +696,7 @@ add_wayland_protocols (GdkDisplay *display,
append_wayland_protocol_row (gen, (struct wl_proxy *)d->viewporter);
append_wayland_protocol_row (gen, (struct wl_proxy *)d->presentation);
append_wayland_protocol_row (gen, (struct wl_proxy *)d->single_pixel_buffer);
append_wayland_protocol_row (gen, gdk_wayland_color_get_color_manager (d->color));
}
}
#endif