From 429e65b993def5ffeb36390efe5d7efeb811a50a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 28 Nov 2023 09:25:59 +0100
Subject: [PATCH] monitor-config-manager: Allow backends to assign extra data

When we're configuring monitors, allow backends to add backend specific
assignments during resource assignment (mapping connectors and CRTCs
etc).

This will later allow the native backend's KMS monitor resources to
assign a primary plane and optionally a cursor plane during
configuration. This will then dictate what plane will be used for
primary plane updates, as well as cursor updates, until reconfigured
again.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3428>
---
 src/backends/meta-crtc.c                      | 22 ++++++++++++++++++-
 src/backends/meta-crtc.h                      | 17 +++++++++++++-
 src/backends/meta-monitor-config-manager.c    |  8 +++++++
 src/backends/meta-monitor-manager-dummy.c     |  3 ++-
 src/backends/meta-monitor-manager-private.h   |  3 +++
 .../native/meta-monitor-manager-native.c      |  3 ++-
 src/backends/x11/meta-crtc-xrandr.c           |  2 +-
 .../x11/meta-monitor-manager-xrandr.c         |  3 ++-
 src/tests/meta-monitor-manager-test.c         |  3 ++-
 9 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/src/backends/meta-crtc.c b/src/backends/meta-crtc.c
index 8d27d204e..7235df263 100644
--- a/src/backends/meta-crtc.c
+++ b/src/backends/meta-crtc.c
@@ -112,11 +112,17 @@ meta_crtc_get_all_transforms (MetaCrtc *crtc)
 
 void
 meta_crtc_set_config (MetaCrtc       *crtc,
-                      MetaCrtcConfig *config)
+                      MetaCrtcConfig *config,
+                      gpointer        backend_private)
 {
   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
+  MetaCrtcClass *klass = META_CRTC_GET_CLASS (crtc);
 
   meta_crtc_unset_config (crtc);
+
+  if (klass->set_config)
+    klass->set_config (crtc, config, backend_private);
+
   priv->config = config;
 }
 
@@ -136,6 +142,20 @@ meta_crtc_get_config (MetaCrtc *crtc)
   return priv->config;
 }
 
+gboolean
+meta_crtc_assign_extra (MetaCrtc            *crtc,
+                        MetaCrtcAssignment  *crtc_assignment,
+                        GPtrArray           *crtc_assignments,
+                        GError             **error)
+{
+  MetaCrtcClass *klass = META_CRTC_GET_CLASS (crtc);
+
+  if (klass->assign_extra)
+    return klass->assign_extra (crtc, crtc_assignment, crtc_assignments, error);
+  else
+    return TRUE;
+}
+
 size_t
 meta_crtc_get_gamma_lut_size (MetaCrtc *crtc)
 {
diff --git a/src/backends/meta-crtc.h b/src/backends/meta-crtc.h
index b39c23b93..8e4e00f68 100644
--- a/src/backends/meta-crtc.h
+++ b/src/backends/meta-crtc.h
@@ -46,6 +46,15 @@ struct _MetaCrtcClass
 
   void (* set_gamma_lut) (MetaCrtc           *crtc,
                           const MetaGammaLut *lut);
+
+  gboolean (* assign_extra) (MetaCrtc            *crtc,
+                             MetaCrtcAssignment  *crtc_assignment,
+                             GPtrArray           *crtc_assignments,
+                             GError             **error);
+
+  void (* set_config) (MetaCrtc             *crtc,
+                       const MetaCrtcConfig *config,
+                       gpointer              backend_private);
 };
 
 META_EXPORT_TEST
@@ -71,7 +80,8 @@ MetaMonitorTransform meta_crtc_get_all_transforms (MetaCrtc *crtc);
 
 META_EXPORT_TEST
 void meta_crtc_set_config (MetaCrtc       *crtc,
-                           MetaCrtcConfig *config);
+                           MetaCrtcConfig *config,
+                           gpointer        backend_private);
 
 META_EXPORT_TEST
 void meta_crtc_unset_config (MetaCrtc *crtc);
@@ -79,6 +89,11 @@ void meta_crtc_unset_config (MetaCrtc *crtc);
 META_EXPORT_TEST
 const MetaCrtcConfig * meta_crtc_get_config (MetaCrtc *crtc);
 
+gboolean meta_crtc_assign_extra (MetaCrtc            *crtc,
+                                 MetaCrtcAssignment  *crtc_assignment,
+                                 GPtrArray           *crtc_assignments,
+                                 GError             **error);
+
 size_t meta_crtc_get_gamma_lut_size (MetaCrtc *crtc);
 
 MetaGammaLut * meta_crtc_get_gamma_lut (MetaCrtc *crtc);
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index 60f32ff4c..6d81822e9 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -261,6 +261,12 @@ assign_monitor_crtc (MetaMonitor         *monitor,
   };
   g_ptr_array_add (crtc_assignment->outputs, output);
 
+  if (!meta_crtc_assign_extra (crtc,
+                               crtc_assignment,
+                               data->crtc_assignments,
+                               error))
+    return FALSE;
+
   /*
    * Only one output can be marked as primary (due to Xrandr limitation),
    * so only mark the main output of the first monitor in the logical monitor
@@ -1748,6 +1754,8 @@ meta_monitors_config_class_init (MetaMonitorsConfigClass *klass)
 static void
 meta_crtc_assignment_free (MetaCrtcAssignment *assignment)
 {
+  g_clear_pointer (&assignment->backend_private,
+                   assignment->backend_private_destroy);
   g_ptr_array_free (assignment->outputs, TRUE);
   g_free (assignment);
 }
diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c
index 28f34f945..06e150418 100644
--- a/src/backends/meta-monitor-manager-dummy.c
+++ b/src/backends/meta-monitor-manager-dummy.c
@@ -522,7 +522,8 @@ apply_crtc_assignments (MetaMonitorManager    *manager,
           crtc_config = meta_crtc_config_new (&crtc_assignment->layout,
                                               crtc_assignment->mode,
                                               crtc_assignment->transform);
-          meta_crtc_set_config (crtc, crtc_config);
+          meta_crtc_set_config (crtc, crtc_config,
+                                crtc_assignment->backend_private);
 
           for (j = 0; j < crtc_assignment->outputs->len; j++)
             {
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index 2d45fe777..5f2f6846e 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -87,6 +87,9 @@ struct _MetaCrtcAssignment
   graphene_rect_t layout;
   MetaMonitorTransform transform;
   GPtrArray *outputs;
+
+  gpointer backend_private;
+  GDestroyNotify backend_private_destroy;
 };
 
 /*
diff --git a/src/backends/native/meta-monitor-manager-native.c b/src/backends/native/meta-monitor-manager-native.c
index df0a4b5ed..44600be57 100644
--- a/src/backends/native/meta-monitor-manager-native.c
+++ b/src/backends/native/meta-monitor-manager-native.c
@@ -220,7 +220,8 @@ apply_crtc_assignments (MetaMonitorManager    *manager,
           crtc_config = meta_crtc_config_new (&crtc_assignment->layout,
                                               crtc_assignment->mode,
                                               crtc_assignment->transform);
-          meta_crtc_set_config (crtc, crtc_config);
+          meta_crtc_set_config (crtc, crtc_config,
+                                crtc_assignment->backend_private);
 
           for (j = 0; j < crtc_assignment->outputs->len; j++)
             {
diff --git a/src/backends/x11/meta-crtc-xrandr.c b/src/backends/x11/meta-crtc-xrandr.c
index 19e7b942d..0b2d8cffe 100644
--- a/src/backends/x11/meta-crtc-xrandr.c
+++ b/src/backends/x11/meta-crtc-xrandr.c
@@ -293,7 +293,7 @@ meta_crtc_xrandr_new (MetaGpuXrandr      *gpu_xrandr,
                                                    crtc_xrandr->rect.height),
                               crtc_xrandr->current_mode,
                               crtc_xrandr->transform);
-      meta_crtc_set_config (META_CRTC (crtc_xrandr), crtc_config);
+      meta_crtc_set_config (META_CRTC (crtc_xrandr), crtc_config, NULL);
     }
 
   return crtc_xrandr;
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 2d8fd4d9c..404faf189 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -560,7 +560,8 @@ apply_crtc_assignments (MetaMonitorManager    *manager,
           crtc_config = meta_crtc_config_new (&crtc_assignment->layout,
                                               crtc_mode,
                                               crtc_assignment->transform);
-          meta_crtc_set_config (crtc, crtc_config);
+          meta_crtc_set_config (crtc, crtc_config,
+                                crtc_assignment->backend_private);
         }
     }
 
diff --git a/src/tests/meta-monitor-manager-test.c b/src/tests/meta-monitor-manager-test.c
index aa98b0600..f9275160c 100644
--- a/src/tests/meta-monitor-manager-test.c
+++ b/src/tests/meta-monitor-manager-test.c
@@ -184,7 +184,8 @@ apply_crtc_assignments (MetaMonitorManager    *manager,
           crtc_config = meta_crtc_config_new (&crtc_assignment->layout,
                                               crtc_assignment->mode,
                                               crtc_assignment->transform);
-          meta_crtc_set_config (crtc, crtc_config);
+          meta_crtc_set_config (crtc, crtc_config,
+                                crtc_assignment->backend_private);
 
           for (j = 0; j < crtc_assignment->outputs->len; j++)
             {