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

View File

@ -137,28 +137,32 @@ meta_crtc_get_config (MetaCrtc *crtc)
return priv->config; return priv->config;
} }
void size_t
meta_crtc_get_gamma_lut (MetaCrtc *crtc, meta_crtc_get_gamma_lut_size (MetaCrtc *crtc)
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{ {
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 void
meta_crtc_set_gamma_lut (MetaCrtc *crtc, meta_crtc_set_gamma_lut (MetaCrtc *crtc,
size_t size, const MetaGammaLut *lut)
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{ {
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 static void

View File

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

View File

@ -32,6 +32,7 @@
#endif #endif
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-crtc.h"
#include "backends/meta-cursor.h" #include "backends/meta-cursor.h"
#include "backends/meta-display-config-shared.h" #include "backends/meta-display-config-shared.h"
#include "backends/meta-monitor-transform.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) for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
{ {
MetaCrtc *crtc = l_crtc->data; MetaCrtc *crtc = l_crtc->data;
size_t gamma_lut_size;
meta_crtc_get_gamma_lut (crtc, &gamma_lut_size, NULL, NULL, NULL); if (meta_crtc_get_gamma_lut_size (crtc) > 0)
if (gamma_lut_size > 0)
{ {
night_light_supported = TRUE; night_light_supported = TRUE;
break; break;
@ -2861,10 +2859,7 @@ meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton,
{ {
GList *combined_crtcs; GList *combined_crtcs;
MetaCrtc *crtc; MetaCrtc *crtc;
gsize size; g_autoptr (MetaGammaLut) gamma_lut = NULL;
unsigned short *red;
unsigned short *green;
unsigned short *blue;
GBytes *red_bytes, *green_bytes, *blue_bytes; GBytes *red_bytes, *green_bytes, *blue_bytes;
GVariant *red_v, *green_v, *blue_v; 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); crtc = g_list_nth_data (combined_crtcs, crtc_id);
g_list_free (combined_crtcs); 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)); red_bytes = g_bytes_new_take (g_steal_pointer (&gamma_lut->red),
green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short)); gamma_lut->size * sizeof (unsigned short));
blue_bytes = g_bytes_new_take (blue, 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); 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); 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; GList *combined_crtcs;
MetaCrtc *crtc; MetaCrtc *crtc;
gsize size, dummy; size_t dummy;
unsigned short *red;
unsigned short *green;
unsigned short *blue;
GBytes *red_bytes, *green_bytes, *blue_bytes; GBytes *red_bytes, *green_bytes, *blue_bytes;
MetaGammaLut lut;
if (serial != manager->serial) 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); green_bytes = g_variant_get_data_as_bytes (green_v);
blue_bytes = g_variant_get_data_as_bytes (blue_v); blue_bytes = g_variant_get_data_as_bytes (blue_v);
size = g_bytes_get_size (red_bytes) / sizeof (unsigned short); lut.size = g_bytes_get_size (red_bytes) / sizeof (uint16_t);
red = (unsigned short*) g_bytes_get_data (red_bytes, &dummy); lut.red = (uint16_t *) g_bytes_get_data (red_bytes, &dummy);
green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy); lut.green = (uint16_t *) g_bytes_get_data (green_bytes, &dummy);
blue = (unsigned short*) g_bytes_get_data (blue_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); meta_dbus_display_config_complete_set_crtc_gamma (skeleton, invocation);
g_bytes_unref (red_bytes); g_bytes_unref (red_bytes);

View File

@ -689,22 +689,12 @@ meta_monitor_get_gamma_lut_size (MetaMonitor *monitor)
{ {
MetaOutput *output; MetaOutput *output;
MetaCrtc *crtc; MetaCrtc *crtc;
size_t size;
output = meta_monitor_get_main_output (monitor); output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
meta_crtc_get_gamma_lut (crtc, &size, NULL, NULL, NULL); return meta_crtc_get_gamma_lut_size (crtc);
return size;
} }
typedef struct
{
uint16_t *red;
uint16_t *green;
uint16_t *blue;
size_t size;
} LutData;
static gboolean static gboolean
set_gamma_lut (MetaMonitor *monitor, set_gamma_lut (MetaMonitor *monitor,
MetaMonitorMode *mode, MetaMonitorMode *mode,
@ -712,16 +702,12 @@ set_gamma_lut (MetaMonitor *monitor,
gpointer user_data, gpointer user_data,
GError **error) GError **error)
{ {
LutData *lut_data = user_data; const MetaGammaLut *lut = user_data;
MetaCrtc *crtc; MetaCrtc *crtc;
crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output); crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
meta_crtc_set_gamma_lut (crtc, meta_crtc_set_gamma_lut (crtc, lut);
lut_data->size,
lut_data->red,
lut_data->green,
lut_data->blue);
return TRUE; return TRUE;
} }
@ -732,27 +718,17 @@ set_gamma_lut (MetaMonitor *monitor,
*/ */
void void
meta_monitor_set_gamma_lut (MetaMonitor *monitor, meta_monitor_set_gamma_lut (MetaMonitor *monitor,
uint16_t *red, const MetaGammaLut *lut)
uint16_t *green,
uint16_t *blue,
size_t size)
{ {
MetaMonitorMode *current_mode; MetaMonitorMode *current_mode;
LutData lut_data;
current_mode = meta_monitor_get_current_mode (monitor); current_mode = meta_monitor_get_current_mode (monitor);
g_return_if_fail (current_mode); g_return_if_fail (current_mode);
lut_data = (LutData) {
.red = red,
.green = green,
.blue = blue,
.size = size,
};
meta_monitor_mode_foreach_crtc (monitor, meta_monitor_mode_foreach_crtc (monitor,
current_mode, current_mode,
set_gamma_lut, set_gamma_lut,
&lut_data, (gpointer) lut,
NULL); NULL);
} }

View File

@ -306,9 +306,6 @@ gboolean meta_monitor_set_privacy_screen_enabled (MetaMonitor *monitor,
size_t meta_monitor_get_gamma_lut_size (MetaMonitor *monitor); size_t meta_monitor_get_gamma_lut_size (MetaMonitor *monitor);
void meta_monitor_set_gamma_lut (MetaMonitor *monitor, void meta_monitor_set_gamma_lut (MetaMonitor *monitor,
uint16_t *red, const MetaGammaLut *lut);
uint16_t *green,
uint16_t *blue,
size_t size);
#endif /* META_MONITOR_H */ #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; crtc_kms->cursor_renderer_private_destroy_notify = destroy_notify;
} }
static void static size_t
meta_crtc_kms_get_gamma_lut (MetaCrtc *crtc, meta_crtc_kms_get_gamma_lut_size (MetaCrtc *crtc)
size_t *size, {
unsigned short **red, MetaKmsCrtc *kms_crtc;
unsigned short **green, const MetaKmsCrtcState *crtc_state;
unsigned short **blue)
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); MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); 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); monitor_manager_from_crtc (crtc);
const MetaKmsCrtcState *crtc_state; const MetaKmsCrtcState *crtc_state;
MetaKmsCrtcGamma *crtc_gamma; MetaKmsCrtcGamma *crtc_gamma;
MetaGammaLut *lut;
crtc_gamma = crtc_gamma =
meta_monitor_manager_native_get_cached_crtc_gamma (monitor_manager_native, meta_monitor_manager_native_get_cached_crtc_gamma (monitor_manager_native,
crtc_kms); crtc_kms);
if (crtc_gamma) if (crtc_gamma)
{ {
if (size) lut = g_new0 (MetaGammaLut, 1);
*size = crtc_gamma->size; lut->size = crtc_gamma->size;
if (red) lut->red = g_memdup2 (crtc_gamma->red,
*red = g_memdup2 (crtc_gamma->red, *size * sizeof **red); lut->size * sizeof (uint16_t));
if (green) lut->green = g_memdup2 (crtc_gamma->green,
*green = g_memdup2 (crtc_gamma->green, *size * sizeof **green); lut->size * sizeof (uint16_t));
if (blue) lut->blue = g_memdup2 (crtc_gamma->blue,
*blue = g_memdup2 (crtc_gamma->blue, *size * sizeof **blue); lut->size * sizeof (uint16_t));
return; return lut;
} }
crtc_state = meta_kms_crtc_get_current_state (kms_crtc); crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
if (size) lut = g_new0 (MetaGammaLut, 1);
*size = crtc_state->gamma.size; lut->size = crtc_state->gamma.size;
if (red) lut->red = g_memdup2 (crtc_state->gamma.red,
*red = g_memdup2 (crtc_state->gamma.red, *size * sizeof **red); lut->size * sizeof (uint16_t));
if (green) lut->green = g_memdup2 (crtc_state->gamma.green,
*green = g_memdup2 (crtc_state->gamma.green, *size * sizeof **green); lut->size * sizeof (uint16_t));
if (blue) lut->blue = g_memdup2 (crtc_state->gamma.blue,
*blue = g_memdup2 (crtc_state->gamma.blue, *size * sizeof **blue); lut->size * sizeof (uint16_t));
return lut;
} }
static char * static char *
generate_gamma_ramp_string (size_t size, generate_gamma_ramp_string (const MetaGammaLut *lut)
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{ {
GString *string; GString *string;
int color; int color;
@ -139,39 +147,39 @@ generate_gamma_ramp_string (size_t size,
string = g_string_new ("["); string = g_string_new ("[");
for (color = 0; color < 3; color++) for (color = 0; color < 3; color++)
{ {
unsigned short **color_ptr = NULL; uint16_t * const *color_ptr = NULL;
char color_char; char color_char;
size_t i; size_t i;
switch (color) switch (color)
{ {
case 0: case 0:
color_ptr = &red; color_ptr = &lut->red;
color_char = 'r'; color_char = 'r';
break; break;
case 1: case 1:
color_ptr = &green; color_ptr = &lut->green;
color_char = 'g'; color_char = 'g';
break; break;
case 2: case 2:
color_ptr = &blue; color_ptr = &lut->blue;
color_char = 'b'; color_char = 'b';
break; break;
} }
g_assert (color_ptr); g_assert (color_ptr);
g_string_append_printf (string, " %c: ", color_char); 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; int j;
if (size > 4) if (lut->size > 4)
{ {
if (i == 2) if (i == 2)
g_string_append (string, ",..."); g_string_append (string, ",...");
if (i >= 2) if (i >= 2)
j = i + (size - 4); j = i + (lut->size - 4);
else else
j = i; j = i;
} }
@ -192,10 +200,7 @@ generate_gamma_ramp_string (size_t size,
static void static void
meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc, meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
size_t size, const MetaGammaLut *lut)
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{ {
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); 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); 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); MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
@ -219,13 +224,16 @@ meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
return; 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, meta_topic (META_DEBUG_COLOR,
"Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s", "Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
meta_crtc_get_id (crtc), gamma_ramp_string); meta_crtc_get_id (crtc), gamma_ramp_string);
crtc_gamma = meta_kms_crtc_gamma_new (kms_crtc, size, crtc_gamma = meta_kms_crtc_gamma_new (kms_crtc,
red, green, blue); lut->size,
lut->red,
lut->green,
lut->blue);
meta_monitor_manager_native_update_cached_crtc_gamma (monitor_manager_native, meta_monitor_manager_native_update_cached_crtc_gamma (monitor_manager_native,
crtc_kms, crtc_kms,
crtc_gamma); crtc_gamma);
@ -559,6 +567,7 @@ meta_crtc_kms_class_init (MetaCrtcKmsClass *klass)
object_class->dispose = meta_crtc_kms_dispose; 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->get_gamma_lut = meta_crtc_kms_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_kms_set_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); NULL);
} }
static void static size_t
meta_crtc_virtual_get_gamma_lut (MetaCrtc *crtc, meta_crtc_virtual_get_gamma_lut_size (MetaCrtc *crtc)
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{ {
if (size) return 0;
*size = 0; }
if (red)
*red = NULL; static MetaGammaLut *
if (green) meta_crtc_virtual_get_gamma_lut (MetaCrtc *crtc)
*green = NULL; {
if (blue) return NULL;
*blue = NULL;
} }
static void static void
meta_crtc_virtual_set_gamma_lut (MetaCrtc *crtc, meta_crtc_virtual_set_gamma_lut (MetaCrtc *crtc,
size_t size, const MetaGammaLut *lut)
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{ {
g_warn_if_reached (); g_warn_if_reached ();
} }
@ -89,6 +81,7 @@ meta_crtc_virtual_class_init (MetaCrtcVirtualClass *klass)
MetaCrtcClass *crtc_class = META_CRTC_CLASS (klass); MetaCrtcClass *crtc_class = META_CRTC_CLASS (klass);
MetaCrtcNativeClass *crtc_native_class = META_CRTC_NATIVE_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->get_gamma_lut = meta_crtc_virtual_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_virtual_set_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; return crtc_xrandr;
} }
static void static MetaGammaLut *
meta_crtc_xrandr_get_gamma_lut (MetaCrtc *crtc, meta_crtc_xrandr_get_gamma_lut (MetaCrtc *crtc)
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{ {
MetaGpu *gpu = meta_crtc_get_gpu (crtc); MetaGpu *gpu = meta_crtc_get_gpu (crtc);
MetaBackend *backend = meta_gpu_get_backend (gpu); MetaBackend *backend = meta_gpu_get_backend (gpu);
Display *xdisplay = Display *xdisplay =
meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XRRCrtcGamma *gamma; XRRCrtcGamma *gamma;
MetaGammaLut *lut;
gamma = XRRGetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc)); gamma = XRRGetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc));
*size = gamma->size; lut = g_new0 (MetaGammaLut, 1);
if (red) lut->size = gamma->size;
*red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size); lut->red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size);
if (green) lut->green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size);
*green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size); lut->blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size);
if (blue)
*blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size);
XRRFreeGamma (gamma); 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 static void
meta_crtc_xrandr_set_gamma_lut (MetaCrtc *crtc, meta_crtc_xrandr_set_gamma_lut (MetaCrtc *crtc,
size_t size, const MetaGammaLut *lut)
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{ {
MetaGpu *gpu = meta_crtc_get_gpu (crtc); MetaGpu *gpu = meta_crtc_get_gpu (crtc);
MetaBackend *backend = meta_gpu_get_backend (gpu); 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)); meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XRRCrtcGamma *gamma; XRRCrtcGamma *gamma;
gamma = XRRAllocGamma (size); gamma = XRRAllocGamma (lut->size);
memcpy (gamma->red, red, sizeof (unsigned short) * size); memcpy (gamma->red, lut->red, sizeof (uint16_t) * lut->size);
memcpy (gamma->green, green, sizeof (unsigned short) * size); memcpy (gamma->green, lut->green, sizeof (uint16_t) * lut->size);
memcpy (gamma->blue, blue, sizeof (unsigned short) * size); memcpy (gamma->blue, lut->blue, sizeof (uint16_t) * lut->size);
XRRSetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc), gamma); 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); 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->get_gamma_lut = meta_crtc_xrandr_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_xrandr_set_gamma_lut; crtc_class->set_gamma_lut = meta_crtc_xrandr_set_gamma_lut;
} }