summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Wick <sebastian.wick@redhat.com>2023-03-02 01:35:10 +0100
committerMarge Bot <marge-bot@gnome.org>2023-03-04 09:30:41 +0000
commit48e759c4430e94c5405a2726645c9560f8a071d2 (patch)
tree7b10fbb92d2a47ed519dc2f52aef334963c639c1
parentfad0efa687e560a4d104a4537fe5d287d72e18f7 (diff)
downloadmutter-48e759c4430e94c5405a2726645c9560f8a071d2.tar.gz
monitor-manager: Make color space and HDR metadata accessible from lg
This adds a new 'experimental-hdr' string property to the MonitorManager which can be changed from looking glass. Currently when the string equals 'on', HDR (PQ, Rec2020) will be enabled on all monitors which support it. In the future support for more transfer functions and color spaces as well as HDR metadata can be added. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2879>
-rw-r--r--src/backends/meta-monitor-manager.c89
-rw-r--r--src/backends/meta-monitor.c60
-rw-r--r--src/backends/meta-monitor.h8
3 files changed, 157 insertions, 0 deletions
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 3a09782a1..19cbb263d 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -73,6 +73,7 @@ enum
PROP_PANEL_ORIENTATION_MANAGED,
PROP_HAS_BUILTIN_PANEL,
PROP_NIGHT_LIGHT_SUPPORTED,
+ PROP_EXPERIMENTAL_HDR,
PROP_LAST
};
@@ -114,6 +115,7 @@ typedef struct _MetaMonitorManagerPrivate
gboolean has_builtin_panel;
gboolean night_light_supported;
+ const char *experimental_hdr;
} MetaMonitorManagerPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitorManager, meta_monitor_manager,
@@ -477,6 +479,71 @@ prepare_shutdown (MetaBackend *backend,
priv->shutting_down = TRUE;
}
+static void
+ensure_hdr_settings (MetaMonitorManager *manager)
+{
+ MetaMonitorManagerPrivate *priv =
+ meta_monitor_manager_get_instance_private (manager);
+ MetaOutputColorspace color_space;
+ MetaOutputHdrMetadata hdr_metadata;
+ GList *l;
+
+ if (g_strcmp0 (priv->experimental_hdr, "on") == 0)
+ {
+ color_space = META_OUTPUT_COLORSPACE_BT2020;
+ hdr_metadata = (MetaOutputHdrMetadata) {
+ .active = TRUE,
+ .eotf = META_OUTPUT_HDR_METADATA_EOTF_PQ,
+ };
+ }
+ else
+ {
+ color_space = META_OUTPUT_COLORSPACE_DEFAULT;
+ hdr_metadata = (MetaOutputHdrMetadata) {
+ .active = FALSE,
+ };
+ }
+
+ for (l = manager->monitors; l; l = l->next)
+ {
+ MetaMonitor *monitor = l->data;
+ g_autoptr (GError) error = NULL;
+
+ if (!meta_monitor_set_color_space (monitor, color_space, &error))
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
+ continue;
+
+ g_warning ("Failed to set color space on monitor %s: %s",
+ meta_monitor_get_display_name (monitor), error->message);
+
+ meta_monitor_set_color_space (monitor,
+ META_OUTPUT_COLORSPACE_UNKNOWN,
+ NULL);
+
+ continue;
+ }
+
+ if (!meta_monitor_set_hdr_metadata (monitor, &hdr_metadata, &error))
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
+ continue;
+
+ g_warning ("Failed to set HDR metadata on monitor %s: %s",
+ meta_monitor_get_display_name (monitor), error->message);
+
+ meta_monitor_set_color_space (monitor,
+ META_OUTPUT_COLORSPACE_UNKNOWN,
+ NULL);
+ meta_monitor_set_hdr_metadata (monitor, &(MetaOutputHdrMetadata) {
+ .active = FALSE,
+ }, NULL);
+
+ continue;
+ }
+ }
+}
+
/**
* meta_monitor_manager_is_headless:
* @manager: A #MetaMonitorManager object
@@ -1262,6 +1329,10 @@ meta_monitor_manager_constructed (GObject *object)
G_CALLBACK (prepare_shutdown),
manager);
+ g_signal_connect (manager, "notify::experimental-hdr",
+ G_CALLBACK (ensure_hdr_settings),
+ NULL);
+
manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
initialize_dbus_interface (manager);
@@ -1314,12 +1385,17 @@ meta_monitor_manager_set_property (GObject *object,
GParamSpec *pspec)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
+ MetaMonitorManagerPrivate *priv =
+ meta_monitor_manager_get_instance_private (manager);
switch (prop_id)
{
case PROP_BACKEND:
manager->backend = g_value_get_object (value);
break;
+ case PROP_EXPERIMENTAL_HDR:
+ priv->experimental_hdr = g_value_dup_string (value);
+ break;
case PROP_PANEL_ORIENTATION_MANAGED:
case PROP_HAS_BUILTIN_PANEL:
case PROP_NIGHT_LIGHT_SUPPORTED:
@@ -1352,6 +1428,9 @@ meta_monitor_manager_get_property (GObject *object,
case PROP_NIGHT_LIGHT_SUPPORTED:
g_value_set_boolean (value, priv->night_light_supported);
break;
+ case PROP_EXPERIMENTAL_HDR:
+ g_value_set_string (value, priv->experimental_hdr);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -1454,6 +1533,14 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS);
+ obj_props[PROP_EXPERIMENTAL_HDR] =
+ g_param_spec_string ("experimental-hdr",
+ "Experimental HDR",
+ "Experimental HDR settings string",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
}
@@ -3597,6 +3684,8 @@ meta_monitor_manager_rebuild (MetaMonitorManager *manager,
ensure_privacy_screen_settings (manager);
+ ensure_hdr_settings (manager);
+
g_list_free_full (old_logical_monitors, g_object_unref);
}
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index 289d0c620..c1315e84e 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -2242,3 +2242,63 @@ meta_monitor_set_privacy_screen_enabled (MetaMonitor *monitor,
return meta_output_set_privacy_screen_enabled (output, enabled, error);
}
+
+gboolean
+meta_monitor_set_color_space (MetaMonitor *monitor,
+ MetaOutputColorspace color_space,
+ GError **error)
+{
+ MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+ GList *l;
+
+ for (l = priv->outputs; l; l = l->next)
+ {
+ MetaOutput *output = l->data;
+
+ if (!meta_output_is_color_space_supported (output, color_space))
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "The color space is not supported by this monitor");
+ return FALSE;
+ }
+ }
+
+ for (l = priv->outputs; l; l = l->next)
+ {
+ MetaOutput *output = l->data;
+
+ meta_output_set_color_space (output, color_space);
+ }
+
+ return TRUE;
+}
+
+gboolean
+meta_monitor_set_hdr_metadata (MetaMonitor *monitor,
+ MetaOutputHdrMetadata *metadata,
+ GError **error)
+{
+ MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+ GList *l;
+
+ for (l = priv->outputs; l; l = l->next)
+ {
+ MetaOutput *output = l->data;
+
+ if (!meta_output_is_hdr_metadata_supported (output))
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "HDR metadata is not supported by this monitor");
+ return FALSE;
+ }
+ }
+
+ for (l = priv->outputs; l; l = l->next)
+ {
+ MetaOutput *output = l->data;
+
+ meta_output_set_hdr_metadata (output, metadata);
+ }
+
+ return TRUE;
+}
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index 3f98a58f6..bccfccbfa 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -310,4 +310,12 @@ size_t meta_monitor_get_gamma_lut_size (MetaMonitor *monitor);
void meta_monitor_set_gamma_lut (MetaMonitor *monitor,
const MetaGammaLut *lut);
+gboolean meta_monitor_set_color_space (MetaMonitor *monitor,
+ MetaOutputColorspace color_space,
+ GError **error);
+
+gboolean meta_monitor_set_hdr_metadata (MetaMonitor *monitor,
+ MetaOutputHdrMetadata *metadata,
+ GError **error);
+
#endif /* META_MONITOR_H */