monitor-manager: Move gamma LUT manipulation API to MetaCrtc

In practice, for KMS backend CRTC's, we cache the gamma in the monitor
manager instance, so that anyone asking gets the pending or up to date
value, instead of the potentially not up to date value if one queries
after gamma was scheduled to be updated, and before it was actually
updated.

While this is true, lets still move the API to the MetaCrtc type; the
backend specific implementation can still look up cached values from the
MetaMonitorManager, but for users, it becomes less cumbersome to not
have to go via the monitor manager.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2165>
This commit is contained in:
Jonas Ådahl 2022-08-01 23:05:28 +02:00
parent 0a0fb2fda9
commit 9dda79b281
11 changed files with 315 additions and 313 deletions

View File

@ -137,6 +137,30 @@ meta_crtc_get_config (MetaCrtc *crtc)
return priv->config; return priv->config;
} }
void
meta_crtc_get_gamma_lut (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{
MetaCrtcClass *crtc_class = META_CRTC_GET_CLASS (crtc);
crtc_class->get_gamma_lut (crtc, size, red, green, blue);
}
void
meta_crtc_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{
MetaCrtcClass *crtc_class = META_CRTC_GET_CLASS (crtc);
crtc_class->set_gamma_lut (crtc, size, red, green, blue);
}
static void static void
meta_crtc_set_property (GObject *object, meta_crtc_set_property (GObject *object,
guint prop_id, guint prop_id,

View File

@ -42,6 +42,18 @@ G_DECLARE_DERIVABLE_TYPE (MetaCrtc, meta_crtc, META, CRTC, GObject)
struct _MetaCrtcClass struct _MetaCrtcClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
void (* get_gamma_lut) (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue);
void (* set_gamma_lut) (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue);
}; };
META_EXPORT_TEST META_EXPORT_TEST
@ -74,4 +86,16 @@ 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 *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue);
void meta_crtc_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue);
#endif /* META_CRTC_H */ #endif /* META_CRTC_H */

View File

@ -182,13 +182,6 @@ struct _MetaMonitorManager
* @change_backlight: Changes the backlight intensity to the given value (in * @change_backlight: Changes the backlight intensity to the given value (in
* percent). * percent).
* *
* @get_crtc_gamma: Queries and returns the gamma rampQueries and returns the
* gamma ramp.
*
* @set_crtc_gamma: Sets custom display LUT (look up table) for each primary
* color. Each table is indexed by a value that represents input intensity,
* and yields a value that represents output intensity.
*
* @tiled_monitor_added: Should be called by a #MetaMonitor when it is created. * @tiled_monitor_added: Should be called by a #MetaMonitor when it is created.
* *
* @tiled_monitor_removed: Should be called by a #MetaMonitor when it is * @tiled_monitor_removed: Should be called by a #MetaMonitor when it is
@ -230,19 +223,6 @@ struct _MetaMonitorManagerClass
MetaOutput *output, MetaOutput *output,
int backlight); int backlight);
void (* get_crtc_gamma) (MetaMonitorManager *manager,
MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue);
void (* set_crtc_gamma) (MetaMonitorManager *manager,
MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue);
void (* tiled_monitor_added) (MetaMonitorManager *manager, void (* tiled_monitor_added) (MetaMonitorManager *manager,
MetaMonitor *monitor); MetaMonitor *monitor);
@ -452,18 +432,4 @@ GList * meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager);
void meta_monitor_manager_maybe_emit_privacy_screen_change (MetaMonitorManager *manager); void meta_monitor_manager_maybe_emit_privacy_screen_change (MetaMonitorManager *manager);
void meta_monitor_manager_get_crtc_gamma (MetaMonitorManager *manager,
MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue);
void meta_monitor_manager_set_crtc_gamma (MetaMonitorManager *manager,
MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue);
#endif /* META_MONITOR_MANAGER_PRIVATE_H */ #endif /* META_MONITOR_MANAGER_PRIVATE_H */

View File

@ -1152,33 +1152,6 @@ update_has_builtin_panel (MetaMonitorManager *manager)
obj_props[PROP_HAS_BUILTIN_PANEL]); obj_props[PROP_HAS_BUILTIN_PANEL]);
} }
void
meta_monitor_manager_get_crtc_gamma (MetaMonitorManager *manager,
MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{
MetaMonitorManagerClass *klass = META_MONITOR_MANAGER_GET_CLASS (manager);
if (klass->get_crtc_gamma)
{
klass->get_crtc_gamma (manager, crtc, size, red, green, blue);
}
else
{
if (size)
*size = 0;
if (red)
*red = NULL;
if (green)
*green = NULL;
if (blue)
*blue = NULL;
}
}
static void static void
update_night_light_supported (MetaMonitorManager *manager) update_night_light_supported (MetaMonitorManager *manager)
{ {
@ -1198,9 +1171,7 @@ update_night_light_supported (MetaMonitorManager *manager)
MetaCrtc *crtc = l_crtc->data; MetaCrtc *crtc = l_crtc->data;
size_t gamma_lut_size; size_t gamma_lut_size;
meta_monitor_manager_get_crtc_gamma (manager, crtc, meta_crtc_get_gamma_lut (crtc, &gamma_lut_size, NULL, NULL, NULL);
&gamma_lut_size,
NULL, NULL, NULL);
if (gamma_lut_size > 0) if (gamma_lut_size > 0)
{ {
night_light_supported = TRUE; night_light_supported = TRUE;
@ -2918,8 +2889,7 @@ 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_monitor_manager_get_crtc_gamma (manager, crtc, meta_crtc_get_gamma_lut (crtc, &size, &red, &green, &blue);
&size, &red, &green, &blue);
red_bytes = g_bytes_new_take (red, size * sizeof (unsigned short)); red_bytes = g_bytes_new_take (red, size * sizeof (unsigned short));
green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short)); green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short));
@ -2949,7 +2919,6 @@ meta_monitor_manager_handle_set_crtc_gamma (MetaDBusDisplayConfig *skeleton,
GVariant *blue_v, GVariant *blue_v,
MetaMonitorManager *manager) MetaMonitorManager *manager)
{ {
MetaMonitorManagerClass *klass;
GList *combined_crtcs; GList *combined_crtcs;
MetaCrtc *crtc; MetaCrtc *crtc;
gsize size, dummy; gsize size, dummy;
@ -2989,9 +2958,7 @@ meta_monitor_manager_handle_set_crtc_gamma (MetaDBusDisplayConfig *skeleton,
green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy); green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy);
blue = (unsigned short*) g_bytes_get_data (blue_bytes, &dummy); blue = (unsigned short*) g_bytes_get_data (blue_bytes, &dummy);
klass = META_MONITOR_MANAGER_GET_CLASS (manager); meta_crtc_set_gamma_lut (crtc, size, red, green, blue);
if (klass->set_crtc_gamma)
klass->set_crtc_gamma (manager, crtc, size, red, green, blue);
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);
@ -3953,17 +3920,3 @@ meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager)
return priv->virtual_monitors; return priv->virtual_monitors;
} }
void
meta_monitor_manager_set_crtc_gamma (MetaMonitorManager *manager,
MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{
MetaMonitorManagerClass *manager_class =
META_MONITOR_MANAGER_GET_CLASS (manager);
manager_class->set_crtc_gamma (manager, crtc, size, red, green, blue);
}

View File

@ -687,17 +687,13 @@ meta_monitor_create_spec (MetaMonitor *monitor,
size_t size_t
meta_monitor_get_gamma_lut_size (MetaMonitor *monitor) meta_monitor_get_gamma_lut_size (MetaMonitor *monitor)
{ {
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (priv->backend);
MetaOutput *output; MetaOutput *output;
MetaCrtc *crtc; MetaCrtc *crtc;
size_t size; 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_monitor_manager_get_crtc_gamma (monitor_manager, crtc, meta_crtc_get_gamma_lut (crtc, &size, NULL, NULL, NULL);
&size, NULL, NULL, NULL);
return size; return size;
} }
@ -717,15 +713,11 @@ set_gamma_lut (MetaMonitor *monitor,
GError **error) GError **error)
{ {
LutData *lut_data = user_data; LutData *lut_data = user_data;
MetaBackend *backend = meta_monitor_get_backend (monitor);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
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_monitor_manager_set_crtc_gamma (monitor_manager, meta_crtc_set_gamma_lut (crtc,
crtc,
lut_data->size, lut_data->size,
lut_data->red, lut_data->red,
lut_data->green, lut_data->green,

View File

@ -56,6 +56,17 @@ static GQuark kms_crtc_crtc_kms_quark;
G_DEFINE_TYPE (MetaCrtcKms, meta_crtc_kms, META_TYPE_CRTC_NATIVE) G_DEFINE_TYPE (MetaCrtcKms, meta_crtc_kms, META_TYPE_CRTC_NATIVE)
static MetaMonitorManagerNative *
monitor_manager_from_crtc (MetaCrtc *crtc)
{
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
MetaBackend *backend = meta_gpu_get_backend (gpu);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
return META_MONITOR_MANAGER_NATIVE (monitor_manager);
}
gpointer gpointer
meta_crtc_kms_get_cursor_renderer_private (MetaCrtcKms *crtc_kms) meta_crtc_kms_get_cursor_renderer_private (MetaCrtcKms *crtc_kms)
{ {
@ -74,6 +85,155 @@ 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
meta_crtc_kms_get_gamma_lut (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
MetaMonitorManagerNative *monitor_manager_native =
monitor_manager_from_crtc (crtc);
const MetaKmsCrtcState *crtc_state;
MetaKmsCrtcGamma *crtc_gamma;
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;
}
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);
}
static char *
generate_gamma_ramp_string (size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{
GString *string;
int color;
string = g_string_new ("[");
for (color = 0; color < 3; color++)
{
unsigned short **color_ptr = NULL;
char color_char;
size_t i;
switch (color)
{
case 0:
color_ptr = &red;
color_char = 'r';
break;
case 1:
color_ptr = &green;
color_char = 'g';
break;
case 2:
color_ptr = &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++)
{
int j;
if (size > 4)
{
if (i == 2)
g_string_append (string, ",...");
if (i >= 2)
j = i + (size - 4);
else
j = i;
}
else
{
j = i;
}
g_string_append_printf (string, "%s%hu",
j == 0 ? "" : ",",
(*color_ptr)[i]);
}
}
g_string_append (string, " ]");
return g_string_free (string, FALSE);
}
static void
meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
MetaBackend *backend = meta_gpu_get_backend (meta_crtc_get_gpu (crtc));
MetaMonitorManagerNative *monitor_manager_native =
monitor_manager_from_crtc (crtc);
ClutterActor *stage = meta_backend_get_stage (backend);
const MetaKmsCrtcState *crtc_state;
g_autofree char *gamma_ramp_string = NULL;
MetaKmsCrtcGamma *crtc_gamma;
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
if (size != crtc_state->gamma.size)
{
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
g_warning ("Tried to set a different gamma LUT size on %u (%s)",
meta_kms_crtc_get_id (kms_crtc),
meta_kms_device_get_path (kms_device));
return;
}
gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
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);
meta_monitor_manager_native_update_cached_crtc_gamma (monitor_manager_native,
crtc_kms,
crtc_gamma);
meta_crtc_kms_invalidate_gamma (crtc_kms);
clutter_stage_schedule_update (CLUTTER_STAGE (stage));
}
static gboolean static gboolean
is_transform_handled (MetaCrtcKms *crtc_kms, is_transform_handled (MetaCrtcKms *crtc_kms,
MetaMonitorTransform transform) MetaMonitorTransform transform)
@ -394,10 +554,14 @@ static void
meta_crtc_kms_class_init (MetaCrtcKmsClass *klass) meta_crtc_kms_class_init (MetaCrtcKmsClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_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);
object_class->dispose = meta_crtc_kms_dispose; object_class->dispose = meta_crtc_kms_dispose;
crtc_class->get_gamma_lut = meta_crtc_kms_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_kms_set_gamma_lut;
crtc_native_class->is_transform_handled = meta_crtc_kms_is_transform_handled; crtc_native_class->is_transform_handled = meta_crtc_kms_is_transform_handled;
crtc_native_class->is_hw_cursor_supported = meta_crtc_kms_is_hw_cursor_supported; crtc_native_class->is_hw_cursor_supported = meta_crtc_kms_is_hw_cursor_supported;
} }

View File

@ -38,6 +38,33 @@ meta_crtc_virtual_new (uint64_t id)
NULL); NULL);
} }
static void
meta_crtc_virtual_get_gamma_lut (MetaCrtc *crtc,
size_t *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{
if (size)
*size = 0;
if (red)
*red = NULL;
if (green)
*green = NULL;
if (blue)
*blue = NULL;
}
static void
meta_crtc_virtual_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{
g_warn_if_reached ();
}
static gboolean static gboolean
meta_crtc_virtual_is_transform_handled (MetaCrtcNative *crtc_native, meta_crtc_virtual_is_transform_handled (MetaCrtcNative *crtc_native,
MetaMonitorTransform transform) MetaMonitorTransform transform)
@ -59,8 +86,12 @@ meta_crtc_virtual_init (MetaCrtcVirtual *crtc_virtual)
static void static void
meta_crtc_virtual_class_init (MetaCrtcVirtualClass *klass) meta_crtc_virtual_class_init (MetaCrtcVirtualClass *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 = meta_crtc_virtual_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_virtual_set_gamma_lut;
crtc_native_class->is_transform_handled = crtc_native_class->is_transform_handled =
meta_crtc_virtual_is_transform_handled; meta_crtc_virtual_is_transform_handled;
crtc_native_class->is_hw_cursor_supported = crtc_native_class->is_hw_cursor_supported =

View File

@ -350,126 +350,6 @@ meta_monitor_manager_native_apply_monitors_config (MetaMonitorManager *ma
return TRUE; return TRUE;
} }
static void
meta_monitor_manager_native_get_crtc_gamma (MetaMonitorManager *manager,
MetaCrtc *crtc,
gsize *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{
MetaMonitorManagerNative *manager_native =
META_MONITOR_MANAGER_NATIVE (manager);
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtcGamma *crtc_gamma;
MetaKmsCrtc *kms_crtc;
const MetaKmsCrtcState *crtc_state;
if (!META_IS_CRTC_KMS (crtc))
{
if (size)
*size = 0;
if (red)
*red = NULL;
if (green)
*green = NULL;
if (blue)
*blue = NULL;
return;
}
crtc_gamma =
meta_monitor_manager_native_get_cached_crtc_gamma (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;
}
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
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);
}
static char *
generate_gamma_ramp_string (size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{
GString *string;
int color;
string = g_string_new ("[");
for (color = 0; color < 3; color++)
{
unsigned short **color_ptr = NULL;
char color_char;
size_t i;
switch (color)
{
case 0:
color_ptr = &red;
color_char = 'r';
break;
case 1:
color_ptr = &green;
color_char = 'g';
break;
case 2:
color_ptr = &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++)
{
int j;
if (size > 4)
{
if (i == 2)
g_string_append (string, ",...");
if (i >= 2)
j = i + (size - 4);
else
j = i;
}
else
{
j = i;
}
g_string_append_printf (string, "%s%hu",
j == 0 ? "" : ",",
(*color_ptr)[i]);
}
}
g_string_append (string, " ]");
return g_string_free (string, FALSE);
}
MetaKmsCrtcGamma * MetaKmsCrtcGamma *
meta_monitor_manager_native_get_cached_crtc_gamma (MetaMonitorManagerNative *manager_native, meta_monitor_manager_native_get_cached_crtc_gamma (MetaMonitorManagerNative *manager_native,
MetaCrtcKms *crtc_kms) MetaCrtcKms *crtc_kms)
@ -481,51 +361,16 @@ meta_monitor_manager_native_get_cached_crtc_gamma (MetaMonitorManagerNative *man
GUINT_TO_POINTER (crtc_id)); GUINT_TO_POINTER (crtc_id));
} }
static void void
meta_monitor_manager_native_set_crtc_gamma (MetaMonitorManager *manager, meta_monitor_manager_native_update_cached_crtc_gamma (MetaMonitorManagerNative *manager_native,
MetaCrtc *crtc, MetaCrtcKms *crtc_kms,
gsize size, MetaKmsCrtcGamma *crtc_gamma)
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{ {
MetaMonitorManagerNative *manager_native = MetaCrtc *crtc = META_CRTC (crtc_kms);
META_MONITOR_MANAGER_NATIVE (manager);
MetaCrtcKms *crtc_kms;
MetaKmsCrtc *kms_crtc;
const MetaKmsCrtcState *crtc_state;
g_autofree char *gamma_ramp_string = NULL;
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
g_return_if_fail (META_IS_CRTC_KMS (crtc));
crtc_kms = META_CRTC_KMS (crtc);
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
if (size != crtc_state->gamma.size)
{
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
g_warning ("Tried to set a different gamma LUT size on %u (%s)",
meta_kms_crtc_get_id (kms_crtc),
meta_kms_device_get_path (kms_device));
return;
}
g_hash_table_replace (manager_native->crtc_gamma_cache, g_hash_table_replace (manager_native->crtc_gamma_cache,
GUINT_TO_POINTER (meta_crtc_get_id (crtc)), GUINT_TO_POINTER (meta_crtc_get_id (crtc)),
meta_kms_crtc_gamma_new (kms_crtc, size, crtc_gamma);
red, green, blue));
gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
meta_topic (META_DEBUG_COLOR,
"Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
meta_crtc_get_id (crtc), gamma_ramp_string);
meta_crtc_kms_invalidate_gamma (crtc_kms);
clutter_stage_schedule_update (stage);
} }
static void static void
@ -902,10 +747,6 @@ meta_monitor_manager_native_class_init (MetaMonitorManagerNativeClass *klass)
meta_monitor_manager_native_apply_monitors_config; meta_monitor_manager_native_apply_monitors_config;
manager_class->set_power_save_mode = manager_class->set_power_save_mode =
meta_monitor_manager_native_set_power_save_mode; meta_monitor_manager_native_set_power_save_mode;
manager_class->get_crtc_gamma =
meta_monitor_manager_native_get_crtc_gamma;
manager_class->set_crtc_gamma =
meta_monitor_manager_native_set_crtc_gamma;
manager_class->is_transform_handled = manager_class->is_transform_handled =
meta_monitor_manager_native_is_transform_handled; meta_monitor_manager_native_is_transform_handled;
manager_class->calculate_monitor_mode_scale = manager_class->calculate_monitor_mode_scale =

View File

@ -46,4 +46,8 @@ uint64_t meta_power_save_to_dpms_state (MetaPowerSave power_save);
MetaKmsCrtcGamma * meta_monitor_manager_native_get_cached_crtc_gamma (MetaMonitorManagerNative *manager_native, MetaKmsCrtcGamma * meta_monitor_manager_native_get_cached_crtc_gamma (MetaMonitorManagerNative *manager_native,
MetaCrtcKms *crtc_kms); MetaCrtcKms *crtc_kms);
void meta_monitor_manager_native_update_cached_crtc_gamma (MetaMonitorManagerNative *manager_native,
MetaCrtcKms *crtc_kms,
MetaKmsCrtcGamma *gamma_lut);
#endif /* META_MONITOR_MANAGER_NATIVE_H */ #endif /* META_MONITOR_MANAGER_NATIVE_H */

View File

@ -297,6 +297,55 @@ meta_crtc_xrandr_new (MetaGpuXrandr *gpu_xrandr,
return crtc_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)
{
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;
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);
XRRFreeGamma (gamma);
}
static void
meta_crtc_xrandr_set_gamma_lut (MetaCrtc *crtc,
size_t size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{
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;
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);
XRRSetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc), gamma);
XRRFreeGamma (gamma);
}
static void static void
meta_crtc_xrandr_init (MetaCrtcXrandr *crtc_xrandr) meta_crtc_xrandr_init (MetaCrtcXrandr *crtc_xrandr)
{ {
@ -305,4 +354,8 @@ meta_crtc_xrandr_init (MetaCrtcXrandr *crtc_xrandr)
static void static void
meta_crtc_xrandr_class_init (MetaCrtcXrandrClass *klass) meta_crtc_xrandr_class_init (MetaCrtcXrandrClass *klass)
{ {
MetaCrtcClass *crtc_class = META_CRTC_CLASS (klass);
crtc_class->get_gamma_lut = meta_crtc_xrandr_get_gamma_lut;
crtc_class->set_gamma_lut = meta_crtc_xrandr_set_gamma_lut;
} }

View File

@ -660,54 +660,6 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
meta_output_xrandr_change_backlight (META_OUTPUT_XRANDR (output), value); meta_output_xrandr_change_backlight (META_OUTPUT_XRANDR (output), value);
} }
static void
meta_monitor_manager_xrandr_get_crtc_gamma (MetaMonitorManager *manager,
MetaCrtc *crtc,
gsize *size,
unsigned short **red,
unsigned short **green,
unsigned short **blue)
{
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
XRRCrtcGamma *gamma;
gamma = XRRGetCrtcGamma (manager_xrandr->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);
XRRFreeGamma (gamma);
}
static void
meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
MetaCrtc *crtc,
gsize size,
unsigned short *red,
unsigned short *green,
unsigned short *blue)
{
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
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);
XRRSetCrtcGamma (manager_xrandr->xdisplay,
(XID) meta_crtc_get_id (crtc),
gamma);
XRRFreeGamma (gamma);
}
static MetaMonitorXrandrData * static MetaMonitorXrandrData *
meta_monitor_xrandr_data_from_monitor (MetaMonitor *monitor) meta_monitor_xrandr_data_from_monitor (MetaMonitor *monitor)
{ {
@ -1015,8 +967,6 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
manager_class->apply_monitors_config = meta_monitor_manager_xrandr_apply_monitors_config; manager_class->apply_monitors_config = meta_monitor_manager_xrandr_apply_monitors_config;
manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode; manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode;
manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight; manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma;
manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma;
manager_class->tiled_monitor_added = meta_monitor_manager_xrandr_tiled_monitor_added; manager_class->tiled_monitor_added = meta_monitor_manager_xrandr_tiled_monitor_added;
manager_class->tiled_monitor_removed = meta_monitor_manager_xrandr_tiled_monitor_removed; manager_class->tiled_monitor_removed = meta_monitor_manager_xrandr_tiled_monitor_removed;
manager_class->is_transform_handled = meta_monitor_manager_xrandr_is_transform_handled; manager_class->is_transform_handled = meta_monitor_manager_xrandr_is_transform_handled;