diff --git a/data/dbus-interfaces/org.gnome.Mutter.DebugControl.xml b/data/dbus-interfaces/org.gnome.Mutter.DebugControl.xml index 2ac0089de..e00444e58 100644 --- a/data/dbus-interfaces/org.gnome.Mutter.DebugControl.xml +++ b/data/dbus-interfaces/org.gnome.Mutter.DebugControl.xml @@ -6,7 +6,6 @@ - diff --git a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml index c5d97d554..43b46f451 100644 --- a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml +++ b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml @@ -393,6 +393,7 @@ Variable Refresh Rate is active (absence of this means unknown) - "is-for-lease" (b): whether the monitor is for lease or not + - "color-mode" (u): current color mode - "supported-color-modes" (au): list of supported color modes Possible mode flags: @@ -499,6 +500,8 @@ - "underscanning" (b): enable monitor underscanning; may only be set when underscanning is supported (see GetCurrentState). + - "color-mode" (u): selected color mode. Defaults to + "default". See GetCurrentState(). @properties may effect the global monitor configuration state. Possible properties are: diff --git a/src/backends/meta-color-device.c b/src/backends/meta-color-device.c index 04a130e69..9d99e8c12 100644 --- a/src/backends/meta-color-device.c +++ b/src/backends/meta-color-device.c @@ -626,61 +626,27 @@ on_manager_ready (MetaColorManager *color_manager, create_cd_device (color_device); } -static ClutterColorimetry -get_colorimetry_from_monitor (MetaMonitor *monitor) +static void +get_color_metadata_from_monitor (MetaMonitor *monitor, + ClutterColorimetry *colorimetry, + ClutterEOTF *eotf) { - ClutterColorimetry colorimetry; + colorimetry->type = CLUTTER_COLORIMETRY_TYPE_COLORSPACE; + eotf->type = CLUTTER_EOTF_TYPE_NAMED; - colorimetry.type = CLUTTER_COLORIMETRY_TYPE_COLORSPACE; - - switch (meta_monitor_get_color_space (monitor)) + switch (meta_monitor_get_color_mode (monitor)) { - case META_OUTPUT_COLORSPACE_DEFAULT: - case META_OUTPUT_COLORSPACE_UNKNOWN: - colorimetry.colorspace = CLUTTER_COLORSPACE_SRGB; - break; - case META_OUTPUT_COLORSPACE_BT2020: - colorimetry.colorspace = CLUTTER_COLORSPACE_BT2020; - break; + case META_COLOR_MODE_DEFAULT: + colorimetry->colorspace = CLUTTER_COLORSPACE_SRGB; + eotf->tf_name = CLUTTER_TRANSFER_FUNCTION_SRGB; + return; + case META_COLOR_MODE_BT2100: + colorimetry->colorspace = CLUTTER_COLORSPACE_BT2020; + eotf->tf_name = CLUTTER_TRANSFER_FUNCTION_PQ; + return; } - return colorimetry; -} - -static ClutterEOTF -get_eotf_from_monitor (MetaMonitor *monitor) -{ - ClutterEOTF eotf; - const MetaOutputHdrMetadata *hdr_metadata = - meta_monitor_get_hdr_metadata (monitor); - - eotf.type = CLUTTER_EOTF_TYPE_NAMED; - - if (!hdr_metadata->active) - { - eotf.tf_name = CLUTTER_TRANSFER_FUNCTION_SRGB; - return eotf; - } - - switch (hdr_metadata->eotf) - { - case META_OUTPUT_HDR_METADATA_EOTF_PQ: - eotf.tf_name = CLUTTER_TRANSFER_FUNCTION_PQ; - break; - case META_OUTPUT_HDR_METADATA_EOTF_TRADITIONAL_GAMMA_SDR: - eotf.tf_name = CLUTTER_TRANSFER_FUNCTION_SRGB; - break; - case META_OUTPUT_HDR_METADATA_EOTF_TRADITIONAL_GAMMA_HDR: - g_warning ("Unhandled HDR EOTF (traditional gamma hdr)"); - eotf.tf_name = CLUTTER_TRANSFER_FUNCTION_SRGB; - break; - case META_OUTPUT_HDR_METADATA_EOTF_HLG: - g_warning ("Unhandled HDR EOTF (HLG)"); - eotf.tf_name = CLUTTER_TRANSFER_FUNCTION_SRGB; - break; - } - - return eotf; + g_assert_not_reached (); } static UpdateResult @@ -699,8 +665,7 @@ update_color_state (MetaColorDevice *color_device) float reference_luminance_factor; UpdateResult result = 0; - colorimetry = get_colorimetry_from_monitor (monitor); - eotf = get_eotf_from_monitor (monitor); + get_color_metadata_from_monitor (monitor, &colorimetry, &eotf); if (meta_debug_control_is_hdr_forced (debug_control)) { @@ -1401,127 +1366,6 @@ 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) { @@ -1588,7 +1432,6 @@ 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-config-manager.c b/src/backends/meta-monitor-config-manager.c index 8ef8470b4..5228b73fc 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -290,6 +290,7 @@ assign_monitor_crtc (MetaMonitor *monitor, .has_max_bpc = data->monitor_config->has_max_bpc, .max_bpc = data->monitor_config->max_bpc, .rgb_range = data->monitor_config->rgb_range, + .color_mode = data->monitor_config->color_mode, }; g_ptr_array_add (data->crtc_assignments, crtc_assignment); @@ -658,7 +659,8 @@ find_primary_monitor (MetaMonitorManager *monitor_manager, static MetaMonitorConfig * create_monitor_config (MetaMonitor *monitor, - MetaMonitorMode *mode) + MetaMonitorMode *mode, + MetaColorMode color_mode) { MetaMonitorSpec *monitor_spec; MetaMonitorModeSpec *mode_spec; @@ -673,6 +675,7 @@ create_monitor_config (MetaMonitor *monitor, .mode_spec = g_memdup2 (mode_spec, sizeof (MetaMonitorModeSpec)), .enable_underscanning = meta_monitor_is_underscanning (monitor), .rgb_range = meta_monitor_get_rgb_range (monitor), + .color_mode = color_mode, }; monitor_config->has_max_bpc = @@ -724,12 +727,13 @@ scale_logical_monitor_width (MetaLogicalMonitorLayoutMode layout_mode, } static MetaLogicalMonitorConfig * -create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager, - MetaMonitor *monitor, - int x, - int y, - float scale, - MetaLogicalMonitorLayoutMode layout_mode) +create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager, + MetaMonitor *monitor, + int x, + int y, + float scale, + MetaColorMode color_mode, + MetaLogicalMonitorLayoutMode layout_mode) { MetaMonitorMode *mode; int width, height; @@ -742,7 +746,7 @@ create_preferred_logical_monitor_config (MetaMonitorManager *monitor_ma scale_logical_monitor_width (layout_mode, scale, width, height, &width, &height); - monitor_config = create_monitor_config (monitor, mode); + monitor_config = create_monitor_config (monitor, mode, color_mode); transform = get_monitor_transform (monitor_manager, monitor); if (mtk_monitor_transform_is_rotated (transform)) @@ -802,6 +806,32 @@ find_logical_monitor_config (MetaMonitorsConfig *config, return NULL; } +static MetaMonitorConfig * +find_monitor_config (MetaMonitorsConfig *config, + MetaMonitor *monitor) +{ + GList *l; + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + GList *l_monitor; + + for (l_monitor = logical_monitor_config->monitor_configs; + l_monitor; + l_monitor = l_monitor->next) + { + MetaMonitorConfig *monitor_config = l_monitor->data; + + if (meta_monitor_spec_equals (meta_monitor_get_spec (monitor), + monitor_config->monitor_spec)) + return monitor_config; + } + } + + return NULL; +} + static GList * get_relevant_configs (MetaMonitorConfigManager *config_manager) { @@ -875,6 +905,32 @@ compute_scale_for_monitor (MetaMonitorConfigManager *config_manager, monitor_mode); } +static gboolean +get_last_color_mode_for_monitor (MetaMonitorConfigManager *config_manager, + MetaMonitor *monitor, + MetaColorMode *out_color_mode) +{ + g_autoptr (GList) configs = NULL; + GList *l; + + configs = get_relevant_configs (config_manager); + + for (l = configs; l; l = l->next) + { + MetaMonitorsConfig *config = l->data; + MetaMonitorConfig *monitor_config; + + monitor_config = find_monitor_config (config, monitor); + if (monitor_config) + { + *out_color_mode = monitor_config->color_mode; + return TRUE; + } + } + + return FALSE; +} + typedef enum _MonitorPositioningMode { MONITOR_POSITIONING_LINEAR, @@ -953,6 +1009,7 @@ create_monitors_config (MetaMonitorConfigManager *config_manager, MetaMonitor *monitor = l->data; MetaLogicalMonitorConfig *logical_monitor_config; gboolean has_suggested_position; + MetaColorMode color_mode; switch (positioning) { @@ -967,10 +1024,15 @@ create_monitors_config (MetaMonitorConfigManager *config_manager, scale = compute_scale_for_monitor (config_manager, monitor, primary_monitor); + if (!get_last_color_mode_for_monitor (config_manager, monitor, + &color_mode)) + color_mode = META_COLOR_MODE_DEFAULT; + logical_monitor_config = create_preferred_logical_monitor_config (monitor_manager, monitor, x, y, scale, + color_mode, layout_mode); logical_monitor_config->is_primary = (monitor == primary_monitor); logical_monitor_configs = g_list_append (logical_monitor_configs, @@ -1262,6 +1324,7 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager) { MetaMonitor *other_monitor = l->data; MetaMonitorMode *mode = NULL; + MetaColorMode color_mode; GList *ll; float scale; @@ -1282,7 +1345,16 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager) scale = compute_scale_for_monitor (config_manager, other_monitor, primary_monitor); best_scale = MAX (best_scale, scale); - monitor_configs = g_list_prepend (monitor_configs, create_monitor_config (other_monitor, mode)); + + if (!get_last_color_mode_for_monitor (config_manager, monitor, + &color_mode)) + color_mode = META_COLOR_MODE_DEFAULT; + + monitor_configs = + g_list_prepend (monitor_configs, + create_monitor_config (other_monitor, + mode, + color_mode)); } scale_logical_monitor_width (layout_mode, best_scale, diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h index f033ac655..c0981b634 100644 --- a/src/backends/meta-monitor-config-manager.h +++ b/src/backends/meta-monitor-config-manager.h @@ -34,6 +34,7 @@ typedef struct _MetaMonitorConfig gboolean has_max_bpc; unsigned int max_bpc; MetaOutputRGBRange rgb_range; + MetaColorMode color_mode; } MetaMonitorConfig; typedef struct _MetaLogicalMonitorConfig diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c index eb22dc3f3..8b862977d 100644 --- a/src/backends/meta-monitor-config-store.c +++ b/src/backends/meta-monitor-config-store.c @@ -165,6 +165,7 @@ typedef enum STATE_MONITOR_UNDERSCANNING, STATE_MONITOR_MAXBPC, STATE_MONITOR_RGB_RANGE, + STATE_MONITOR_COLOR_MODE, STATE_DISABLED, STATE_FOR_LEASE, STATE_POLICY, @@ -464,6 +465,10 @@ handle_start_element (GMarkupParseContext *context, { parser->state = STATE_MONITOR_RGB_RANGE; } + else if (g_str_equal (element_name, "colormode")) + { + parser->state = STATE_MONITOR_COLOR_MODE; + } else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, @@ -576,6 +581,13 @@ handle_start_element (GMarkupParseContext *context, return; } + case STATE_MONITOR_COLOR_MODE: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid element '%s' under colormode", element_name); + return; + } + case STATE_DISABLED: { if (!g_str_equal (element_name, "monitorspec")) @@ -1435,6 +1447,14 @@ handle_end_element (GMarkupParseContext *context, return; } + case STATE_MONITOR_COLOR_MODE: + { + g_assert (g_str_equal (element_name, "colormode")); + + parser->state = STATE_MONITOR; + return; + } + case STATE_MONITOR: { MetaLogicalMonitorConfig *logical_monitor_config; @@ -2045,6 +2065,26 @@ handle_text (GMarkupParseContext *context, return; } + case STATE_MONITOR_COLOR_MODE: + { + if (text_equals (text, text_len, "default")) + { + parser->current_monitor_config->color_mode = + META_COLOR_MODE_DEFAULT; + } + else if (text_equals (text, text_len, "bt2100")) + { + parser->current_monitor_config->color_mode = + META_COLOR_MODE_BT2100; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid color mode %.*s", (int)text_len, text); + } + return; + } + case STATE_STORE: { MetaConfigStore store; @@ -2219,6 +2259,28 @@ append_rgb_range (GString *buffer, rgb_range_str); } +static void +append_color_mode (GString *buffer, + MetaColorMode rgb_range, + const char *indentation) +{ + const char *color_mode_str; + + switch (rgb_range) + { + case META_COLOR_MODE_BT2100: + color_mode_str = "bt2100"; + break; + case META_COLOR_MODE_DEFAULT: + default: + return; + } + + g_string_append_printf (buffer, "%s%s\n", + indentation, + color_mode_str); +} + static void append_monitors (GString *buffer, GList *monitor_configs) @@ -2251,6 +2313,7 @@ append_monitors (GString *buffer, if (monitor_config->enable_underscanning) g_string_append (buffer, " yes\n"); append_rgb_range (buffer, monitor_config->rgb_range, " "); + append_color_mode (buffer, monitor_config->color_mode, " "); if (monitor_config->has_max_bpc) { diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index 66492c2a5..1f129f685 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -34,6 +34,7 @@ #include "backends/meta-crtc.h" #include "backends/meta-cursor.h" #include "backends/meta-display-config-shared.h" +#include "backends/meta-output.h" #include "backends/meta-viewport-info.h" #include "core/util-private.h" #include "meta/display.h" @@ -107,6 +108,7 @@ struct _MetaOutputAssignment gboolean has_max_bpc; unsigned int max_bpc; unsigned int rgb_range; + MetaColorMode color_mode; }; /* diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index c8700c66f..35c184162 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -2050,6 +2050,7 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, GList *k; gboolean is_builtin; gboolean is_for_lease; + MetaColorMode color_mode; const char *display_name; current_mode = meta_monitor_get_current_mode (monitor); @@ -2176,6 +2177,11 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, "is-for-lease", g_variant_new_boolean (is_for_lease)); + color_mode = meta_monitor_get_color_mode (monitor); + g_variant_builder_add (&monitor_properties_builder, "{sv}", + "color-mode", + g_variant_new_uint32 (color_mode)); + g_variant_builder_add (&monitor_properties_builder, "{sv}", "supported-color-modes", generate_color_modes_variant (monitor)); @@ -2471,6 +2477,8 @@ create_monitor_config_from_variant (MetaMonitorManager *manager, g_autoptr (GVariant) properties_variant = NULL; gboolean enable_underscanning = FALSE; gboolean set_underscanning = FALSE; + MetaColorMode color_mode = META_COLOR_MODE_DEFAULT; + uint32_t color_mode_value; g_variant_get (monitor_config_variant, "(ss@a{sv})", &connector, @@ -2506,6 +2514,10 @@ create_monitor_config_from_variant (MetaMonitorManager *manager, } } + if (g_variant_lookup (properties_variant, "color-mode", "u", + &color_mode_value)) + color_mode = color_mode_value; + monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor)); monitor_mode_spec = g_new0 (MetaMonitorModeSpec, 1); @@ -2515,7 +2527,8 @@ create_monitor_config_from_variant (MetaMonitorManager *manager, *monitor_config = (MetaMonitorConfig) { .monitor_spec = monitor_spec, .mode_spec = monitor_mode_spec, - .enable_underscanning = enable_underscanning + .enable_underscanning = enable_underscanning, + .color_mode = color_mode, }; return monitor_config; diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c index 01a2b201a..8f56e794b 100644 --- a/src/backends/meta-monitor.c +++ b/src/backends/meta-monitor.c @@ -2310,84 +2310,6 @@ meta_monitor_get_min_refresh_rate (MetaMonitor *monitor, min_refresh_rate); } -MetaOutputColorspace -meta_monitor_get_color_space (MetaMonitor *monitor) -{ - MetaOutput *output = meta_monitor_get_main_output (monitor); - - return meta_output_peek_color_space (output); -} - -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; - const MetaOutputInfo *output_info = meta_output_get_info (output); - - if (!(output_info->supported_color_spaces & (1 << 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; -} - -MetaOutputHdrMetadata * -meta_monitor_get_hdr_metadata (MetaMonitor *monitor) -{ - MetaOutput *output = meta_monitor_get_main_output (monitor); - - return meta_output_peek_hdr_metadata (output); -} - -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; - const MetaOutputInfo *output_info = meta_output_get_info (output); - - if (!(output_info->supported_hdr_eotfs & (1 << metadata->eotf))) - { - 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; -} - GList * meta_monitor_get_supported_color_modes (MetaMonitor *monitor) { @@ -2396,6 +2318,15 @@ meta_monitor_get_supported_color_modes (MetaMonitor *monitor) return priv->color_modes; } +MetaColorMode +meta_monitor_get_color_mode (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + return meta_output_get_color_mode (output); +} + gboolean meta_parse_monitor_mode (const char *string, int *out_width, diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h index 5abb27900..b60f37f5a 100644 --- a/src/backends/meta-monitor.h +++ b/src/backends/meta-monitor.h @@ -318,17 +318,10 @@ size_t meta_monitor_get_gamma_lut_size (MetaMonitor *monitor); void meta_monitor_set_gamma_lut (MetaMonitor *monitor, const MetaGammaLut *lut); -MetaOutputColorspace meta_monitor_get_color_space (MetaMonitor *monitor); +MetaColorMode meta_monitor_get_color_mode (MetaMonitor *monitor); -gboolean meta_monitor_set_color_space (MetaMonitor *monitor, - MetaOutputColorspace color_space, - GError **error); - -MetaOutputHdrMetadata * meta_monitor_get_hdr_metadata (MetaMonitor *monitor); - -gboolean meta_monitor_set_hdr_metadata (MetaMonitor *monitor, - MetaOutputHdrMetadata *metadata, - GError **error); +META_EXPORT_TEST +GList * meta_monitor_get_supported_color_modes (MetaMonitor *monitor); META_EXPORT_TEST gboolean meta_parse_monitor_mode (const char *string, @@ -355,6 +348,4 @@ void meta_monitor_set_for_lease (MetaMonitor *monitor, META_EXPORT_TEST gboolean meta_monitor_is_for_lease (MetaMonitor *monitor); -GList * meta_monitor_get_supported_color_modes (MetaMonitor *monitor); - G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaMonitorSpec, meta_monitor_spec_free) diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c index 937aa8bb6..430f4aafc 100644 --- a/src/backends/meta-output.c +++ b/src/backends/meta-output.c @@ -39,8 +39,6 @@ static GParamSpec *obj_props[N_PROPS]; enum { - COLOR_SPACE_CHANGED, - HDR_METADATA_CHANGED, BACKLIGHT_CHANGED, N_SIGNALS @@ -74,8 +72,7 @@ typedef struct _MetaOutputPrivate MetaPrivacyScreenState privacy_screen_state; gboolean is_privacy_screen_enabled; - MetaOutputHdrMetadata hdr_metadata; - MetaOutputColorspace color_space; + MetaColorMode color_mode; MetaOutputRGBRange rgb_range; } MetaOutputPrivate; @@ -284,6 +281,8 @@ meta_output_assign_crtc (MetaOutput *output, priv->has_max_bpc = output_assignment->has_max_bpc; if (priv->has_max_bpc) priv->max_bpc = output_assignment->max_bpc; + + priv->color_mode = output_assignment->color_mode; } void @@ -538,56 +537,36 @@ meta_output_info_get_min_refresh_rate (const MetaOutputInfo *output_info, } void -meta_output_set_color_space (MetaOutput *output, - MetaOutputColorspace color_space) +meta_output_get_color_metadata (MetaOutput *output, + MetaOutputHdrMetadata *hdr_metadata, + MetaOutputColorspace *colorspace) { MetaOutputPrivate *priv = meta_output_get_instance_private (output); - priv->color_space = color_space; - - g_signal_emit (output, signals[COLOR_SPACE_CHANGED], 0); -} - -MetaOutputColorspace -meta_output_peek_color_space (MetaOutput *output) -{ - MetaOutputPrivate *priv = meta_output_get_instance_private (output); - - return priv->color_space; -} - -const char * -meta_output_colorspace_get_name (MetaOutputColorspace color_space) -{ - switch (color_space) + switch (priv->color_mode) { - case META_OUTPUT_COLORSPACE_UNKNOWN: - return "Unknown"; - case META_OUTPUT_COLORSPACE_DEFAULT: - return "Default"; - case META_OUTPUT_COLORSPACE_BT2020: - return "bt.2020"; + case META_COLOR_MODE_DEFAULT: + *hdr_metadata = (MetaOutputHdrMetadata) { + .active = FALSE + }; + *colorspace = META_OUTPUT_COLORSPACE_DEFAULT; + break; + case META_COLOR_MODE_BT2100: + *hdr_metadata = (MetaOutputHdrMetadata) { + .active = TRUE, + .eotf = META_OUTPUT_HDR_METADATA_EOTF_PQ, + }; + *colorspace = META_OUTPUT_COLORSPACE_BT2020; + break; } - g_assert_not_reached (); } -void -meta_output_set_hdr_metadata (MetaOutput *output, - MetaOutputHdrMetadata *metadata) +MetaColorMode +meta_output_get_color_mode (MetaOutput *output) { MetaOutputPrivate *priv = meta_output_get_instance_private (output); - priv->hdr_metadata = *metadata; - - g_signal_emit (output, signals[HDR_METADATA_CHANGED], 0); -} - -MetaOutputHdrMetadata * -meta_output_peek_hdr_metadata (MetaOutput *output) -{ - MetaOutputPrivate *priv = meta_output_get_instance_private (output); - - return &priv->hdr_metadata; + return priv->color_mode; } MetaOutputRGBRange @@ -629,8 +608,6 @@ meta_output_init (MetaOutput *output) priv->is_primary = FALSE; priv->is_presentation = FALSE; priv->is_underscanning = FALSE; - priv->color_space = META_OUTPUT_COLORSPACE_DEFAULT; - priv->hdr_metadata.active = FALSE; priv->has_max_bpc = FALSE; priv->max_bpc = 0; priv->rgb_range = META_OUTPUT_RGB_RANGE_AUTO; @@ -671,20 +648,6 @@ meta_output_class_init (MetaOutputClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPS, obj_props); - signals[COLOR_SPACE_CHANGED] = - g_signal_new ("color-space-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - signals[HDR_METADATA_CHANGED] = - g_signal_new ("hdr-metadata-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); signals[BACKLIGHT_CHANGED] = g_signal_new ("backlight-changed", G_TYPE_FROM_CLASS (klass), diff --git a/src/backends/meta-output.h b/src/backends/meta-output.h index c91030c9a..f35b11212 100644 --- a/src/backends/meta-output.h +++ b/src/backends/meta-output.h @@ -279,15 +279,11 @@ gboolean meta_output_set_privacy_screen_enabled (MetaOutput *output, gboolean enabled, GError **error); -void meta_output_set_color_space (MetaOutput *output, - MetaOutputColorspace color_space); +void meta_output_get_color_metadata (MetaOutput *output, + MetaOutputHdrMetadata *hdr_metadata, + MetaOutputColorspace *colorspace); -MetaOutputColorspace meta_output_peek_color_space (MetaOutput *output); - -void meta_output_set_hdr_metadata (MetaOutput *output, - MetaOutputHdrMetadata *metadata); - -MetaOutputHdrMetadata * meta_output_peek_hdr_metadata (MetaOutput *output); +MetaColorMode meta_output_get_color_mode (MetaOutput *output); META_EXPORT_TEST MetaOutputRGBRange meta_output_peek_rgb_range (MetaOutput *output); diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index ba267042b..51489054d 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -128,10 +128,8 @@ struct _MetaOnscreenNative struct { KmsProperty gamma_lut; KmsProperty privacy_screen; - KmsProperty color_space; - KmsProperty hdr_metadata; } property; - KmsProperty properties[4]; + KmsProperty properties[2]; }; }; @@ -721,6 +719,26 @@ set_rgb_range (MetaOutputKms *output_kms, meta_kms_update_set_broadcast_rgb (kms_update, kms_connector, rgb_range); } +static void +set_color_mode (MetaOutputKms *output_kms, + MetaKmsUpdate *kms_update) +{ + MetaOutput *output = META_OUTPUT (output_kms); + MetaKmsConnector *kms_connector = + meta_output_kms_get_kms_connector (output_kms); + MetaOutputHdrMetadata hdr_metadata; + MetaOutputColorspace color_space; + + + meta_output_get_color_metadata (output, &hdr_metadata, &color_space); + + if (meta_kms_connector_supports_colorspace (kms_connector)) + meta_kms_update_set_color_space (kms_update, kms_connector, color_space); + + if (meta_kms_connector_supports_hdr_metadata (kms_connector)) + meta_kms_update_set_hdr_metadata (kms_update, kms_connector, &hdr_metadata); +} + static void meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, MetaKmsUpdate *kms_update, @@ -777,6 +795,7 @@ meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, set_underscan (META_OUTPUT_KMS (onscreen_native->output), kms_update); set_max_bpc (META_OUTPUT_KMS (onscreen_native->output), kms_update); set_rgb_range (META_OUTPUT_KMS (onscreen_native->output), kms_update); + set_color_mode (META_OUTPUT_KMS (onscreen_native->output), kms_update); } static void @@ -1927,40 +1946,6 @@ meta_onscreen_native_prepare_frame (CoglOnscreen *onscreen, onscreen_native->property.privacy_screen.target_frame_counter = target_frame_counter; } - - if (onscreen_native->property.color_space.invalidated) - { - MetaKmsConnector *kms_connector = - meta_output_kms_get_kms_connector (output_kms); - MetaKmsUpdate *kms_update; - MetaOutputColorspace color_space; - - kms_update = meta_frame_native_ensure_kms_update (frame_native, - kms_device); - - color_space = meta_output_peek_color_space (onscreen_native->output); - meta_kms_update_set_color_space (kms_update, kms_connector, color_space); - onscreen_native->property.color_space.invalidated = FALSE; - onscreen_native->property.color_space.target_frame_counter = - target_frame_counter; - } - - if (onscreen_native->property.hdr_metadata.invalidated) - { - MetaKmsConnector *kms_connector = - meta_output_kms_get_kms_connector (output_kms); - MetaKmsUpdate *kms_update; - MetaOutputHdrMetadata *metadata; - - kms_update = meta_frame_native_ensure_kms_update (frame_native, - kms_device); - - metadata = meta_output_peek_hdr_metadata (onscreen_native->output); - meta_kms_update_set_hdr_metadata (kms_update, kms_connector, metadata); - onscreen_native->property.hdr_metadata.invalidated = FALSE; - onscreen_native->property.hdr_metadata.target_frame_counter = - target_frame_counter; - } } static void @@ -2777,12 +2762,6 @@ meta_onscreen_native_invalidate (MetaOnscreenNative *onscreen_native) onscreen_native->property.gamma_lut.invalidated = TRUE; if (output_info->supports_privacy_screen) onscreen_native->property.privacy_screen.invalidated = TRUE; - if (output_info->supported_color_spaces & - (1 << META_OUTPUT_COLORSPACE_DEFAULT)) - onscreen_native->property.color_space.invalidated = TRUE; - if (output_info->supported_hdr_eotfs & - (1 << META_OUTPUT_HDR_METADATA_EOTF_TRADITIONAL_GAMMA_SDR)) - onscreen_native->property.hdr_metadata.invalidated = TRUE; } static void @@ -2806,26 +2785,6 @@ on_privacy_screen_enabled_changed (MetaOutput *output, clutter_stage_view_schedule_update (stage_view); } -static void -on_color_space_changed (MetaOutput *output, - MetaOnscreenNative *onscreen_native) -{ - ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (onscreen_native->view); - - onscreen_native->property.color_space.invalidated = TRUE; - clutter_stage_view_schedule_update (stage_view); -} - -static void -on_hdr_metadata_changed (MetaOutput *output, - MetaOnscreenNative *onscreen_native) -{ - ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (onscreen_native->view); - - onscreen_native->property.hdr_metadata.invalidated = TRUE; - clutter_stage_view_schedule_update (stage_view); -} - MetaOnscreenNative * meta_onscreen_native_new (MetaRendererNative *renderer_native, MetaGpuKms *render_gpu, @@ -2873,26 +2832,6 @@ meta_onscreen_native_new (MetaRendererNative *renderer_native, onscreen_native); } - if (output_info->supported_color_spaces & - (1 << META_OUTPUT_COLORSPACE_DEFAULT)) - { - onscreen_native->property.color_space.invalidated = TRUE; - onscreen_native->property.color_space.signal_handler_id = - g_signal_connect (output, "color-space-changed", - G_CALLBACK (on_color_space_changed), - onscreen_native); - } - - if (output_info->supported_hdr_eotfs & - (1 << META_OUTPUT_HDR_METADATA_EOTF_TRADITIONAL_GAMMA_SDR)) - { - onscreen_native->property.hdr_metadata.invalidated = TRUE; - onscreen_native->property.hdr_metadata.signal_handler_id = - g_signal_connect (output, "hdr-metadata-changed", - G_CALLBACK (on_hdr_metadata_changed), - onscreen_native); - } - return onscreen_native; } @@ -2903,10 +2842,6 @@ clear_invalidation_handlers (MetaOnscreenNative *onscreen_native) onscreen_native->crtc); g_clear_signal_handler (&onscreen_native->property.privacy_screen.signal_handler_id, onscreen_native->output); - g_clear_signal_handler (&onscreen_native->property.color_space.signal_handler_id, - onscreen_native->output); - g_clear_signal_handler (&onscreen_native->property.hdr_metadata.signal_handler_id, - onscreen_native->output); } static void diff --git a/src/core/meta-debug-control-private.h b/src/core/meta-debug-control-private.h index 372cf0d3c..416be2da5 100644 --- a/src/core/meta-debug-control-private.h +++ b/src/core/meta-debug-control-private.h @@ -24,8 +24,6 @@ gboolean meta_debug_control_is_color_management_protocol_enabled (MetaDebugContr gboolean meta_debug_control_is_linear_blending_forced (MetaDebugControl *debug_control); -gboolean meta_debug_control_is_hdr_enabled (MetaDebugControl *debug_control); - gboolean meta_debug_control_is_hdr_forced (MetaDebugControl *debug_control); unsigned int meta_debug_control_get_luminance_percentage (MetaDebugControl *debug_control); diff --git a/src/core/meta-debug-control.c b/src/core/meta-debug-control.c index de66ec3c5..bdf52ed08 100644 --- a/src/core/meta-debug-control.c +++ b/src/core/meta-debug-control.c @@ -168,7 +168,7 @@ meta_debug_control_init (MetaDebugControl *debug_control) { MetaDBusDebugControl *dbus_debug_control = META_DBUS_DEBUG_CONTROL (debug_control); - gboolean enable_hdr, force_hdr, force_linear_blending, + gboolean force_hdr, force_linear_blending, color_management_protocol; gboolean session_management_protocol; gboolean inhibit_hw_cursor; @@ -178,9 +178,6 @@ meta_debug_control_init (MetaDebugControl *debug_control) meta_dbus_debug_control_set_color_management_protocol (dbus_debug_control, color_management_protocol); - enable_hdr = g_strcmp0 (getenv ("MUTTER_DEBUG_ENABLE_HDR"), "1") == 0; - meta_dbus_debug_control_set_enable_hdr (dbus_debug_control, enable_hdr); - force_hdr = g_strcmp0 (getenv ("MUTTER_DEBUG_FORCE_HDR"), "1") == 0; meta_dbus_debug_control_set_force_hdr (dbus_debug_control, force_hdr); @@ -220,16 +217,6 @@ meta_debug_control_is_linear_blending_forced (MetaDebugControl *debug_control) return meta_dbus_debug_control_get_force_linear_blending (dbus_debug_control); } -gboolean -meta_debug_control_is_hdr_enabled (MetaDebugControl *debug_control) -{ - MetaDBusDebugControl *dbus_debug_control = - META_DBUS_DEBUG_CONTROL (debug_control); - - return meta_dbus_debug_control_get_enable_hdr (dbus_debug_control) || - meta_debug_control_is_hdr_forced (debug_control); -} - gboolean meta_debug_control_is_hdr_forced (MetaDebugControl *debug_control) { diff --git a/src/tests/gdctl/show-properties b/src/tests/gdctl/show-properties index d341a6e77..c0b0ba025 100644 --- a/src/tests/gdctl/show-properties +++ b/src/tests/gdctl/show-properties @@ -12,10 +12,11 @@ Monitors: │ │ └──Properties: (2) │ │ ├──is-current ⇒ yes │ │ └──is-preferred ⇒ yes -│ └──Properties: (4) +│ └──Properties: (5) │ ├──is-builtin ⇒ no │ ├──display-name ⇒ MetaProduct's Inc. 14" │ ├──is-for-lease ⇒ no +│ ├──color-mode ⇒ 0 │ └──supported-color-modes ⇒ [0] └──Monitor DP-2 (MetaProduct's Inc. 13") ├──Vendor: MetaProduct's Inc. @@ -30,10 +31,11 @@ Monitors: │ └──Properties: (2) │ ├──is-current ⇒ yes │ └──is-preferred ⇒ yes - └──Properties: (4) + └──Properties: (5) ├──is-builtin ⇒ no ├──display-name ⇒ MetaProduct's Inc. 13" ├──is-for-lease ⇒ no + ├──color-mode ⇒ 0 └──supported-color-modes ⇒ [0] Logical monitors: diff --git a/src/tests/gdctl/show-verbose b/src/tests/gdctl/show-verbose index 344f54a56..7b9f71920 100644 --- a/src/tests/gdctl/show-verbose +++ b/src/tests/gdctl/show-verbose @@ -30,10 +30,11 @@ Monitors: │ │ ├──Preferred scale: 1.0 │ │ ├──Supported scales: [1.0, 1.25, 1.5, 1.7475727796554565] │ │ └──Properties: (0) -│ └──Properties: (4) +│ └──Properties: (5) │ ├──is-builtin ⇒ no │ ├──display-name ⇒ MetaProduct's Inc. 14" │ ├──is-for-lease ⇒ no +│ ├──color-mode ⇒ 0 │ └──supported-color-modes ⇒ [0] └──Monitor DP-2 (MetaProduct's Inc. 13") ├──Vendor: MetaProduct's Inc. @@ -66,10 +67,11 @@ Monitors: │ ├──Preferred scale: 1.0 │ ├──Supported scales: [1.0] │ └──Properties: (0) - └──Properties: (4) + └──Properties: (5) ├──is-builtin ⇒ no ├──display-name ⇒ MetaProduct's Inc. 13" ├──is-for-lease ⇒ no + ├──color-mode ⇒ 0 └──supported-color-modes ⇒ [0] Logical monitors: diff --git a/src/tests/meta-monitor-test-utils.c b/src/tests/meta-monitor-test-utils.c index 895ac5ffb..54b52947c 100644 --- a/src/tests/meta-monitor-test-utils.c +++ b/src/tests/meta-monitor-test-utils.c @@ -797,6 +797,10 @@ meta_create_monitor_test_setup (MetaBackend *backend, (uint8_t *) &setup->outputs[i].edid_info, sizeof (setup->outputs[i].edid_info)); } + output_info->supported_color_spaces = + setup->outputs[i].supported_color_spaces; + output_info->supported_hdr_eotfs = + setup->outputs[i].supported_hdr_eotfs; output = g_object_new (META_TYPE_OUTPUT_TEST, "id", (uint64_t) i, diff --git a/src/tests/meta-monitor-test-utils.h b/src/tests/meta-monitor-test-utils.h index 436b21ce9..96c519040 100644 --- a/src/tests/meta-monitor-test-utils.h +++ b/src/tests/meta-monitor-test-utils.h @@ -118,6 +118,8 @@ typedef struct _MonitorTestCaseOutput int backlight_max; gboolean has_edid_info; MetaEdidInfo edid_info; + uint64_t supported_color_spaces; + uint64_t supported_hdr_eotfs; } MonitorTestCaseOutput; typedef struct _MonitorTestCaseCrtc diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c index 74d86b3a5..ed2e1c994 100644 --- a/src/tests/monitor-unit-tests.c +++ b/src/tests/monitor-unit-tests.c @@ -9659,6 +9659,95 @@ meta_test_monitor_custom_for_lease_config_dbus (void) assert_monitor_state (new_state, 1, "DP-2", FALSE); } +static void +meta_test_monitor_color_modes (void) +{ + MonitorTestCaseSetup test_case_setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .serial = "0x123456", + .supported_color_spaces = ((1 << META_OUTPUT_COLORSPACE_DEFAULT) | + (1 << META_OUTPUT_COLORSPACE_BT2020)), + .supported_hdr_eotfs = + ((1 << META_OUTPUT_HDR_METADATA_EOTF_TRADITIONAL_GAMMA_SDR) | + (1 << META_OUTPUT_HDR_METADATA_EOTF_PQ)), + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .serial = "0x654321", + .supported_color_spaces = 1 << META_OUTPUT_COLORSPACE_DEFAULT, + .supported_hdr_eotfs = + 1 << META_OUTPUT_HDR_METADATA_EOTF_TRADITIONAL_GAMMA_SDR, + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }; + MetaBackend *backend = meta_context_get_backend (test_context); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *monitors; + MetaMonitor *first_monitor; + MetaMonitor *second_monitor; + GList *color_modes; + MetaMonitorTestSetup *test_setup; + + test_setup = meta_create_monitor_test_setup (test_backend, + &test_case_setup, + MONITOR_TEST_FLAG_NONE); + emulate_hotplug (test_setup); + check_monitor_test_clients_state (); + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + g_assert_cmpuint (g_list_length (monitors), ==, 2); + + first_monitor = g_list_nth_data (monitors, 0); + second_monitor = g_list_nth_data (monitors, 1); + + color_modes = meta_monitor_get_supported_color_modes (first_monitor); + g_assert_cmpuint (g_list_length (color_modes), ==, 2); + g_assert_nonnull (g_list_find (color_modes, + GINT_TO_POINTER (META_COLOR_MODE_DEFAULT))); + g_assert_nonnull (g_list_find (color_modes, + GINT_TO_POINTER (META_COLOR_MODE_BT2100))); + + color_modes = meta_monitor_get_supported_color_modes (second_monitor); + g_assert_cmpuint (g_list_length (color_modes), ==, 1); + g_assert_nonnull (g_list_find (color_modes, + GINT_TO_POINTER (META_COLOR_MODE_DEFAULT))); +} + static gboolean quit_main_loop (gpointer data) { @@ -10892,6 +10981,9 @@ init_monitor_tests (void) add_monitor_test ("/backends/monitor/custom/for-lease-config-dbus", meta_test_monitor_custom_for_lease_config_dbus); + add_monitor_test ("/backends/monitor/color-modes", + meta_test_monitor_color_modes); + add_monitor_test ("/backends/monitor/migrated/rotated", meta_test_monitor_migrated_rotated); add_monitor_test ("/backends/monitor/migrated/horizontal-strip",