crtc: Get/set gamma via helper struct

Instead of passing 4 arguments (red, green and blue arrays as well as a
size), always pass them together in a new struct MetaGammaLut. Makes
things slightly less tedious.

The KMS layer still has its own variant, but lets leave it as that for
now, to keep the KMS layer "below" the cross backend CRTC layer.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2165>
This commit is contained in:
Jonas Ådahl 2021-12-03 17:34:34 +01:00
parent 9dda79b281
commit b59dc05b22
10 changed files with 169 additions and 174 deletions

View File

@ -21,6 +21,9 @@
#ifndef META_BACKEND_TYPE_H
#define META_BACKEND_TYPE_H
#include <stdint.h>
#include <stddef.h>
typedef struct _MetaBackend MetaBackend;
typedef struct _MetaColorDevice MetaColorDevice;
@ -77,4 +80,12 @@ typedef struct _MetaIdleManager MetaIdleManager;
typedef struct _MetaRemoteDesktop MetaRemoteDesktop;
#endif
typedef struct _MetaGammaLut
{
uint16_t *red;
uint16_t *green;
uint16_t *blue;
size_t size;
} MetaGammaLut;
#endif /* META_BACKEND_TYPE_H */

View File

@ -137,28 +137,32 @@ meta_crtc_get_config (MetaCrtc *crtc)
return priv->config;
}
void
meta_crtc_get_gamma_lut (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
size_t
meta_crtc_get_gamma_lut_size (MetaCrtc *crtc)
{
MetaCrtcClass *crtc_class = META_CRTC_GET_CLASS (crtc);
return META_CRTC_GET_CLASS (crtc)->get_gamma_lut_size (crtc);
}
crtc_class->get_gamma_lut (crtc, size, red, green, blue);
MetaGammaLut *
meta_crtc_get_gamma_lut (MetaCrtc *crtc)
{
return META_CRTC_GET_CLASS (crtc)->get_gamma_lut (crtc);
}
void
meta_crtc_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
meta_crtc_set_gamma_lut (MetaCrtc *crtc,
const MetaGammaLut *lut)
{
MetaCrtcClass *crtc_class = META_CRTC_GET_CLASS (crtc);
return META_CRTC_GET_CLASS (crtc)->set_gamma_lut (crtc, lut);
}
crtc_class->set_gamma_lut (crtc, size, red, green, blue);
void
meta_gamma_lut_free (MetaGammaLut *lut)
{
g_free (lut->red);
g_free (lut->green);
g_free (lut->blue);
g_free (lut);
}
static void

View File

@ -43,17 +43,12 @@ struct _MetaCrtcClass
{
GObjectClass parent_class;
void (* get_gamma_lut) (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue);
size_t (* get_gamma_lut_size) (MetaCrtc *crtc);
void (* set_gamma_lut) (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue);
MetaGammaLut * (* get_gamma_lut) (MetaCrtc *crtc);
void (* set_gamma_lut) (MetaCrtc *crtc,
const MetaGammaLut *lut);
};
META_EXPORT_TEST
@ -86,16 +81,15 @@ void meta_crtc_unset_config (MetaCrtc *crtc);
META_EXPORT_TEST
const MetaCrtcConfig * meta_crtc_get_config (MetaCrtc *crtc);
void meta_crtc_get_gamma_lut (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue);
size_t meta_crtc_get_gamma_lut_size (MetaCrtc *crtc);
void meta_crtc_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue);
MetaGammaLut * meta_crtc_get_gamma_lut (MetaCrtc *crtc);
void meta_crtc_set_gamma_lut (MetaCrtc *crtc,
const MetaGammaLut *lut);
void meta_gamma_lut_free (MetaGammaLut *lut);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaGammaLut, meta_gamma_lut_free)
#endif /* META_CRTC_H */

View File

@ -32,6 +32,7 @@
#endif
#include "backends/meta-backend-private.h"
#include "backends/meta-crtc.h"
#include "backends/meta-cursor.h"
#include "backends/meta-display-config-shared.h"
#include "backends/meta-monitor-transform.h"

View File

@ -1169,10 +1169,8 @@ update_night_light_supported (MetaMonitorManager *manager)
for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
{
MetaCrtc *crtc = l_crtc->data;
size_t gamma_lut_size;
meta_crtc_get_gamma_lut (crtc, &gamma_lut_size, NULL, NULL, NULL);
if (gamma_lut_size > 0)
if (meta_crtc_get_gamma_lut_size (crtc) > 0)
{
night_light_supported = TRUE;
break;
@ -2861,10 +2859,7 @@ meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton,
{
GList *combined_crtcs;
MetaCrtc *crtc;
gsize size;
unsigned short *red;
unsigned short *green;
unsigned short *blue;
g_autoptr (MetaGammaLut) gamma_lut = NULL;
GBytes *red_bytes, *green_bytes, *blue_bytes;
GVariant *red_v, *green_v, *blue_v;
@ -2889,11 +2884,14 @@ meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton,
crtc = g_list_nth_data (combined_crtcs, crtc_id);
g_list_free (combined_crtcs);
meta_crtc_get_gamma_lut (crtc, &size, &red, &green, &blue);
gamma_lut = meta_crtc_get_gamma_lut (crtc);
red_bytes = g_bytes_new_take (red, size * sizeof (unsigned short));
green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short));
blue_bytes = g_bytes_new_take (blue, size * sizeof (unsigned short));
red_bytes = g_bytes_new_take (g_steal_pointer (&gamma_lut->red),
gamma_lut->size * sizeof (unsigned short));
green_bytes = g_bytes_new_take (g_steal_pointer (&gamma_lut->green),
gamma_lut->size * sizeof (unsigned short));
blue_bytes = g_bytes_new_take (g_steal_pointer (&gamma_lut->blue),
gamma_lut->size * sizeof (unsigned short));
red_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), red_bytes, TRUE);
green_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), green_bytes, TRUE);
@ -2921,11 +2919,9 @@ meta_monitor_manager_handle_set_crtc_gamma (MetaDBusDisplayConfig *skeleton,
{
GList *combined_crtcs;
MetaCrtc *crtc;
gsize size, dummy;
unsigned short *red;
unsigned short *green;
unsigned short *blue;
size_t dummy;
GBytes *red_bytes, *green_bytes, *blue_bytes;
MetaGammaLut lut;
if (serial != manager->serial)
{
@ -2953,12 +2949,12 @@ meta_monitor_manager_handle_set_crtc_gamma (MetaDBusDisplayConfig *skeleton,
green_bytes = g_variant_get_data_as_bytes (green_v);
blue_bytes = g_variant_get_data_as_bytes (blue_v);
size = g_bytes_get_size (red_bytes) / sizeof (unsigned short);
red = (unsigned short*) g_bytes_get_data (red_bytes, &dummy);
green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy);
blue = (unsigned short*) g_bytes_get_data (blue_bytes, &dummy);
lut.size = g_bytes_get_size (red_bytes) / sizeof (uint16_t);
lut.red = (uint16_t *) g_bytes_get_data (red_bytes, &dummy);
lut.green = (uint16_t *) g_bytes_get_data (green_bytes, &dummy);
lut.blue = (uint16_t *) g_bytes_get_data (blue_bytes, &dummy);
meta_crtc_set_gamma_lut (crtc, size, red, green, blue);
meta_crtc_set_gamma_lut (crtc, &lut);
meta_dbus_display_config_complete_set_crtc_gamma (skeleton, invocation);
g_bytes_unref (red_bytes);

View File

@ -689,22 +689,12 @@ meta_monitor_get_gamma_lut_size (MetaMonitor *monitor)
{
MetaOutput *output;
MetaCrtc *crtc;
size_t size;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
meta_crtc_get_gamma_lut (crtc, &size, NULL, NULL, NULL);
return size;
return meta_crtc_get_gamma_lut_size (crtc);
}
typedef struct
{
uint16_t *red;
uint16_t *green;
uint16_t *blue;
size_t size;
} LutData;
static gboolean
set_gamma_lut (MetaMonitor *monitor,
MetaMonitorMode *mode,
@ -712,16 +702,12 @@ set_gamma_lut (MetaMonitor *monitor,
gpointer user_data,
GError **error)
{
LutData *lut_data = user_data;
const MetaGammaLut *lut = user_data;
MetaCrtc *crtc;
crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
meta_crtc_set_gamma_lut (crtc,
lut_data->size,
lut_data->red,
lut_data->green,
lut_data->blue);
meta_crtc_set_gamma_lut (crtc, lut);
return TRUE;
}
@ -731,28 +717,18 @@ set_gamma_lut (MetaMonitor *monitor,
* Set a new gamma look-up table (LUT) for the given monitor's CRTCs.
*/
void
meta_monitor_set_gamma_lut (MetaMonitor *monitor,
uint16_t *red,
uint16_t *green,
uint16_t *blue,
size_t size)
meta_monitor_set_gamma_lut (MetaMonitor *monitor,
const MetaGammaLut *lut)
{
MetaMonitorMode *current_mode;
LutData lut_data;
current_mode = meta_monitor_get_current_mode (monitor);
g_return_if_fail (current_mode);
lut_data = (LutData) {
.red = red,
.green = green,
.blue = blue,
.size = size,
};
meta_monitor_mode_foreach_crtc (monitor,
current_mode,
set_gamma_lut,
&lut_data,
(gpointer) lut,
NULL);
}

View File

@ -305,10 +305,7 @@ gboolean meta_monitor_set_privacy_screen_enabled (MetaMonitor *monitor,
size_t meta_monitor_get_gamma_lut_size (MetaMonitor *monitor);
void meta_monitor_set_gamma_lut (MetaMonitor *monitor,
uint16_t *red,
uint16_t *green,
uint16_t *blue,
size_t size);
void meta_monitor_set_gamma_lut (MetaMonitor *monitor,
const MetaGammaLut *lut);
#endif /* META_MONITOR_H */

View File

@ -85,12 +85,20 @@ meta_crtc_kms_set_cursor_renderer_private (MetaCrtcKms *crtc_kms,
crtc_kms->cursor_renderer_private_destroy_notify = destroy_notify;
}
static void
meta_crtc_kms_get_gamma_lut (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
static size_t
meta_crtc_kms_get_gamma_lut_size (MetaCrtc *crtc)
{
MetaKmsCrtc *kms_crtc;
const MetaKmsCrtcState *crtc_state;
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
return crtc_state->gamma.size;
}
static MetaGammaLut *
meta_crtc_kms_get_gamma_lut (MetaCrtc *crtc)
{
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
@ -98,40 +106,40 @@ meta_crtc_kms_get_gamma_lut (MetaCrtc *crtc,
monitor_manager_from_crtc (crtc);
const MetaKmsCrtcState *crtc_state;
MetaKmsCrtcGamma *crtc_gamma;
MetaGammaLut *lut;
crtc_gamma =
meta_monitor_manager_native_get_cached_crtc_gamma (monitor_manager_native,
crtc_kms);
if (crtc_gamma)
{
if (size)
*size = crtc_gamma->size;
if (red)
*red = g_memdup2 (crtc_gamma->red, *size * sizeof **red);
if (green)
*green = g_memdup2 (crtc_gamma->green, *size * sizeof **green);
if (blue)
*blue = g_memdup2 (crtc_gamma->blue, *size * sizeof **blue);
return;
lut = g_new0 (MetaGammaLut, 1);
lut->size = crtc_gamma->size;
lut->red = g_memdup2 (crtc_gamma->red,
lut->size * sizeof (uint16_t));
lut->green = g_memdup2 (crtc_gamma->green,
lut->size * sizeof (uint16_t));
lut->blue = g_memdup2 (crtc_gamma->blue,
lut->size * sizeof (uint16_t));
return lut;
}
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
if (size)
*size = crtc_state->gamma.size;
if (red)
*red = g_memdup2 (crtc_state->gamma.red, *size * sizeof **red);
if (green)
*green = g_memdup2 (crtc_state->gamma.green, *size * sizeof **green);
if (blue)
*blue = g_memdup2 (crtc_state->gamma.blue, *size * sizeof **blue);
lut = g_new0 (MetaGammaLut, 1);
lut->size = crtc_state->gamma.size;
lut->red = g_memdup2 (crtc_state->gamma.red,
lut->size * sizeof (uint16_t));
lut->green = g_memdup2 (crtc_state->gamma.green,
lut->size * sizeof (uint16_t));
lut->blue = g_memdup2 (crtc_state->gamma.blue,
lut->size * sizeof (uint16_t));
return lut;
}
static char *
generate_gamma_ramp_string (size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
generate_gamma_ramp_string (const MetaGammaLut *lut)
{
GString *string;
int color;
@ -139,39 +147,39 @@ generate_gamma_ramp_string (size_t size,
string = g_string_new ("[");
for (color = 0; color < 3; color++)
{
unsigned short **color_ptr = NULL;
uint16_t * const *color_ptr = NULL;
char color_char;
size_t i;
switch (color)
{
case 0:
color_ptr = &red;
color_ptr = &lut->red;
color_char = 'r';
break;
case 1:
color_ptr = &green;
color_ptr = &lut->green;
color_char = 'g';
break;
case 2:
color_ptr = &blue;
color_ptr = &lut->blue;
color_char = 'b';
break;
}
g_assert (color_ptr);
g_string_append_printf (string, " %c: ", color_char);
for (i = 0; i < MIN (4, size); i++)
for (i = 0; i < MIN (4, lut->size); i++)
{
int j;
if (size > 4)
if (lut->size > 4)
{
if (i == 2)
g_string_append (string, ",...");
if (i >= 2)
j = i + (size - 4);
j = i + (lut->size - 4);
else
j = i;
}
@ -191,11 +199,8 @@ generate_gamma_ramp_string (size_t size,
}
static void
meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
const MetaGammaLut *lut)
{
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
@ -209,7 +214,7 @@ meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
if (size != crtc_state->gamma.size)
if (lut->size != crtc_state->gamma.size)
{
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
@ -219,13 +224,16 @@ meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
return;
}
gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
gamma_ramp_string = generate_gamma_ramp_string (lut);
meta_topic (META_DEBUG_COLOR,
"Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
meta_crtc_get_id (crtc), gamma_ramp_string);
crtc_gamma = meta_kms_crtc_gamma_new (kms_crtc, size,
red, green, blue);
crtc_gamma = meta_kms_crtc_gamma_new (kms_crtc,
lut->size,
lut->red,
lut->green,
lut->blue);
meta_monitor_manager_native_update_cached_crtc_gamma (monitor_manager_native,
crtc_kms,
crtc_gamma);
@ -559,6 +567,7 @@ meta_crtc_kms_class_init (MetaCrtcKmsClass *klass)
object_class->dispose = meta_crtc_kms_dispose;
crtc_class->get_gamma_lut_size = meta_crtc_kms_get_gamma_lut_size;
crtc_class->get_gamma_lut = meta_crtc_kms_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_kms_set_gamma_lut;

View File

@ -38,29 +38,21 @@ meta_crtc_virtual_new (uint64_t id)
NULL);
}
static void
meta_crtc_virtual_get_gamma_lut (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
static size_t
meta_crtc_virtual_get_gamma_lut_size (MetaCrtc *crtc)
{
if (size)
*size = 0;
if (red)
*red = NULL;
if (green)
*green = NULL;
if (blue)
*blue = NULL;
return 0;
}
static MetaGammaLut *
meta_crtc_virtual_get_gamma_lut (MetaCrtc *crtc)
{
return NULL;
}
static void
meta_crtc_virtual_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
meta_crtc_virtual_set_gamma_lut (MetaCrtc *crtc,
const MetaGammaLut *lut)
{
g_warn_if_reached ();
}
@ -89,6 +81,7 @@ meta_crtc_virtual_class_init (MetaCrtcVirtualClass *klass)
MetaCrtcClass *crtc_class = META_CRTC_CLASS (klass);
MetaCrtcNativeClass *crtc_native_class = META_CRTC_NATIVE_CLASS (klass);
crtc_class->get_gamma_lut_size = meta_crtc_virtual_get_gamma_lut_size;
crtc_class->get_gamma_lut = meta_crtc_virtual_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_virtual_set_gamma_lut;

View File

@ -297,38 +297,51 @@ meta_crtc_xrandr_new (MetaGpuXrandr *gpu_xrandr,
return crtc_xrandr;
}
static void
meta_crtc_xrandr_get_gamma_lut (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
static MetaGammaLut *
meta_crtc_xrandr_get_gamma_lut (MetaCrtc *crtc)
{
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
MetaBackend *backend = meta_gpu_get_backend (gpu);
Display *xdisplay =
meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XRRCrtcGamma *gamma;
MetaGammaLut *lut;
gamma = XRRGetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc));
*size = gamma->size;
if (red)
*red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size);
if (green)
*green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size);
if (blue)
*blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size);
lut = g_new0 (MetaGammaLut, 1);
lut->size = gamma->size;
lut->red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size);
lut->green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size);
lut->blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size);
XRRFreeGamma (gamma);
return lut;
}
static size_t
meta_crtc_xrandr_get_gamma_lut_size (MetaCrtc *crtc)
{
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
MetaBackend *backend = meta_gpu_get_backend (gpu);
Display *xdisplay =
meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XRRCrtcGamma *gamma;
size_t size;
gamma = XRRGetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc));
size = gamma->size;
XRRFreeGamma (gamma);
return size;
}
static void
meta_crtc_xrandr_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
meta_crtc_xrandr_set_gamma_lut (MetaCrtc *crtc,
const MetaGammaLut *lut)
{
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
MetaBackend *backend = meta_gpu_get_backend (gpu);
@ -336,10 +349,10 @@ meta_crtc_xrandr_set_gamma_lut (MetaCrtc *crtc,
meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XRRCrtcGamma *gamma;
gamma = XRRAllocGamma (size);
memcpy (gamma->red, red, sizeof (unsigned short) * size);
memcpy (gamma->green, green, sizeof (unsigned short) * size);
memcpy (gamma->blue, blue, sizeof (unsigned short) * size);
gamma = XRRAllocGamma (lut->size);
memcpy (gamma->red, lut->red, sizeof (uint16_t) * lut->size);
memcpy (gamma->green, lut->green, sizeof (uint16_t) * lut->size);
memcpy (gamma->blue, lut->blue, sizeof (uint16_t) * lut->size);
XRRSetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc), gamma);
@ -356,6 +369,7 @@ meta_crtc_xrandr_class_init (MetaCrtcXrandrClass *klass)
{
MetaCrtcClass *crtc_class = META_CRTC_CLASS (klass);
crtc_class->get_gamma_lut_size = meta_crtc_xrandr_get_gamma_lut_size;
crtc_class->get_gamma_lut = meta_crtc_xrandr_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_xrandr_set_gamma_lut;
}