From f760b47a3cda90ff8290925401ebb70a9469bdb9 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Tue, 14 Jun 2022 16:27:53 +0800 Subject: [PATCH 01/18] kms-impl-device: Remember the min/max values for a DRM_MODE_PROP_RANGE Part-of: --- src/backends/native/meta-kms-impl-device.c | 14 ++++++++++++++ src/backends/native/meta-kms-impl-device.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index dc2ac31ef4..b1dd321a7f 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -690,6 +690,20 @@ meta_kms_impl_device_update_prop_table (MetaKmsImplDevice *impl_device, update_prop_value (prop, prop_value); + if (prop->type == DRM_MODE_PROP_RANGE) + { + if (drm_prop->count_values == 2) + { + prop->range_min = drm_prop->values[0]; + prop->range_max = drm_prop->values[1]; + } + else + { + g_warning ("DRM property '%s' is a range with %d values, ignoring", + drm_prop->name, drm_prop->count_values); + } + } + drmModeFreeProperty (drm_prop); } } diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h index c5ac131cc2..a45d24bedb 100644 --- a/src/backends/native/meta-kms-impl-device.h +++ b/src/backends/native/meta-kms-impl-device.h @@ -64,6 +64,9 @@ struct _MetaKmsProp MetaKmsEnum *enum_values; uint64_t default_value; + uint64_t range_min; + uint64_t range_max; + uint32_t prop_id; uint64_t value; }; -- GitLab From f7654374103698443cd3975b16c32e205a225847 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Tue, 17 May 2022 16:46:52 +0800 Subject: [PATCH 02/18] kms-types: Add type MetaKmsRange Part-of: --- src/backends/native/meta-kms-types.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/backends/native/meta-kms-types.h b/src/backends/native/meta-kms-types.h index a2e2f8ded3..81fcad0e66 100644 --- a/src/backends/native/meta-kms-types.h +++ b/src/backends/native/meta-kms-types.h @@ -89,4 +89,11 @@ typedef enum _MetaKmsPropType META_KMS_PROP_TYPE_FIXED_16, } MetaKmsPropType; +typedef struct _MetaKmsRange +{ + uint64_t value; + uint64_t min_value; + uint64_t max_value; +} MetaKmsRange; + #endif /* META_KMS_IMPL_TYPES_H */ -- GitLab From 33ee155630da652b8bbe319f89f976b5da5b9476 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Fri, 13 May 2022 16:20:57 +0800 Subject: [PATCH 03/18] kms-connector: Add "max bpc" property This limits the bits-per-channel colour depth of the signal that the connector is allowed to output. Part-of: --- .../native/meta-kms-connector-private.h | 1 + src/backends/native/meta-kms-connector.c | 31 +++++++++++++++++++ src/backends/native/meta-kms-connector.h | 4 +++ 3 files changed, 36 insertions(+) diff --git a/src/backends/native/meta-kms-connector-private.h b/src/backends/native/meta-kms-connector-private.h index e1d9b44cd5..73757a8fca 100644 --- a/src/backends/native/meta-kms-connector-private.h +++ b/src/backends/native/meta-kms-connector-private.h @@ -39,6 +39,7 @@ typedef enum _MetaKmsConnectorProp META_KMS_CONNECTOR_PROP_SCALING_MODE, META_KMS_CONNECTOR_PROP_PANEL_ORIENTATION, META_KMS_CONNECTOR_PROP_NON_DESKTOP, + META_KMS_CONNECTOR_PROP_MAX_BPC, META_KMS_CONNECTOR_N_PROPS } MetaKmsConnectorProp; diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c index 724f96e36f..2bc3372917 100644 --- a/src/backends/native/meta-kms-connector.c +++ b/src/backends/native/meta-kms-connector.c @@ -190,6 +190,19 @@ has_privacy_screen_software_toggle (MetaKmsConnector *connector) META_KMS_CONNECTOR_PROP_PRIVACY_SCREEN_SW_STATE) != 0; } +const MetaKmsRange * +meta_kms_connector_get_max_bpc (MetaKmsConnector *connector) +{ + const MetaKmsRange *range = NULL; + + if (connector->current_state && + meta_kms_connector_get_prop_id (connector, + META_KMS_CONNECTOR_PROP_MAX_BPC)) + range = &connector->current_state->max_bpc; + + return range; +} + static void sync_fd_held (MetaKmsConnector *connector, MetaKmsImplDevice *impl_device) @@ -308,6 +321,14 @@ state_set_properties (MetaKmsConnectorState *state, prop = &props[META_KMS_CONNECTOR_PROP_PRIVACY_SCREEN_HW_STATE]; if (prop->prop_id) set_privacy_screen (state, connector, prop); + + prop = &props[META_KMS_CONNECTOR_PROP_MAX_BPC]; + if (prop->prop_id) + { + state->max_bpc.value = prop->value; + state->max_bpc.min_value = prop->range_min; + state->max_bpc.max_value = prop->range_max; + } } static CoglSubpixelOrder @@ -622,6 +643,11 @@ meta_kms_connector_state_changes (MetaKmsConnectorState *state, if (!kms_modes_equal (state->modes, new_state->modes)) return META_KMS_RESOURCE_CHANGE_FULL; + if (state->max_bpc.value != new_state->max_bpc.value || + state->max_bpc.min_value != new_state->max_bpc.min_value || + state->max_bpc.max_value != new_state->max_bpc.max_value) + return META_KMS_RESOURCE_CHANGE_FULL; + if (state->privacy_screen_state != new_state->privacy_screen_state) return META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN; @@ -940,6 +966,11 @@ init_properties (MetaKmsConnector *connector, .name = "non-desktop", .type = DRM_MODE_PROP_RANGE, }, + [META_KMS_CONNECTOR_PROP_MAX_BPC] = + { + .name = "max bpc", + .type = DRM_MODE_PROP_RANGE, + }, }, .dpms_enum = { [META_KMS_CONNECTOR_DPMS_ON] = diff --git a/src/backends/native/meta-kms-connector.h b/src/backends/native/meta-kms-connector.h index c2b763548e..bbd59d3423 100644 --- a/src/backends/native/meta-kms-connector.h +++ b/src/backends/native/meta-kms-connector.h @@ -59,6 +59,8 @@ typedef struct _MetaKmsConnectorState gboolean hotplug_mode_update; MetaMonitorTransform panel_orientation_transform; + + MetaKmsRange max_bpc; } MetaKmsConnectorState; META_EXPORT_TEST @@ -83,4 +85,6 @@ gboolean meta_kms_connector_is_underscanning_supported (MetaKmsConnector *connec gboolean meta_kms_connector_is_privacy_screen_supported (MetaKmsConnector *connector); +const MetaKmsRange * meta_kms_connector_get_max_bpc (MetaKmsConnector *connector); + #endif /* META_KMS_CONNECTOR_H */ -- GitLab From 2b561a369ca57e68625973ac83bb56460b35665d Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Fri, 13 May 2022 16:26:10 +0800 Subject: [PATCH 04/18] kms-update: Add function meta_kms_update_set_max_bpc Part-of: --- src/backends/native/meta-kms-update-private.h | 5 +++++ src/backends/native/meta-kms-update.c | 14 ++++++++++++++ src/backends/native/meta-kms-update.h | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 9dab7c133c..3a648ba0da 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -82,6 +82,11 @@ typedef struct _MetaKmsConnectorUpdate gboolean has_update; gboolean is_enabled; } privacy_screen; + + struct { + gboolean has_update; + uint64_t value; + } max_bpc; } MetaKmsConnectorUpdate; typedef struct _MetaKmsPageFlipListener diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 042714d0aa..4c34000ef5 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -356,6 +356,20 @@ meta_kms_update_set_privacy_screen (MetaKmsUpdate *update, connector_update->privacy_screen.is_enabled = enabled; } +void +meta_kms_update_set_max_bpc (MetaKmsUpdate *update, + MetaKmsConnector *connector, + uint64_t max_bpc) +{ + MetaKmsConnectorUpdate *connector_update; + + g_assert (meta_kms_connector_get_device (connector) == update->device); + + connector_update = ensure_connector_update (update, connector); + connector_update->max_bpc.value = max_bpc; + connector_update->max_bpc.has_update = TRUE; +} + void meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma) { diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index f31e36aad3..d5557d7ced 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -107,6 +107,10 @@ void meta_kms_update_set_privacy_screen (MetaKmsUpdate *update, MetaKmsConnector *connector, gboolean enabled); +void meta_kms_update_set_max_bpc (MetaKmsUpdate *update, + MetaKmsConnector *connector, + uint64_t max_bpc); + META_EXPORT_TEST void meta_kms_update_set_power_save (MetaKmsUpdate *update); -- GitLab From 0cc48158374c50bfb4f4fe3944b661f1c9e96363 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Fri, 13 May 2022 16:31:30 +0800 Subject: [PATCH 05/18] kms-impl-device-atomic: Apply META_KMS_CONNECTOR_PROP_MAX_BPC Part-of: --- .../native/meta-kms-impl-device-atomic.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c index b1925f9843..7b7f7fc1fb 100644 --- a/src/backends/native/meta-kms-impl-device-atomic.c +++ b/src/backends/native/meta-kms-impl-device-atomic.c @@ -218,6 +218,22 @@ process_connector_update (MetaKmsImplDevice *impl_device, return FALSE; } + if (connector_update->max_bpc.has_update) + { + meta_topic (META_DEBUG_KMS, + "[atomic] Setting max BPC to %u on connector %u (%s)", + (unsigned int) connector_update->max_bpc.value, + meta_kms_connector_get_id (connector), + meta_kms_impl_device_get_path (impl_device)); + + if (!add_connector_property (impl_device, + connector, req, + META_KMS_CONNECTOR_PROP_MAX_BPC, + connector_update->max_bpc.value, + error)) + return FALSE; + } + return TRUE; } -- GitLab From b6dbb686e2f3cb02b9386dd2dcae26112d427865 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Fri, 13 May 2022 16:45:03 +0800 Subject: [PATCH 06/18] kms-impl-device-simple: Apply META_KMS_CONNECTOR_PROP_MAX_BPC Part-of: --- .../native/meta-kms-impl-device-simple.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c index e4a8d5f1bf..648de51c65 100644 --- a/src/backends/native/meta-kms-impl-device-simple.c +++ b/src/backends/native/meta-kms-impl-device-simple.c @@ -250,6 +250,22 @@ process_connector_update (MetaKmsImplDevice *impl_device, return FALSE; } + if (connector_update->max_bpc.has_update) + { + meta_topic (META_DEBUG_KMS, + "[simple] Setting max BPC to %u on connector %u (%s)", + (unsigned int) connector_update->max_bpc.value, + meta_kms_connector_get_id (connector), + meta_kms_impl_device_get_path (impl_device)); + + if (!set_connector_property (impl_device, + connector, + META_KMS_CONNECTOR_PROP_MAX_BPC, + connector_update->max_bpc.value, + error)) + return FALSE; + } + return TRUE; } -- GitLab From e0e10c29d962ef902dba13b1115a1d2e4bf43f6e Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 9 Jun 2022 18:43:22 +0800 Subject: [PATCH 07/18] monitor-manager-private: Add max_bpc to MetaOutputAssignment Part-of: --- src/backends/meta-monitor-manager-private.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index 6bbcfd0e98..c8255ba0c4 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -101,6 +101,8 @@ struct _MetaOutputAssignment gboolean is_primary; gboolean is_presentation; gboolean is_underscanning; + gboolean has_max_bpc; + unsigned int max_bpc; }; /* -- GitLab From 6ff0d600c3d0fcc945489428b5b1a2d1aca68bfe Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 9 Jun 2022 18:44:46 +0800 Subject: [PATCH 08/18] output: Add max_bpc support Part-of: --- src/backends/meta-output.c | 19 +++++++++++++++++++ src/backends/meta-output.h | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c index 9d9454fdfe..a02feca90f 100644 --- a/src/backends/meta-output.c +++ b/src/backends/meta-output.c @@ -55,6 +55,9 @@ typedef struct _MetaOutputPrivate gboolean is_underscanning; + gboolean has_max_bpc; + unsigned int max_bpc; + int backlight; } MetaOutputPrivate; @@ -177,6 +180,18 @@ meta_output_is_underscanning (MetaOutput *output) return priv->is_underscanning; } +gboolean +meta_output_get_max_bpc (MetaOutput *output, + unsigned int *max_bpc) +{ + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + + if (priv->has_max_bpc && max_bpc) + *max_bpc = priv->max_bpc; + + return priv->has_max_bpc; +} + void meta_output_set_backlight (MetaOutput *output, int backlight) @@ -235,6 +250,10 @@ meta_output_assign_crtc (MetaOutput *output, priv->is_primary = output_assignment->is_primary; priv->is_presentation = output_assignment->is_presentation; priv->is_underscanning = output_assignment->is_underscanning; + + priv->has_max_bpc = output_assignment->has_max_bpc; + if (priv->has_max_bpc) + priv->max_bpc = output_assignment->max_bpc; } void diff --git a/src/backends/meta-output.h b/src/backends/meta-output.h index cbacabace9..9970a7a450 100644 --- a/src/backends/meta-output.h +++ b/src/backends/meta-output.h @@ -107,6 +107,9 @@ typedef struct _MetaOutputInfo gboolean supports_underscanning; gboolean supports_color_transform; + unsigned int max_bpc_min; + unsigned int max_bpc_max; + /* * Get a new preferred mode on hotplug events, to handle dynamic guest * resizing. @@ -182,6 +185,10 @@ gboolean meta_output_is_presentation (MetaOutput *output); META_EXPORT_TEST gboolean meta_output_is_underscanning (MetaOutput *output); +META_EXPORT_TEST +gboolean meta_output_get_max_bpc (MetaOutput *output, + unsigned int *max_bpc); + void meta_output_set_backlight (MetaOutput *output, int backlight); -- GitLab From a907cef9050a4bc24dd8bf65f9a3121fa43f9a2d Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 9 Jun 2022 18:45:46 +0800 Subject: [PATCH 09/18] monitor: Add function meta_monitor_get_max_bpc() Part-of: --- src/backends/meta-monitor.c | 11 +++++++++++ src/backends/meta-monitor.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c index b7abd9b4b6..3ad02ee3ad 100644 --- a/src/backends/meta-monitor.c +++ b/src/backends/meta-monitor.c @@ -358,6 +358,17 @@ meta_monitor_is_underscanning (MetaMonitor *monitor) return meta_output_is_underscanning (output); } +gboolean +meta_monitor_get_max_bpc (MetaMonitor *monitor, + unsigned int *max_bpc) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + + return meta_output_get_max_bpc (output, max_bpc); +} + gboolean meta_monitor_is_laptop_panel (MetaMonitor *monitor) { diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h index d8a90097fe..4d61f1d4bc 100644 --- a/src/backends/meta-monitor.h +++ b/src/backends/meta-monitor.h @@ -118,6 +118,9 @@ gboolean meta_monitor_supports_underscanning (MetaMonitor *monitor); gboolean meta_monitor_is_underscanning (MetaMonitor *monitor); +gboolean meta_monitor_get_max_bpc (MetaMonitor *monitor, + unsigned int *max_bpc); + gboolean meta_monitor_is_laptop_panel (MetaMonitor *monitor); gboolean meta_monitor_is_same_as (MetaMonitor *monitor, -- GitLab From 4eef54f80ad2daa4fc8758ed0821de02b07c573f Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 9 Jun 2022 18:46:54 +0800 Subject: [PATCH 10/18] monitor-config-manager: Add a max_bpc field to MetaMonitorConfig Part-of: --- src/backends/meta-monitor-config-manager.c | 11 +++++++++-- src/backends/meta-monitor-config-manager.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c index e782f1444e..bdafba4780 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -286,7 +286,9 @@ assign_monitor_crtc (MetaMonitor *monitor, .output = output, .is_primary = assign_output_as_primary, .is_presentation = assign_output_as_presentation, - .is_underscanning = data->monitor_config->enable_underscanning + .is_underscanning = data->monitor_config->enable_underscanning, + .has_max_bpc = data->monitor_config->has_max_bpc, + .max_bpc = data->monitor_config->max_bpc }; g_ptr_array_add (data->crtc_assignments, crtc_assignment); @@ -694,6 +696,9 @@ create_monitor_config (MetaMonitor *monitor, .enable_underscanning = meta_monitor_is_underscanning (monitor) }; + monitor_config->has_max_bpc = + meta_monitor_get_max_bpc (monitor, &monitor_config->max_bpc); + return monitor_config; } @@ -1041,7 +1046,9 @@ clone_monitor_config_list (GList *monitor_configs_in) .monitor_spec = meta_monitor_spec_clone (monitor_config_in->monitor_spec), .mode_spec = g_memdup2 (monitor_config_in->mode_spec, sizeof (MetaMonitorModeSpec)), - .enable_underscanning = monitor_config_in->enable_underscanning + .enable_underscanning = monitor_config_in->enable_underscanning, + .has_max_bpc = monitor_config_in->has_max_bpc, + .max_bpc = monitor_config_in->max_bpc }; monitor_configs_out = g_list_append (monitor_configs_out, monitor_config_out); diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h index a789e2f088..bf45b23276 100644 --- a/src/backends/meta-monitor-config-manager.h +++ b/src/backends/meta-monitor-config-manager.h @@ -34,6 +34,8 @@ typedef struct _MetaMonitorConfig MetaMonitorSpec *monitor_spec; MetaMonitorModeSpec *mode_spec; gboolean enable_underscanning; + gboolean has_max_bpc; + unsigned int max_bpc; } MetaMonitorConfig; typedef struct _MetaLogicalMonitorConfig -- GitLab From f19b350c9481e9cc22a2143e758f292e2592a444 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 9 Jun 2022 18:49:05 +0800 Subject: [PATCH 11/18] output-kms: Add max_bpc support Part-of: --- src/backends/native/meta-output-kms.c | 38 +++++++++++++++++++++++++++ src/backends/native/meta-output-kms.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index 5e572e27b2..2062a20cf7 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -97,6 +97,36 @@ meta_output_kms_set_underscan (MetaOutputKms *output_kms, } } +void +meta_output_kms_set_max_bpc (MetaOutputKms *output_kms, + MetaKmsUpdate *kms_update) +{ + MetaKmsConnector *kms_connector = output_kms->kms_connector; + const MetaKmsRange *range; + + range = meta_kms_connector_get_max_bpc (kms_connector); + if (range) + { + MetaOutput *output = META_OUTPUT (output_kms); + unsigned int max_bpc; + + if (!meta_output_get_max_bpc (output, &max_bpc)) + return; + + if (max_bpc >= range->min_value && max_bpc <= range->max_value) + { + meta_kms_update_set_max_bpc (kms_update, kms_connector, max_bpc); + } + else + { + g_warning ("Ignoring out of range value %u for max bpc (%u-%u)", + max_bpc, + (unsigned) range->min_value, + (unsigned) range->max_value); + } + } +} + static MetaPrivacyScreenState meta_output_kms_get_privacy_screen_state (MetaOutput *output) { @@ -362,6 +392,7 @@ meta_output_kms_new (MetaGpuKms *gpu_kms, const MetaKmsConnectorState *connector_state; GArray *crtcs; GList *l; + const MetaKmsRange *max_bpc_range; gpu_id = meta_gpu_kms_get_id (gpu_kms); connector_id = meta_kms_connector_get_id (kms_connector); @@ -409,6 +440,13 @@ meta_output_kms_new (MetaGpuKms *gpu_kms, output_info->supports_underscanning = meta_kms_connector_is_underscanning_supported (kms_connector); + max_bpc_range = meta_kms_connector_get_max_bpc (kms_connector); + if (max_bpc_range) + { + output_info->max_bpc_min = max_bpc_range->min_value; + output_info->max_bpc_max = max_bpc_range->max_value; + } + meta_output_info_parse_edid (output_info, connector_state->edid_data); drm_connector_type = meta_kms_connector_get_connector_type (kms_connector); diff --git a/src/backends/native/meta-output-kms.h b/src/backends/native/meta-output-kms.h index 52acc6032a..1e35dbb17d 100644 --- a/src/backends/native/meta-output-kms.h +++ b/src/backends/native/meta-output-kms.h @@ -40,6 +40,9 @@ void meta_output_kms_set_power_save_mode (MetaOutputKms *output_kms, void meta_output_kms_set_underscan (MetaOutputKms *output_kms, MetaKmsUpdate *kms_update); +void meta_output_kms_set_max_bpc (MetaOutputKms *output_kms, + MetaKmsUpdate *kms_update); + gboolean meta_output_kms_can_clone (MetaOutputKms *output_kms, MetaOutputKms *other_output_kms); -- GitLab From 978cbe2da46e138af3f6ea77b3b37ead59606ef2 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 9 Jun 2022 18:49:34 +0800 Subject: [PATCH 12/18] onscreen-native: Set max_bpc with mode sets Part-of: --- src/backends/native/meta-onscreen-native.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 36d6e291eb..a107a99bb3 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -533,6 +533,8 @@ meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, meta_crtc_kms_set_mode (crtc_kms, kms_update); meta_output_kms_set_underscan (META_OUTPUT_KMS (onscreen_native->output), kms_update); + meta_output_kms_set_max_bpc (META_OUTPUT_KMS (onscreen_native->output), + kms_update); } static void -- GitLab From 99d84ae1cc8f027a35c32d266cef48758daaff6d Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Fri, 10 Jun 2022 16:34:40 +0800 Subject: [PATCH 13/18] output-xrandr: Add support for the "max bpc" KMS connector property Part-of: --- src/backends/x11/meta-output-xrandr.c | 88 +++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/backends/x11/meta-output-xrandr.c b/src/backends/x11/meta-output-xrandr.c index 6fde5667e4..37a377e48c 100644 --- a/src/backends/x11/meta-output-xrandr.c +++ b/src/backends/x11/meta-output-xrandr.c @@ -145,11 +145,28 @@ output_set_underscanning_xrandr (MetaOutput *output, } } +static void +output_set_max_bpc_xrandr (MetaOutput *output, + unsigned int max_bpc) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom prop = XInternAtom (xdisplay, "max bpc", False); + uint32_t value = max_bpc; + + xcb_randr_change_output_property (XGetXCBConnection (xdisplay), + (XID) meta_output_get_id (output), + prop, XCB_ATOM_INTEGER, 32, + XCB_PROP_MODE_REPLACE, + 1, &value); +} + void meta_output_xrandr_apply_mode (MetaOutputXrandr *output_xrandr) { MetaOutput *output = META_OUTPUT (output_xrandr); Display *xdisplay = xdisplay_from_output (output); + const MetaOutputInfo *output_info = meta_output_get_info (output); + unsigned int max_bpc; if (meta_output_is_primary (output)) { @@ -164,6 +181,13 @@ meta_output_xrandr_apply_mode (MetaOutputXrandr *output_xrandr) output_set_underscanning_xrandr (output, meta_output_is_underscanning (output)); } + + if (meta_output_get_max_bpc (output, &max_bpc) && + max_bpc >= output_info->max_bpc_min && + max_bpc <= output_info->max_bpc_max) + { + output_set_max_bpc_xrandr (output, max_bpc); + } } static int @@ -347,6 +371,33 @@ output_get_underscanning_xrandr (MetaOutput *output) return (strcmp (str, "on") == 0); } +static gboolean +output_get_max_bpc_xrandr (MetaOutput *output, + unsigned int *max_bpc) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom atom, actual_type; + int actual_format; + unsigned long nitems, bytes_after; + g_autofree unsigned char *buffer = NULL; + + atom = XInternAtom (xdisplay, "max bpc", False); + XRRGetOutputProperty (xdisplay, + (XID) meta_output_get_id (output), + atom, + 0, G_MAXLONG, False, False, XCB_ATOM_INTEGER, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + if (actual_type != XCB_ATOM_INTEGER || actual_format != 32 || nitems < 1) + return FALSE; + + if (max_bpc) + *max_bpc = *((uint32_t*) buffer); + + return TRUE; +} + static gboolean output_get_supports_underscanning_xrandr (Display *xdisplay, RROutput output_id) @@ -392,6 +443,36 @@ output_get_supports_underscanning_xrandr (Display *xdisplay, return supports_underscanning; } +static gboolean +output_get_max_bpc_range_xrandr (Display *xdisplay, + RROutput output_id, + unsigned int *min, + unsigned int *max) +{ + Atom atom; + XRRPropertyInfo *property_info; + long *values; + + atom = XInternAtom (xdisplay, "max bpc", False); + + meta_clutter_x11_trap_x_errors (); + property_info = XRRQueryOutputProperty (xdisplay, + (XID) output_id, + atom); + meta_clutter_x11_untrap_x_errors (); + + if (!property_info || property_info->num_values != 2) + return FALSE; + + values = (long *) property_info->values; + if (min) + *min = values[0]; + if (max) + *max = values[1]; + + return TRUE; +} + static gboolean output_get_supports_color_transform_xrandr (Display *xdisplay, RROutput output_id) @@ -934,6 +1015,10 @@ meta_output_xrandr_new (MetaGpuXrandr *gpu_xrandr, output_info->supports_underscanning = output_get_supports_underscanning_xrandr (xdisplay, output_id); + output_get_max_bpc_range_xrandr (xdisplay, + output_id, + &output_info->max_bpc_min, + &output_info->max_bpc_max); output_info->supports_color_transform = output_get_supports_color_transform_xrandr (xdisplay, output_id); output_info_init_backlight_limits_xrandr (output_info, xdisplay, output_id); @@ -954,6 +1039,9 @@ meta_output_xrandr_new (MetaGpuXrandr *gpu_xrandr, .is_presentation = output_get_presentation_xrandr (output), .is_underscanning = output_get_underscanning_xrandr (output), }; + output_assignment.has_max_bpc = + output_get_max_bpc_xrandr (output, &output_assignment.max_bpc); + meta_output_assign_crtc (output, assigned_crtc, &output_assignment); } else -- GitLab From d39137c63189775c23e962ef73a4bf41e7c29ca7 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Fri, 10 Jun 2022 16:34:01 +0800 Subject: [PATCH 14/18] monitor-manager-xrandr: Changing "max bpc" changes output assignment Part-of: --- src/backends/x11/meta-monitor-manager-xrandr.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index 5f1369d3d7..6c9a289bcc 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -274,6 +274,7 @@ is_output_assignment_changed (MetaOutput *output, for (i = 0; i < n_output_assignments; i++) { MetaOutputAssignment *output_assignment = output_assignments[i]; + unsigned int max_bpc; if (output_assignment->output != output) continue; @@ -289,6 +290,17 @@ is_output_assignment_changed (MetaOutput *output, output_assignment->is_underscanning) return TRUE; + if (meta_output_get_max_bpc (output, &max_bpc)) + { + if (!output_assignment->has_max_bpc || + max_bpc != output_assignment->max_bpc) + return TRUE; + } + else if (output_assignment->has_max_bpc) + { + return TRUE; + } + output_is_found = TRUE; } -- GitLab From 03336788fb079cb8aa203e031f85d039a87832ce Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 9 Jun 2022 18:50:52 +0800 Subject: [PATCH 15/18] monitor-config-store: Add parsing support for "maxbpc" in monitors.xml For example: ... 8 Part-of: --- src/backends/meta-monitor-config-store.c | 49 ++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c index 4f6d03d670..377d8debf0 100644 --- a/src/backends/meta-monitor-config-store.c +++ b/src/backends/meta-monitor-config-store.c @@ -167,6 +167,7 @@ typedef enum STATE_MONITOR_MODE_RATE, STATE_MONITOR_MODE_FLAG, STATE_MONITOR_UNDERSCANNING, + STATE_MONITOR_MAXBPC, STATE_DISABLED, STATE_POLICY, STATE_STORES, @@ -451,6 +452,10 @@ handle_start_element (GMarkupParseContext *context, { parser->state = STATE_MONITOR_UNDERSCANNING; } + else if (g_str_equal (element_name, "maxbpc")) + { + parser->state = STATE_MONITOR_MAXBPC; + } else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, @@ -544,6 +549,13 @@ handle_start_element (GMarkupParseContext *context, return; } + case STATE_MONITOR_MAXBPC: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid element '%s' under maxbpc", element_name); + return; + } + case STATE_DISABLED: { if (!g_str_equal (element_name, "monitorspec")) @@ -818,6 +830,14 @@ handle_end_element (GMarkupParseContext *context, return; } + case STATE_MONITOR_MAXBPC: + { + g_assert (g_str_equal (element_name, "maxbpc")); + + parser->state = STATE_MONITOR; + return; + } + case STATE_MONITOR: { MetaLogicalMonitorConfig *logical_monitor_config; @@ -1309,6 +1329,29 @@ handle_text (GMarkupParseContext *context, return; } + case STATE_MONITOR_MAXBPC: + { + int signed_max_bpc; + + if (read_int (text, text_len, &signed_max_bpc, error)) + { + if (signed_max_bpc >= 0) + { + parser->current_monitor_config->has_max_bpc = TRUE; + parser->current_monitor_config->max_bpc = signed_max_bpc; + } + else + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid negative maxbpc value \"%s\"", + text); + } + } + + return; + } + case STATE_STORE: { MetaConfigStore store; @@ -1480,6 +1523,12 @@ append_monitors (GString *buffer, g_string_append (buffer, " \n"); if (monitor_config->enable_underscanning) g_string_append (buffer, " yes\n"); + + if (monitor_config->has_max_bpc) + { + g_string_append_printf (buffer, " %u\n", + monitor_config->max_bpc); + } g_string_append (buffer, " \n"); } } -- GitLab From cc203e241df9dabfd533552405ad54b8b81e4f87 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Wed, 29 Jun 2022 17:32:49 +0800 Subject: [PATCH 16/18] monitor-test-utils: Add max_bpc field Part-of: --- src/tests/meta-monitor-test-utils.c | 8 ++++++++ src/tests/meta-monitor-test-utils.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/tests/meta-monitor-test-utils.c b/src/tests/meta-monitor-test-utils.c index aab9e18589..2cb41cd13c 100644 --- a/src/tests/meta-monitor-test-utils.c +++ b/src/tests/meta-monitor-test-utils.c @@ -387,11 +387,17 @@ meta_check_monitor_configuration (MetaContext *context, { MetaOutput *output = l_output->data; uint64_t winsys_id = expect->monitors[i].outputs[j]; + unsigned int output_max_bpc; g_assert (output == output_from_winsys_id (backend, winsys_id)); g_assert_cmpint (expect->monitors[i].is_underscanning, ==, meta_output_is_underscanning (output)); + + if (!meta_output_get_max_bpc (output, &output_max_bpc)) + output_max_bpc = 0; + + g_assert_cmpint (expect->monitors[i].max_bpc, ==, output_max_bpc); } meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm); @@ -778,6 +784,8 @@ meta_create_monitor_test_setup (MetaBackend *backend, output_assignment = (MetaOutputAssignment) { .is_underscanning = setup->outputs[i].is_underscanning, + .has_max_bpc = !!setup->outputs[i].max_bpc, + .max_bpc = setup->outputs[i].max_bpc, }; meta_output_assign_crtc (output, crtc, &output_assignment); } diff --git a/src/tests/meta-monitor-test-utils.h b/src/tests/meta-monitor-test-utils.h index 988a4115e8..ceae9d52aa 100644 --- a/src/tests/meta-monitor-test-utils.h +++ b/src/tests/meta-monitor-test-utils.h @@ -106,6 +106,7 @@ typedef struct _MonitorTestCaseOutput float scale; gboolean is_laptop_panel; gboolean is_underscanning; + unsigned int max_bpc; const char *serial; MetaMonitorTransform panel_orientation_transform; gboolean hotplug_mode; @@ -157,6 +158,7 @@ typedef struct _MonitorTestCaseMonitor int width_mm; int height_mm; gboolean is_underscanning; + unsigned int max_bpc; } MonitorTestCaseMonitor; typedef struct _MonitorTestCaseLogicalMonitor -- GitLab From 26a9dd7f8848f79ad442012824f45d30b5831316 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Wed, 29 Jun 2022 17:33:54 +0800 Subject: [PATCH 17/18] monitor-unit-tests: Add a basic set-and-get test for max_bpc Part-of: --- src/tests/monitor-unit-tests.c | 96 ++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c index ed81afbf1e..8e34c8b22c 100644 --- a/src/tests/monitor-unit-tests.c +++ b/src/tests/monitor-unit-tests.c @@ -3276,6 +3276,100 @@ meta_test_monitor_underscanning_config (void) check_monitor_test_clients_state (); } +static void +meta_test_monitor_max_bpc_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .max_bpc = 8, + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + .max_bpc = 8, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = meta_create_monitor_test_setup (test_backend, + &test_case.setup, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + META_TEST_LOG_CALL ("Checking monitor configuration", + meta_check_monitor_configuration (test_context, + &test_case.expect)); + check_monitor_test_clients_state (); +} + static void meta_test_monitor_preferred_non_first_mode (void) { @@ -9366,6 +9460,8 @@ init_monitor_tests (void) meta_test_monitor_no_outputs); add_monitor_test ("/backends/monitor/underscanning-config", meta_test_monitor_underscanning_config); + add_monitor_test ("/backends/monitor/max-bpc-config", + meta_test_monitor_max_bpc_config); add_monitor_test ("/backends/monitor/preferred-non-first-mode", meta_test_monitor_preferred_non_first_mode); add_monitor_test ("/backends/monitor/non-upright-panel", -- GitLab From 0cfd0c3a8cb26270b51bb631348c910a97751b77 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Wed, 29 Jun 2022 17:47:26 +0800 Subject: [PATCH 18/18] monitor-store-unit-tests: Verify XML is stored correctly Part-of: --- src/tests/monitor-configs/max-bpc.xml | 23 ++++++++++++ src/tests/monitor-store-unit-tests.c | 54 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/tests/monitor-configs/max-bpc.xml diff --git a/src/tests/monitor-configs/max-bpc.xml b/src/tests/monitor-configs/max-bpc.xml new file mode 100644 index 0000000000..c98e6605cc --- /dev/null +++ b/src/tests/monitor-configs/max-bpc.xml @@ -0,0 +1,23 @@ + + + + 0 + 0 + yes + + + DP-1 + MetaProduct's Inc. + MetaMonitor + 0x123456 + + + 1024 + 768 + 60.000495910644531 + + 12 + + + + diff --git a/src/tests/monitor-store-unit-tests.c b/src/tests/monitor-store-unit-tests.c index 38f4bc52fc..f8fd2b2628 100644 --- a/src/tests/monitor-store-unit-tests.c +++ b/src/tests/monitor-store-unit-tests.c @@ -48,6 +48,7 @@ typedef struct _MonitorStoreTestCaseMonitor const char *serial; MonitorStoreTestCaseMonitorMode mode; gboolean is_underscanning; + unsigned int max_bpc; } MonitorStoreTestCaseMonitor; typedef struct _MonitorStoreTestCaseLogicalMonitor @@ -196,6 +197,12 @@ check_monitor_store_configuration (MetaMonitorConfigStore *config_store, g_assert_cmpint (monitor_config->enable_underscanning, ==, test_monitor->is_underscanning); + g_assert_cmpint (monitor_config->has_max_bpc, + ==, + !!test_monitor->max_bpc); + g_assert_cmpint (monitor_config->max_bpc, + ==, + test_monitor->max_bpc); } } } @@ -446,6 +453,51 @@ meta_test_monitor_store_underscanning (void) check_monitor_store_configurations (&expect); } +static void +meta_test_monitor_store_max_bpc (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1024, + .height = 768 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .max_bpc = 12, + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + }, + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + meta_set_custom_monitor_config (test_context, "max-bpc.xml"); + + check_monitor_store_configurations (&expect); +} + static void meta_test_monitor_store_scale (void) { @@ -1013,6 +1065,8 @@ init_monitor_store_tests (void) meta_test_monitor_store_primary); g_test_add_func ("/backends/monitor-store/underscanning", meta_test_monitor_store_underscanning); + g_test_add_func ("/backends/monitor-store/max-bpc", + meta_test_monitor_store_max_bpc); g_test_add_func ("/backends/monitor-store/scale", meta_test_monitor_store_scale); g_test_add_func ("/backends/monitor-store/fractional-scale", -- GitLab