From 5edc118d62a73c5acc9ef78eec660f9890e71507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 8 Oct 2020 17:30:47 +0200 Subject: [PATCH] monitor-manager: Connect assigned CRTCs to their outputs both ways We had a pointer from the output to the assigned CRTC, but had no way to get the outputs an CRTC was assigned to. Add that connection. Part-of: --- src/backends/meta-crtc.c | 30 ++++++++++++++++++++ src/backends/meta-crtc.h | 10 +++++++ src/backends/meta-output.c | 12 +++++++- src/tests/monitor-test-utils.c | 52 ++++++++++++++++++++++++++++++---- 4 files changed, 98 insertions(+), 6 deletions(-) diff --git a/src/backends/meta-crtc.c b/src/backends/meta-crtc.c index ea0b24431..09f9199d5 100644 --- a/src/backends/meta-crtc.c +++ b/src/backends/meta-crtc.c @@ -44,6 +44,7 @@ typedef struct _MetaCrtcPrivate MetaMonitorTransform all_transforms; + GList *outputs; MetaCrtcConfig *config; } MetaCrtcPrivate; @@ -65,6 +66,34 @@ meta_crtc_get_gpu (MetaCrtc *crtc) return priv->gpu; } +const GList * +meta_crtc_get_outputs (MetaCrtc *crtc) +{ + MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc); + + return priv->outputs; +} + +void +meta_crtc_assign_output (MetaCrtc *crtc, + MetaOutput *output) +{ + MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc); + + priv->outputs = g_list_append (priv->outputs, output); +} + +void +meta_crtc_unassign_output (MetaCrtc *crtc, + MetaOutput *output) +{ + MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc); + + g_return_if_fail (g_list_find (priv->outputs, output)); + + priv->outputs = g_list_remove (priv->outputs, output); +} + MetaMonitorTransform meta_crtc_get_all_transforms (MetaCrtc *crtc) { @@ -165,6 +194,7 @@ meta_crtc_finalize (GObject *object) MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc); g_clear_pointer (&priv->config, g_free); + g_clear_pointer (&priv->outputs, g_list_free); G_OBJECT_CLASS (meta_crtc_parent_class)->finalize (object); } diff --git a/src/backends/meta-crtc.h b/src/backends/meta-crtc.h index 50db1a532..f6a3bc136 100644 --- a/src/backends/meta-crtc.h +++ b/src/backends/meta-crtc.h @@ -50,6 +50,16 @@ uint64_t meta_crtc_get_id (MetaCrtc *crtc); META_EXPORT_TEST MetaGpu * meta_crtc_get_gpu (MetaCrtc *crtc); +META_EXPORT_TEST +const GList * meta_crtc_get_outputs (MetaCrtc *crtc); + +void meta_crtc_assign_output (MetaCrtc *crtc, + MetaOutput *output); + +META_EXPORT_TEST +void meta_crtc_unassign_output (MetaCrtc *crtc, + MetaOutput *output); + MetaMonitorTransform meta_crtc_get_all_transforms (MetaCrtc *crtc); META_EXPORT_TEST diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c index 8f1131c0e..f8ce8655e 100644 --- a/src/backends/meta-output.c +++ b/src/backends/meta-output.c @@ -22,6 +22,8 @@ #include "backends/edid.h" #include "backends/meta-output.h" +#include "backends/meta-crtc.h" + enum { PROP_0, @@ -191,8 +193,12 @@ meta_output_assign_crtc (MetaOutput *output, g_assert (crtc); + meta_output_unassign_crtc (output); + g_set_object (&priv->crtc, crtc); + meta_crtc_assign_output (crtc, output); + priv->is_primary = output_assignment->is_primary; priv->is_presentation = output_assignment->is_presentation; priv->is_underscanning = output_assignment->is_underscanning; @@ -203,7 +209,11 @@ meta_output_unassign_crtc (MetaOutput *output) { MetaOutputPrivate *priv = meta_output_get_instance_private (output); - g_clear_object (&priv->crtc); + if (priv->crtc) + { + meta_crtc_unassign_output (priv->crtc, output); + g_clear_object (&priv->crtc); + } priv->is_primary = FALSE; priv->is_presentation = FALSE; diff --git a/src/tests/monitor-test-utils.c b/src/tests/monitor-test-utils.c index a83d8c8e2..a2a0b08a1 100644 --- a/src/tests/monitor-test-utils.c +++ b/src/tests/monitor-test-utils.c @@ -226,8 +226,9 @@ logical_monitor_from_layout (MetaMonitorManager *monitor_manager, } static void -check_logical_monitor (MetaMonitorManager *monitor_manager, - MonitorTestCaseLogicalMonitor *test_logical_monitor) +check_logical_monitor (MetaMonitorManager *monitor_manager, + MonitorTestCaseLogicalMonitor *test_logical_monitor, + GList **all_crtcs) { MetaLogicalMonitor *logical_monitor; MetaOutput *primary_output; @@ -295,8 +296,19 @@ check_logical_monitor (MetaMonitorManager *monitor_manager, } crtc = meta_output_get_assigned_crtc (output); - g_assert (!crtc || - meta_monitor_get_logical_monitor (monitor) == logical_monitor); + if (crtc) + { + g_assert (meta_monitor_get_logical_monitor (monitor) == + logical_monitor); + g_assert (g_list_find ((GList *) meta_crtc_get_outputs (crtc), + output)); + *all_crtcs = g_list_remove (*all_crtcs, crtc); + } + else + { + g_assert_null (crtc); + } + g_assert_cmpint (logical_monitor->is_presentation, ==, meta_output_is_presentation (output)); @@ -320,6 +332,7 @@ check_monitor_configuration (MonitorTestCaseExpect *expect) GList *monitors; GList *crtcs; int n_logical_monitors; + GList *all_crtcs; GList *l; int i; @@ -488,15 +501,32 @@ check_monitor_configuration (MonitorTestCaseExpect *expect) g_assert (logical_monitor == monitor_manager->primary_logical_monitor); } + all_crtcs = NULL; + for (l = meta_backend_get_gpus (backend); l; l = l->next) + { + MetaGpu *gpu = l->data; + + all_crtcs = g_list_concat (all_crtcs, + g_list_copy (meta_gpu_get_crtcs (gpu))); + } + for (i = 0; i < expect->n_logical_monitors; i++) { MonitorTestCaseLogicalMonitor *test_logical_monitor = &expect->logical_monitors[i]; - check_logical_monitor (monitor_manager, test_logical_monitor); + check_logical_monitor (monitor_manager, test_logical_monitor, &all_crtcs); } g_assert_cmpint (n_logical_monitors, ==, i); + for (l = all_crtcs; l; l = l->next) + { + MetaCrtc *crtc = l->data; + + g_assert_null (meta_crtc_get_outputs (crtc)); + } + g_list_free (all_crtcs); + crtcs = meta_gpu_get_crtcs (gpu); for (l = crtcs, i = 0; l; l = l->next, i++) { @@ -505,11 +535,23 @@ check_monitor_configuration (MonitorTestCaseExpect *expect) if (expect->crtcs[i].current_mode == -1) { + g_assert_null (meta_crtc_get_outputs (crtc)); g_assert_null (crtc_config); } else { MetaCrtcMode *expected_current_mode; + const GList *l_output; + + for (l_output = meta_crtc_get_outputs (crtc); + l_output; + l_output = l_output->next) + { + MetaOutput *output = l_output->data; + + g_assert (meta_output_get_assigned_crtc (output) == crtc); + g_assert_null (g_list_find (l_output->next, output)); + } g_assert_nonnull (crtc_config);