From e3afa1a1d18cad490c59b0ad5ff30e8fe45e9464 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Thu, 25 Jul 2024 17:01:09 +0200 Subject: [PATCH] color-device: Apply HDR and colorspace calibration The color device now updates the white point via a LUT and sets the colorspace and HDR metadata properties on monitors to get into the required configuration. Part-of: --- src/backends/meta-color-device.c | 123 +++++++++++++++++++++++ src/backends/meta-monitor-manager.c | 145 +++------------------------- 2 files changed, 135 insertions(+), 133 deletions(-) diff --git a/src/backends/meta-color-device.c b/src/backends/meta-color-device.c index 6fbd0ec3a..f7bf9339d 100644 --- a/src/backends/meta-color-device.c +++ b/src/backends/meta-color-device.c @@ -29,6 +29,7 @@ #include "backends/meta-color-profile.h" #include "backends/meta-color-store.h" #include "backends/meta-monitor.h" +#include "core/meta-debug-control-private.h" #define EFI_PANEL_COLOR_INFO_PATH \ "/sys/firmware/efi/efivars/INTERNAL_PANEL_COLOR_INFO-01e1ada1-79f2-46b3-8d3e-71fc0996ca6b" @@ -1348,6 +1349,127 @@ meta_color_device_get_assigned_profile (MetaColorDevice *color_device) return color_device->assigned_profile; } +static void +set_color_space_and_hdr_metadata (MetaMonitor *monitor, + gboolean enable, + MetaOutputColorspace *color_space, + MetaOutputHdrMetadata *hdr_metadata) +{ + MetaBackend *backend = meta_monitor_get_backend (monitor); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + + if (enable && + !cogl_context_has_feature (cogl_context, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT)) + { + g_warning ("Tried to enable HDR without half float rendering support, ignoring"); + enable = FALSE; + } + + if (enable) + { + *color_space = META_OUTPUT_COLORSPACE_BT2020; + *hdr_metadata = (MetaOutputHdrMetadata) { + .active = TRUE, + .eotf = META_OUTPUT_HDR_METADATA_EOTF_PQ, + }; + + meta_topic (META_DEBUG_COLOR, + "ColorDevice: Trying to enabling HDR mode " + "(Colorimetry: bt.2020, TF: PQ, HDR Metadata: Minimal):"); + } + else + { + *color_space = META_OUTPUT_COLORSPACE_DEFAULT; + *hdr_metadata = (MetaOutputHdrMetadata) { + .active = FALSE, + }; + + meta_topic (META_DEBUG_COLOR, + "ColorDevice: Trying to enable default mode " + "(Colorimetry: default, TF: default, HDR Metadata: None):"); + } +} + +static UpdateResult +update_hdr (MetaColorDevice *color_device) +{ + MetaMonitor *monitor = color_device->monitor; + MetaBackend *backend = meta_monitor_get_backend (monitor); + MetaContext *context = meta_backend_get_context (backend); + MetaDebugControl *debug_control = meta_context_get_debug_control (context); + MetaOutputColorspace color_space; + MetaOutputHdrMetadata hdr_metadata; + gboolean hdr_enabled; + g_autoptr (GError) error = NULL; + + hdr_enabled = meta_debug_control_is_hdr_enabled (debug_control); + set_color_space_and_hdr_metadata (monitor, hdr_enabled, + &color_space, &hdr_metadata); + + if (meta_monitor_get_color_space (monitor) == color_space && + meta_output_hdr_metadata_equal (meta_monitor_get_hdr_metadata (monitor), + &hdr_metadata)) + return 0; + + if (!meta_monitor_set_color_space (monitor, color_space, &error)) + { + meta_monitor_set_color_space (monitor, + META_OUTPUT_COLORSPACE_DEFAULT, + NULL); + meta_monitor_set_hdr_metadata (monitor, &(MetaOutputHdrMetadata) { + .active = FALSE, + }, NULL); + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + meta_topic (META_DEBUG_COLOR, + "ColorDevice: Colorimetry not supported " + "on monitor %s", + meta_monitor_get_display_name (monitor)); + } + else + { + g_warning ("Failed to set color space on monitor %s: %s", + meta_monitor_get_display_name (monitor), error->message); + } + + return 0; + } + + if (!meta_monitor_set_hdr_metadata (monitor, &hdr_metadata, &error)) + { + meta_monitor_set_color_space (monitor, + META_OUTPUT_COLORSPACE_DEFAULT, + NULL); + meta_monitor_set_hdr_metadata (monitor, &(MetaOutputHdrMetadata) { + .active = FALSE, + }, NULL); + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + meta_topic (META_DEBUG_COLOR, + "ColorDevice: HDR Metadata not supported " + "on monitor %s", + meta_monitor_get_display_name (monitor)); + } + else + { + g_warning ("Failed to set HDR metadata on monitor %s: %s", + meta_monitor_get_display_name (monitor), + error->message); + } + + return 0; + } + + meta_topic (META_DEBUG_COLOR, + "ColorDevice: successfully set on monitor %s", + meta_monitor_get_display_name (monitor)); + + return UPDATE_RESULT_CALIBRATION; +} + static UpdateResult update_white_point (MetaColorDevice *color_device) { @@ -1414,6 +1536,7 @@ meta_color_device_update (MetaColorDevice *color_device) if (!meta_monitor_is_active (monitor)) return; + result |= update_hdr (color_device); result |= update_white_point (color_device); result |= update_color_state (color_device); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 4ac2b5056..30659dcbe 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -55,7 +55,6 @@ #include "backends/meta-output.h" #include "backends/meta-virtual-monitor.h" #include "clutter/clutter.h" -#include "core/meta-debug-control-private.h" #include "core/util-private.h" #include "meta/main.h" #include "meta/meta-enum-types.h" @@ -489,125 +488,6 @@ prepare_shutdown (MetaBackend *backend, g_clear_handle_id (&priv->reload_monitor_manager_id, g_source_remove); } -static void -set_color_space_and_hdr_metadata (MetaMonitorManager *manager, - gboolean enable, - MetaOutputColorspace *color_space, - MetaOutputHdrMetadata *hdr_metadata) -{ - MetaBackend *backend = meta_monitor_manager_get_backend (manager); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); - - if (enable && - !cogl_context_has_feature (cogl_context, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT)) - { - g_warning ("Tried to enable HDR without half float rendering support, ignoring"); - enable = FALSE; - } - - if (enable) - { - *color_space = META_OUTPUT_COLORSPACE_BT2020; - *hdr_metadata = (MetaOutputHdrMetadata) { - .active = TRUE, - .eotf = META_OUTPUT_HDR_METADATA_EOTF_PQ, - }; - - meta_topic (META_DEBUG_COLOR, - "MonitorManager: Trying to enabling HDR mode " - "(Colorimetry: bt.2020, TF: PQ, HDR Metadata: Minimal):"); - } - else - { - *color_space = META_OUTPUT_COLORSPACE_DEFAULT; - *hdr_metadata = (MetaOutputHdrMetadata) { - .active = FALSE, - }; - - meta_topic (META_DEBUG_COLOR, - "MonitorManager: Trying to enable default mode " - "(Colorimetry: default, TF: default, HDR Metadata: None):"); - } -} - -static void -ensure_hdr_settings (MetaMonitorManager *manager) -{ - MetaBackend *backend = manager->backend; - MetaContext *context = meta_backend_get_context (backend); - MetaDebugControl *debug_control = meta_context_get_debug_control (context); - MetaOutputColorspace color_space; - MetaOutputHdrMetadata hdr_metadata; - GList *l; - - set_color_space_and_hdr_metadata (manager, - meta_debug_control_is_hdr_enabled (debug_control), - &color_space, - &hdr_metadata); - - 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)) - { - meta_monitor_set_color_space (monitor, - META_OUTPUT_COLORSPACE_DEFAULT, - NULL); - meta_monitor_set_hdr_metadata (monitor, &(MetaOutputHdrMetadata) { - .active = FALSE, - }, NULL); - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) - { - meta_topic (META_DEBUG_COLOR, - "MonitorManager: Colorimetry not supported " - "on monitor %s", - meta_monitor_get_display_name (monitor)); - } - else - { - g_warning ("Failed to set color space on monitor %s: %s", - meta_monitor_get_display_name (monitor), error->message); - } - - continue; - } - - if (!meta_monitor_set_hdr_metadata (monitor, &hdr_metadata, &error)) - { - meta_monitor_set_color_space (monitor, - META_OUTPUT_COLORSPACE_DEFAULT, - NULL); - meta_monitor_set_hdr_metadata (monitor, &(MetaOutputHdrMetadata) { - .active = FALSE, - }, NULL); - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) - { - meta_topic (META_DEBUG_COLOR, - "MonitorManager: HDR Metadata not supported " - "on monitor %s", - meta_monitor_get_display_name (monitor)); - } - else - { - g_warning ("Failed to set HDR metadata on monitor %s: %s", - meta_monitor_get_display_name (monitor), - error->message); - } - - continue; - } - - meta_topic (META_DEBUG_COLOR, - "MonitorManager: successfully set on monitor %s", - meta_monitor_get_display_name (monitor)); - } -} - /** * meta_monitor_manager_is_headless: * @manager: A #MetaMonitorManager object @@ -1323,6 +1203,17 @@ update_night_light_supported (MetaMonitorManager *manager) night_light_supported); } +static void +meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager) +{ + meta_backend_monitors_changed (manager->backend); + + g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0); + g_signal_emit (manager, signals[MONITORS_CHANGED], 0); + + meta_dbus_display_config_emit_monitors_changed (manager->display_config); +} + void meta_monitor_manager_setup (MetaMonitorManager *manager) { @@ -1350,7 +1241,7 @@ meta_monitor_manager_setup (MetaMonitorManager *manager) if (privacy_screen_needs_update (manager)) manager->privacy_screen_change_state = META_PRIVACY_SCREEN_CHANGE_STATE_INIT; - ensure_hdr_settings (manager); + meta_monitor_manager_notify_monitors_changed (manager); manager->in_init = FALSE; } @@ -3688,17 +3579,6 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager) manager_class->read_current_state (manager); } -static void -meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager) -{ - meta_backend_monitors_changed (manager->backend); - - g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0); - g_signal_emit (manager, signals[MONITORS_CHANGED], 0); - - meta_dbus_display_config_emit_monitors_changed (manager->display_config); -} - static void set_logical_monitor_modes (MetaMonitorManager *manager, MetaLogicalMonitorConfig *logical_monitor_config) @@ -3780,7 +3660,6 @@ meta_monitor_manager_rebuild (MetaMonitorManager *manager, meta_monitor_manager_update_logical_state (manager, config); ensure_privacy_screen_settings (manager); - ensure_hdr_settings (manager); meta_monitor_manager_notify_monitors_changed (manager);