[mutter] wayland/output: Make each wl_output correspond to one monitor



commit bf7c34507dbfc787d3d1b76d4ca75583e47a832c
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Feb 5 17:22:30 2021 +0100

    wayland/output: Make each wl_output correspond to one monitor
    
    This is more in line with the protocol, and allows us to remove some
    awkward code that tries to "combine" different metadata from different
    monitors into one, which sometimes meant picking an arbitrary "main"
    monitor, or "and" metadata together to find a common ground.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1712>

 src/wayland/meta-wayland-outputs.c | 185 +++++++++++++++----------------------
 src/wayland/meta-wayland.c         |   5 +-
 2 files changed, 76 insertions(+), 114 deletions(-)
---
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
index bae4ee2dc9..549a5dc97e 100644
--- a/src/wayland/meta-wayland-outputs.c
+++ b/src/wayland/meta-wayland-outputs.c
@@ -53,7 +53,6 @@ struct _MetaWaylandOutput
   GObject parent;
 
   struct wl_global *global;
-  MetaLogicalMonitor *logical_monitor;
   uint32_t mode_flags;
   float refresh_rate;
   int scale;
@@ -63,7 +62,7 @@ struct _MetaWaylandOutput
   GList *resources;
   GList *xdg_output_resources;
 
-  uint64_t winsys_id;
+  MetaMonitor *monitor;
 };
 
 G_DEFINE_TYPE (MetaWaylandOutput, meta_wayland_output, G_TYPE_OBJECT)
@@ -71,7 +70,7 @@ G_DEFINE_TYPE (MetaWaylandOutput, meta_wayland_output, G_TYPE_OBJECT)
 static void
 send_xdg_output_events (struct wl_resource *resource,
                         MetaWaylandOutput  *wayland_output,
-                        MetaLogicalMonitor *logical_monitor,
+                        MetaMonitor        *monitor,
                         gboolean            need_all_events,
                         gboolean           *pending_done_event);
 
@@ -84,7 +83,7 @@ meta_wayland_output_get_resources (MetaWaylandOutput *wayland_output)
 MetaLogicalMonitor *
 meta_wayland_output_get_logical_monitor (MetaWaylandOutput *wayland_output)
 {
-  return wayland_output->logical_monitor;
+  return meta_monitor_get_logical_monitor (wayland_output->monitor);
 }
 
 static void
@@ -99,15 +98,6 @@ output_resource_destroy (struct wl_resource *res)
   wayland_output->resources = g_list_remove (wayland_output->resources, res);
 }
 
-static MetaMonitor *
-pick_main_monitor (MetaLogicalMonitor *logical_monitor)
-{
-  GList *monitors;
-
-  monitors = meta_logical_monitor_get_monitors (logical_monitor);
-  return g_list_first (monitors)->data;
-}
-
 static enum wl_output_subpixel
 cogl_subpixel_order_to_wl_output_subpixel (CoglSubpixelOrder subpixel_order)
 {
@@ -131,37 +121,13 @@ cogl_subpixel_order_to_wl_output_subpixel (CoglSubpixelOrder subpixel_order)
   return WL_OUTPUT_SUBPIXEL_UNKNOWN;
 }
 
-static enum wl_output_subpixel
-calculate_suitable_subpixel_order (MetaLogicalMonitor *logical_monitor)
-{
-  GList *monitors;
-  GList *l;
-  MetaMonitor *first_monitor;
-  CoglSubpixelOrder subpixel_order;
-
-  monitors = meta_logical_monitor_get_monitors (logical_monitor);
-  first_monitor = monitors->data;
-  subpixel_order = meta_monitor_get_subpixel_order (first_monitor);
-
-  for (l = monitors->next; l; l = l->next)
-    {
-      MetaMonitor *monitor = l->data;
-
-      if (meta_monitor_get_subpixel_order (monitor) != subpixel_order)
-        {
-          subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
-          break;
-        }
-    }
-
-  return cogl_subpixel_order_to_wl_output_subpixel (subpixel_order);
-}
-
 static int
-calculate_wayland_output_scale (MetaLogicalMonitor *logical_monitor)
+calculate_wayland_output_scale (MetaMonitor *monitor)
 {
+  MetaLogicalMonitor *logical_monitor;
   float scale;
 
+  logical_monitor = meta_monitor_get_logical_monitor (monitor);
   scale = meta_logical_monitor_get_scale (logical_monitor);
   return ceilf (scale);
 }
@@ -200,13 +166,15 @@ is_different_rotation (MetaLogicalMonitor *a,
 }
 
 static void
-get_native_output_mode_resolution (MetaLogicalMonitor *logical_monitor,
-                                   MetaMonitorMode    *mode,
-                                   int                *mode_width,
-                                   int                *mode_height)
+get_native_output_mode_resolution (MetaMonitor     *monitor,
+                                   MetaMonitorMode *mode,
+                                   int             *mode_width,
+                                   int             *mode_height)
 {
+  MetaLogicalMonitor *logical_monitor;
   MetaMonitorTransform transform;
 
+  logical_monitor = meta_monitor_get_logical_monitor (monitor);
   transform = meta_logical_monitor_get_transform (logical_monitor);
   if (meta_monitor_transform_is_rotated (transform))
     meta_monitor_mode_get_resolution (mode, mode_height, mode_width);
@@ -217,15 +185,15 @@ get_native_output_mode_resolution (MetaLogicalMonitor *logical_monitor,
 static void
 send_output_events (struct wl_resource *resource,
                     MetaWaylandOutput  *wayland_output,
-                    MetaLogicalMonitor *logical_monitor,
+                    MetaMonitor        *monitor,
                     gboolean            need_all_events,
                     gboolean           *pending_done_event)
 {
   int version = wl_resource_get_version (resource);
-  MetaMonitor *monitor;
   MetaMonitorMode *current_mode;
   MetaMonitorMode *preferred_mode;
   guint mode_flags = WL_OUTPUT_MODE_CURRENT;
+  MetaLogicalMonitor *logical_monitor;
   MetaLogicalMonitor *old_logical_monitor;
   guint old_mode_flags;
   gint old_scale;
@@ -233,13 +201,13 @@ send_output_events (struct wl_resource *resource,
   float refresh_rate;
   int new_width, new_height;
 
-  old_logical_monitor = wayland_output->logical_monitor;
+  logical_monitor = meta_monitor_get_logical_monitor (monitor);
+  old_logical_monitor =
+    meta_monitor_get_logical_monitor (wayland_output->monitor);
   old_mode_flags = wayland_output->mode_flags;
   old_scale = wayland_output->scale;
   old_refresh_rate = wayland_output->refresh_rate;
 
-  monitor = pick_main_monitor (logical_monitor);
-
   current_mode = meta_monitor_get_current_mode (monitor);
   refresh_rate = meta_monitor_mode_get_refresh_rate (current_mode);
 
@@ -254,20 +222,16 @@ send_output_events (struct wl_resource *resource,
       const char *vendor;
       const char *product;
       uint32_t transform;
+      CoglSubpixelOrder cogl_subpixel_order;
       enum wl_output_subpixel subpixel_order;
 
-      /*
-       * While the wl_output carries information specific to a single monitor,
-       * it is actually referring to a region of the compositor's screen region
-       * (logical monitor), which may consist of multiple monitors (clones).
-       * Arbitrarily use whatever monitor is the first in the logical monitor
-       * and use that for these details.
-       */
       get_rotated_physical_dimensions (monitor, &width_mm, &height_mm);
       vendor = meta_monitor_get_vendor (monitor);
       product = meta_monitor_get_product (monitor);
 
-      subpixel_order = calculate_suitable_subpixel_order (logical_monitor);
+      cogl_subpixel_order = meta_monitor_get_subpixel_order (monitor);
+      subpixel_order =
+        cogl_subpixel_order_to_wl_output_subpixel (cogl_subpixel_order);
 
       /*
        * TODO: When we support wl_surface.set_buffer_transform, pass along
@@ -293,7 +257,7 @@ send_output_events (struct wl_resource *resource,
   if (current_mode == preferred_mode)
     mode_flags |= WL_OUTPUT_MODE_PREFERRED;
 
-  get_native_output_mode_resolution (logical_monitor,
+  get_native_output_mode_resolution (monitor,
                                      current_mode,
                                      &new_width,
                                      &new_height);
@@ -315,7 +279,7 @@ send_output_events (struct wl_resource *resource,
     {
       int scale;
 
-      scale = calculate_wayland_output_scale (logical_monitor);
+      scale = calculate_wayland_output_scale (monitor);
       if (need_all_events ||
           old_scale != scale)
         {
@@ -341,10 +305,10 @@ bind_output (struct wl_client *client,
              guint32 id)
 {
   MetaWaylandOutput *wayland_output = data;
-  MetaLogicalMonitor *logical_monitor = wayland_output->logical_monitor;
+  MetaMonitor *monitor;
   struct wl_resource *resource;
 #ifdef WITH_VERBOSE_MODE
-  MetaMonitor *monitor;
+  MetaLogicalMonitor *logical_monitor;
 #endif
 
   resource = wl_resource_create (client, &wl_output_interface, version, id);
@@ -353,12 +317,12 @@ bind_output (struct wl_client *client,
   wl_resource_set_user_data (resource, wayland_output);
   wl_resource_set_destructor (resource, output_resource_destroy);
 
-  if (!logical_monitor)
+  monitor = wayland_output->monitor;
+  if (!monitor)
     return;
 
 #ifdef WITH_VERBOSE_MODE
-  monitor = pick_main_monitor (logical_monitor);
-
+  logical_monitor = meta_monitor_get_logical_monitor (monitor);
   meta_verbose ("Binding monitor %p/%s (%u, %u, %u, %u) x %f",
                 logical_monitor,
                 meta_monitor_get_product (monitor),
@@ -368,41 +332,38 @@ bind_output (struct wl_client *client,
                 wayland_output->refresh_rate);
 #endif
 
-  send_output_events (resource, wayland_output, logical_monitor, TRUE, NULL);
+  send_output_events (resource, wayland_output, monitor, TRUE, NULL);
 
   g_signal_emit (wayland_output, signals[OUTPUT_BOUND], 0, resource);
 }
 
 static void
-meta_wayland_output_set_logical_monitor (MetaWaylandOutput  *wayland_output,
-                                         MetaLogicalMonitor *logical_monitor)
+meta_wayland_output_set_monitor (MetaWaylandOutput *wayland_output,
+                                 MetaMonitor       *monitor)
 {
-  MetaMonitor *monitor;
   MetaMonitorMode *current_mode;
   MetaMonitorMode *preferred_mode;
 
-  wayland_output->logical_monitor = logical_monitor;
+  wayland_output->monitor = monitor;
   wayland_output->mode_flags = WL_OUTPUT_MODE_CURRENT;
 
-  monitor = pick_main_monitor (logical_monitor);
   current_mode = meta_monitor_get_current_mode (monitor);
   preferred_mode = meta_monitor_get_preferred_mode (monitor);
 
   if (current_mode == preferred_mode)
     wayland_output->mode_flags |= WL_OUTPUT_MODE_PREFERRED;
-  wayland_output->scale = calculate_wayland_output_scale (logical_monitor);
+  wayland_output->scale = calculate_wayland_output_scale (monitor);
   wayland_output->refresh_rate = meta_monitor_mode_get_refresh_rate (current_mode);
 
-  wayland_output->winsys_id = logical_monitor->winsys_id;
-  get_native_output_mode_resolution (logical_monitor,
+  get_native_output_mode_resolution (monitor,
                                      current_mode,
                                      &wayland_output->mode_width,
                                      &wayland_output->mode_height);
 }
 
 static void
-wayland_output_update_for_output (MetaWaylandOutput  *wayland_output,
-                                  MetaLogicalMonitor *logical_monitor)
+wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
+                                  MetaMonitor       *monitor)
 {
   GList *iter;
   gboolean pending_done_event;
@@ -411,13 +372,17 @@ wayland_output_update_for_output (MetaWaylandOutput  *wayland_output,
   for (iter = wayland_output->resources; iter; iter = iter->next)
     {
       struct wl_resource *resource = iter->data;
-      send_output_events (resource, wayland_output, logical_monitor, FALSE, &pending_done_event);
+
+      send_output_events (resource, wayland_output, monitor,
+                          FALSE, &pending_done_event);
     }
 
   for (iter = wayland_output->xdg_output_resources; iter; iter = iter->next)
     {
       struct wl_resource *xdg_output = iter->data;
-      send_xdg_output_events (xdg_output, wayland_output, logical_monitor, FALSE, &pending_done_event);
+
+      send_xdg_output_events (xdg_output, wayland_output, monitor,
+                              FALSE, &pending_done_event);
     }
 
   /* Send the "done" events if needed */
@@ -437,14 +402,13 @@ wayland_output_update_for_output (MetaWaylandOutput  *wayland_output,
             zxdg_output_v1_send_done (xdg_output);
         }
     }
-  /* It's very important that we change the output pointer here, as
-     the old structure is about to be freed by MetaMonitorManager */
-  meta_wayland_output_set_logical_monitor (wayland_output, logical_monitor);
+
+  meta_wayland_output_set_monitor (wayland_output, monitor);
 }
 
 static MetaWaylandOutput *
 meta_wayland_output_new (MetaWaylandCompositor *compositor,
-                         MetaLogicalMonitor    *logical_monitor)
+                         MetaMonitor           *monitor)
 {
   MetaWaylandOutput *wayland_output;
 
@@ -454,7 +418,7 @@ meta_wayland_output_new (MetaWaylandCompositor *compositor,
                                              META_WL_OUTPUT_VERSION,
                                              wayland_output, bind_output);
   meta_wayland_compositor_flush_clients (compositor);
-  meta_wayland_output_set_logical_monitor (wayland_output, logical_monitor);
+  meta_wayland_output_set_monitor (wayland_output, monitor);
 
   return wayland_output;
 }
@@ -492,7 +456,7 @@ make_output_inert (gpointer key,
 
   g_signal_emit (wayland_output, signals[OUTPUT_DESTROYED], 0);
 
-  wayland_output->logical_monitor = NULL;
+  wayland_output->monitor = NULL;
   make_output_resources_inert (wayland_output);
 }
 
@@ -508,42 +472,42 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
                                         MetaMonitorManager    *monitor_manager)
 {
   GHashTable *new_table;
-  GList *logical_monitors, *l;
+  GList *monitors, *l;
 
-  logical_monitors =
-    meta_monitor_manager_get_logical_monitors (monitor_manager);
-  new_table = g_hash_table_new_full (g_int64_hash, g_int64_equal, NULL,
+  monitors = meta_monitor_manager_get_monitors (monitor_manager);
+  new_table = g_hash_table_new_full (meta_monitor_spec_hash,
+                                     (GEqualFunc) meta_monitor_spec_equals,
+                                     (GDestroyNotify) meta_monitor_spec_free,
                                      g_object_unref);
 
-  for (l = logical_monitors; l; l = l->next)
+  for (l = monitors; l; l = l->next)
     {
-      MetaLogicalMonitor *logical_monitor = l->data;
+      MetaMonitor *monitor = l->data;
+      MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor);
       MetaWaylandOutput *wayland_output = NULL;
 
-      if (logical_monitor->winsys_id == 0)
+      if (!meta_monitor_is_active (monitor))
         continue;
 
-      wayland_output = g_hash_table_lookup (compositor->outputs,
-                                            &logical_monitor->winsys_id);
+      if (compositor->outputs)
+        wayland_output = g_hash_table_lookup (compositor->outputs, monitor_spec);
 
       if (wayland_output)
-        {
-          g_hash_table_steal (compositor->outputs,
-                              &logical_monitor->winsys_id);
-        }
+        g_hash_table_steal (compositor->outputs, monitor_spec);
       else
-        {
-          wayland_output = meta_wayland_output_new (compositor, logical_monitor);
-        }
+        wayland_output = meta_wayland_output_new (compositor, monitor);
 
-      wayland_output_update_for_output (wayland_output, logical_monitor);
+      wayland_output_update_for_output (wayland_output, monitor);
       g_hash_table_insert (new_table,
-                           &wayland_output->winsys_id,
+                           meta_monitor_spec_clone (monitor_spec),
                            wayland_output);
     }
 
-  g_hash_table_foreach (compositor->outputs, make_output_inert, NULL);
-  g_timeout_add_seconds (10, delayed_destroy_outputs, compositor->outputs);
+  if (compositor->outputs)
+    {
+      g_hash_table_foreach (compositor->outputs, make_output_inert, NULL);
+      g_timeout_add_seconds (10, delayed_destroy_outputs, compositor->outputs);
+    }
 
   return new_table;
 }
@@ -626,19 +590,21 @@ static const struct zxdg_output_v1_interface
 static void
 send_xdg_output_events (struct wl_resource *resource,
                         MetaWaylandOutput  *wayland_output,
-                        MetaLogicalMonitor *logical_monitor,
+                        MetaMonitor        *monitor,
                         gboolean            need_all_events,
                         gboolean           *pending_done_event)
 {
   MetaRectangle new_layout;
   MetaRectangle old_layout;
+  MetaLogicalMonitor *logical_monitor;
   MetaLogicalMonitor *old_logical_monitor;
-  MetaMonitor *monitor;
   gboolean need_done;
   int version;
 
   need_done = FALSE;
-  old_logical_monitor = wayland_output->logical_monitor;
+  logical_monitor = meta_monitor_get_logical_monitor (monitor);
+  old_logical_monitor =
+    meta_monitor_get_logical_monitor (wayland_output->monitor);
   old_layout = meta_logical_monitor_get_layout (old_logical_monitor);
   new_layout = meta_logical_monitor_get_layout (logical_monitor);
 
@@ -663,7 +629,6 @@ send_xdg_output_events (struct wl_resource *resource,
     }
 
   version = wl_resource_get_version (resource);
-  monitor = pick_main_monitor (logical_monitor);
 
   if (need_all_events && version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
     {
@@ -712,12 +677,12 @@ meta_xdg_output_manager_get_xdg_output (struct wl_client   *client,
   wayland_output->xdg_output_resources =
     g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);
 
-  if (!wayland_output->logical_monitor)
+  if (!wayland_output->monitor)
     return;
 
   send_xdg_output_events (xdg_output_resource,
                           wayland_output,
-                          wayland_output->logical_monitor,
+                          wayland_output->monitor,
                           TRUE, NULL);
 
   xdg_output_version = wl_resource_get_version (xdg_output_resource);
@@ -768,8 +733,6 @@ meta_wayland_outputs_init (MetaWaylandCompositor *compositor)
   g_signal_connect (monitors, "monitors-changed-internal",
                     G_CALLBACK (on_monitors_changed), compositor);
 
-  compositor->outputs = g_hash_table_new_full (g_int64_hash, g_int64_equal, NULL,
-                                               g_object_unref);
   compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors);
 
   wl_global_create (compositor->wayland_display,
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index e2832bbc41..089b2d5026 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -240,7 +240,6 @@ get_output_for_stage_view (MetaWaylandCompositor *compositor,
   MetaCrtc *crtc;
   MetaOutput *output;
   MetaMonitor *monitor;
-  MetaLogicalMonitor *logical_monitor;
 
   crtc = meta_renderer_view_get_crtc (META_RENDERER_VIEW (stage_view));
 
@@ -251,8 +250,8 @@ get_output_for_stage_view (MetaWaylandCompositor *compositor,
   output = meta_crtc_get_outputs (crtc)->data;
 
   monitor = meta_output_get_monitor (output);
-  logical_monitor = meta_monitor_get_logical_monitor (monitor);
-  return g_hash_table_lookup (compositor->outputs, &logical_monitor->winsys_id);
+  return g_hash_table_lookup (compositor->outputs,
+                              meta_monitor_get_spec (monitor));
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]