[mutter] Reshuffle Wayland initailization



commit 1571f8078a23b7cbd794e7f9479cf3512bf01122
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Apr 27 13:30:26 2020 +0200

    Reshuffle Wayland initailization
    
    Move Wayland support (i.e. the MetaWaylandCompositor object) made to be
    part of the backend. This is due to the fact that it is needed by the
    backend initialization, e.g. the Wayland EGLDisplay server support.
    
    The backend is changed to be more involved in Wayland and clutter
    initialization, so that the parts needed for clutter initialization
    happens before clutter itself initialization happens, and the rest
    happens after. This simplifies the setup a bit, as clutter and Wayland
    init now happens as part of the backend initialization.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1218

 src/backends/meta-backend-private.h               |   8 +
 src/backends/meta-backend-types.h                 |   2 +
 src/backends/meta-backend.c                       | 216 +++++++++++++---------
 src/backends/native/meta-backend-native.c         |   8 +
 src/backends/x11/nested/meta-backend-x11-nested.c |  46 ++++-
 src/compositor/compositor.c                       |  10 +-
 src/core/main.c                                   |  13 --
 src/wayland/meta-wayland.c                        |  33 ++--
 src/wayland/meta-wayland.h                        |   6 +-
 9 files changed, 214 insertions(+), 128 deletions(-)
---
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index 4678f7768a..5b0c849ec7 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -108,6 +108,14 @@ struct _MetaBackendClass
 
 void meta_init_backend (GType backend_gtype);
 
+#ifdef HAVE_WAYLAND
+MetaWaylandCompositor * meta_backend_get_wayland_compositor (MetaBackend *backend);
+
+void meta_backend_init_wayland_display (MetaBackend *backend);
+
+void meta_backend_init_wayland (MetaBackend *backend);
+#endif
+
 ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
 
 MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend        *backend,
diff --git a/src/backends/meta-backend-types.h b/src/backends/meta-backend-types.h
index 98cac8b9e2..2961a8b206 100644
--- a/src/backends/meta-backend-types.h
+++ b/src/backends/meta-backend-types.h
@@ -54,4 +54,6 @@ typedef struct _MetaScreenCast MetaScreenCast;
 typedef struct _MetaScreenCastSession MetaScreenCastSession;
 typedef struct _MetaScreenCastStream MetaScreenCastStream;
 
+typedef struct _MetaWaylandCompositor MetaWaylandCompositor;
+
 #endif /* META_BACKEND_TYPE_H */
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 1c6a6783a6..d6892f5bb6 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -81,6 +81,10 @@
 #include "backends/native/meta-backend-native.h"
 #endif
 
+#ifdef HAVE_WAYLAND
+#include "wayland/meta-wayland.h"
+#endif
+
 enum
 {
   KEYMAP_CHANGED,
@@ -130,6 +134,10 @@ struct _MetaBackendPrivate
   MetaRemoteDesktop *remote_desktop;
 #endif
 
+#ifdef HAVE_WAYLAND
+  MetaWaylandCompositor *wayland_compositor;
+#endif
+
 #ifdef HAVE_PROFILER
   MetaProfiler *profiler;
 #endif
@@ -864,6 +872,120 @@ system_bus_gotten_cb (GObject      *object,
                                         NULL);
 }
 
+#ifdef HAVE_WAYLAND
+MetaWaylandCompositor *
+meta_backend_get_wayland_compositor (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  return priv->wayland_compositor;
+}
+
+void
+meta_backend_init_wayland_display (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  priv->wayland_compositor = meta_wayland_compositor_new ();
+}
+
+void
+meta_backend_init_wayland (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  meta_wayland_compositor_setup (priv->wayland_compositor);
+}
+#endif
+
+/* Mutter is responsible for pulling events off the X queue, so Clutter
+ * doesn't need (and shouldn't) run its normal event source which polls
+ * the X fd, but we do have to deal with dispatching events that accumulate
+ * in the clutter queue. This happens, for example, when clutter generate
+ * enter/leave events on mouse motion - several events are queued in the
+ * clutter queue but only one dispatched. It could also happen because of
+ * explicit calls to clutter_event_put(). We add a very simple custom
+ * event loop source which is simply responsible for pulling events off
+ * of the queue and dispatching them before we block for new events.
+ */
+
+static gboolean
+clutter_source_prepare (GSource *source,
+                        int     *timeout)
+{
+  *timeout = -1;
+
+  return clutter_events_pending ();
+}
+
+static gboolean
+clutter_source_check (GSource *source)
+{
+  return clutter_events_pending ();
+}
+
+static gboolean
+clutter_source_dispatch (GSource     *source,
+                         GSourceFunc  callback,
+                         gpointer     user_data)
+{
+  ClutterEvent *event = clutter_event_get ();
+
+  if (event)
+    {
+      clutter_do_event (event);
+      clutter_event_free (event);
+    }
+
+  return TRUE;
+}
+
+static GSourceFuncs clutter_source_funcs = {
+  clutter_source_prepare,
+  clutter_source_check,
+  clutter_source_dispatch
+};
+
+static ClutterBackend *
+meta_get_clutter_backend (void)
+{
+  MetaBackend *backend = meta_get_backend ();
+
+  return meta_backend_get_clutter_backend (backend);
+}
+
+static gboolean
+init_clutter (MetaBackend  *backend,
+              GError      **error)
+{
+  GSource *source;
+
+  clutter_set_custom_backend_func (meta_get_clutter_backend);
+
+  if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Unable to initialize Clutter");
+      return FALSE;
+    }
+
+  source = g_source_new (&clutter_source_funcs, sizeof (GSource));
+  g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  return TRUE;
+}
+
+static void
+meta_backend_post_init (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  META_BACKEND_GET_CLASS (backend)->post_init (backend);
+
+  meta_settings_post_init (priv->settings);
+}
+
 static gboolean
 meta_backend_initable_init (GInitable     *initable,
                             GCancellable  *cancellable,
@@ -902,6 +1024,11 @@ meta_backend_initable_init (GInitable     *initable,
   priv->profiler = meta_profiler_new ();
 #endif
 
+  if (!init_clutter (backend, error))
+    return FALSE;
+
+  meta_backend_post_init (backend);
+
   return TRUE;
 }
 
@@ -917,16 +1044,6 @@ meta_backend_init (MetaBackend *backend)
   _backend = backend;
 }
 
-static void
-meta_backend_post_init (MetaBackend *backend)
-{
-  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
-  META_BACKEND_GET_CLASS (backend)->post_init (backend);
-
-  meta_settings_post_init (priv->settings);
-}
-
 /**
  * meta_backend_get_idle_monitor: (skip)
  */
@@ -1258,54 +1375,6 @@ meta_backend_set_client_pointer_constraint (MetaBackend           *backend,
     priv->client_pointer_constraint = g_object_ref (constraint);
 }
 
-/* Mutter is responsible for pulling events off the X queue, so Clutter
- * doesn't need (and shouldn't) run its normal event source which polls
- * the X fd, but we do have to deal with dispatching events that accumulate
- * in the clutter queue. This happens, for example, when clutter generate
- * enter/leave events on mouse motion - several events are queued in the
- * clutter queue but only one dispatched. It could also happen because of
- * explicit calls to clutter_event_put(). We add a very simple custom
- * event loop source which is simply responsible for pulling events off
- * of the queue and dispatching them before we block for new events.
- */
-
-static gboolean
-event_prepare (GSource    *source,
-               gint       *timeout_)
-{
-  *timeout_ = -1;
-
-  return clutter_events_pending ();
-}
-
-static gboolean
-event_check (GSource *source)
-{
-  return clutter_events_pending ();
-}
-
-static gboolean
-event_dispatch (GSource    *source,
-                GSourceFunc callback,
-                gpointer    user_data)
-{
-  ClutterEvent *event = clutter_event_get ();
-
-  if (event)
-    {
-      clutter_do_event (event);
-      clutter_event_free (event);
-    }
-
-  return TRUE;
-}
-
-static GSourceFuncs event_funcs = {
-  event_prepare,
-  event_check,
-  event_dispatch
-};
-
 ClutterBackend *
 meta_backend_get_clutter_backend (MetaBackend *backend)
 {
@@ -1320,14 +1389,6 @@ meta_backend_get_clutter_backend (MetaBackend *backend)
   return priv->clutter_backend;
 }
 
-static ClutterBackend *
-meta_get_clutter_backend (void)
-{
-  MetaBackend *backend = meta_get_backend ();
-
-  return meta_backend_get_clutter_backend (backend);
-}
-
 void
 meta_init_backend (GType backend_gtype)
 {
@@ -1344,29 +1405,6 @@ meta_init_backend (GType backend_gtype)
     }
 }
 
-/**
- * meta_clutter_init: (skip)
- */
-void
-meta_clutter_init (void)
-{
-  GSource *source;
-
-  clutter_set_custom_backend_func (meta_get_clutter_backend);
-
-  if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
-    {
-      g_warning ("Unable to initialize Clutter.\n");
-      exit (1);
-    }
-
-  source = g_source_new (&event_funcs, sizeof (GSource));
-  g_source_attach (source, NULL);
-  g_source_unref (source);
-
-  meta_backend_post_init (_backend);
-}
-
 /**
  * meta_is_stage_views_enabled:
  *
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index 6c4a474e2d..e5a16f3374 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -366,6 +366,10 @@ meta_backend_native_post_init (MetaBackend *backend)
       if (retval != 0)
         g_warning ("Failed to set RT scheduler: %m");
     }
+
+#ifdef HAVE_WAYLAND
+  meta_backend_init_wayland (backend);
+#endif
 }
 
 static MetaMonitorManager *
@@ -647,6 +651,10 @@ meta_backend_native_initable_init (GInitable     *initable,
   if (!native->launcher)
     return FALSE;
 
+#ifdef HAVE_WAYLAND
+  meta_backend_init_wayland_display (META_BACKEND (native));
+#endif
+
   native->udev = meta_udev_new (native);
   native->barrier_manager = meta_barrier_manager_native_new ();
 
diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c 
b/src/backends/x11/nested/meta-backend-x11-nested.c
index b9e7ff3b86..def74bb749 100644
--- a/src/backends/x11/nested/meta-backend-x11-nested.c
+++ b/src/backends/x11/nested/meta-backend-x11-nested.c
@@ -33,8 +33,16 @@ typedef struct _MetaBackendX11NestedPrivate
   MetaGpu *gpu;
 } MetaBackendX11NestedPrivate;
 
-G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11Nested, meta_backend_x11_nested,
-                            META_TYPE_BACKEND_X11)
+static GInitableIface *initable_parent_iface;
+
+static void
+initable_iface_init (GInitableIface *initable_iface);
+
+G_DEFINE_TYPE_WITH_CODE (MetaBackendX11Nested, meta_backend_x11_nested,
+                         META_TYPE_BACKEND_X11,
+                         G_ADD_PRIVATE (MetaBackendX11Nested)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                                initable_iface_init));
 
 static MetaRenderer *
 meta_backend_x11_nested_create_renderer (MetaBackend *backend,
@@ -201,6 +209,39 @@ meta_backend_x11_nested_real_init_gpus (MetaBackendX11Nested *backend_x11_nested
   meta_backend_add_gpu (META_BACKEND (backend_x11_nested), priv->gpu);
 }
 
+static void
+meta_backend_x11_nested_post_init (MetaBackend *backend)
+{
+  MetaBackendClass *backend_class =
+    META_BACKEND_CLASS (meta_backend_x11_nested_parent_class);
+
+  backend_class->post_init (backend);
+
+#ifdef HAVE_WAYLAND
+  meta_backend_init_wayland (backend);
+#endif
+}
+
+static gboolean
+meta_backend_x11_nested_initable_init (GInitable     *initable,
+                                       GCancellable  *cancellable,
+                                       GError       **error)
+{
+#ifdef HAVE_WAYLAND
+  meta_backend_init_wayland_display (META_BACKEND (initable));
+#endif
+
+  return initable_parent_iface->init (initable, cancellable, error);
+}
+
+static void
+initable_iface_init (GInitableIface *initable_iface)
+{
+  initable_parent_iface = g_type_interface_peek_parent (initable_iface);
+
+  initable_iface->init = meta_backend_x11_nested_initable_init;
+}
+
 static void
 meta_backend_x11_nested_constructed (GObject *object)
 {
@@ -229,6 +270,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
 
   object_class->constructed = meta_backend_x11_nested_constructed;
 
+  backend_class->post_init = meta_backend_x11_nested_post_init;
   backend_class->create_renderer = meta_backend_x11_nested_create_renderer;
   backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
   backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer;
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 338817127e..d45d507432 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -502,11 +502,6 @@ after_stage_paint (ClutterStage *stage,
 
   for (l = priv->windows; l; l = l->next)
     meta_window_actor_post_paint (l->data);
-
-#ifdef HAVE_WAYLAND
-  if (meta_is_wayland_compositor ())
-    meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
-#endif
 }
 
 static void
@@ -1154,6 +1149,11 @@ meta_compositor_real_post_paint (MetaCompositor *compositor)
     meta_compositor_get_instance_private (compositor);
   CoglGraphicsResetStatus status;
 
+#ifdef HAVE_WAYLAND
+  if (meta_is_wayland_compositor ())
+    meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
+#endif
+
   status = cogl_get_graphics_reset_status (priv->context);
   switch (status)
     {
diff --git a/src/core/main.c b/src/core/main.c
index 16aa8736ab..16ab6e81f0 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -586,11 +586,6 @@ meta_init (void)
   g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
 #endif
 
-#ifdef HAVE_WAYLAND
-  if (meta_is_wayland_compositor ())
-    meta_wayland_pre_clutter_init ();
-#endif
-
   /* NB: When running as a hybrid wayland compositor we run our own headless X
    * server so the user can't control the X display to connect too. */
   if (!meta_is_wayland_compositor ())
@@ -598,14 +593,6 @@ meta_init (void)
 
   meta_init_backend (backend_gtype);
 
-  meta_clutter_init ();
-
-#ifdef HAVE_WAYLAND
-  /* Bring up Wayland. This also launches Xwayland and sets DISPLAY as well... */
-  if (meta_is_wayland_compositor ())
-    meta_wayland_init ();
-#endif
-
   meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL));
 
   if (opt_replace_wm)
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index f3f9226355..a7bf9158ce 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -47,7 +47,6 @@
 #include "wayland/meta-xwayland-private.h"
 #include "wayland/meta-xwayland.h"
 
-static MetaWaylandCompositor *_meta_wayland_compositor = NULL;
 static char *_display_name_override;
 
 G_DEFINE_TYPE (MetaWaylandCompositor, meta_wayland_compositor, G_TYPE_OBJECT)
@@ -55,9 +54,14 @@ G_DEFINE_TYPE (MetaWaylandCompositor, meta_wayland_compositor, G_TYPE_OBJECT)
 MetaWaylandCompositor *
 meta_wayland_compositor_get_default (void)
 {
-  g_assert (_meta_wayland_compositor);
+  MetaBackend *backend;
+  MetaWaylandCompositor *wayland_compositor;
 
-  return _meta_wayland_compositor;
+  backend = meta_get_backend ();
+  wayland_compositor = meta_backend_get_wayland_compositor (backend);
+  g_assert (wayland_compositor);
+
+  return wayland_compositor;
 }
 
 typedef struct
@@ -318,6 +322,8 @@ meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
   compositor->wayland_display = wl_display_create ();
   if (compositor->wayland_display == NULL)
     g_error ("Failed to create the global wl_display");
+
+  clutter_wayland_set_compositor_display (compositor->wayland_display);
 }
 
 static void
@@ -325,19 +331,6 @@ meta_wayland_compositor_class_init (MetaWaylandCompositorClass *klass)
 {
 }
 
-void
-meta_wayland_pre_clutter_init (void)
-{
-  MetaWaylandCompositor *compositor;
-
-  g_assert (!_meta_wayland_compositor);
-
-  compositor = g_object_new (META_TYPE_WAYLAND_COMPOSITOR, NULL);
-  clutter_wayland_set_compositor_display (compositor->wayland_display);
-
-  _meta_wayland_compositor = compositor;
-}
-
 static bool
 meta_xwayland_global_filter (const struct wl_client *client,
                              const struct wl_global *global,
@@ -368,8 +361,14 @@ meta_wayland_get_xwayland_auth_file (MetaWaylandCompositor *compositor)
   return compositor->xwayland_manager.auth_file;
 }
 
+MetaWaylandCompositor *
+meta_wayland_compositor_new (void)
+{
+  return g_object_new (META_TYPE_WAYLAND_COMPOSITOR, NULL);
+}
+
 void
-meta_wayland_init (void)
+meta_wayland_compositor_setup (MetaWaylandCompositor *wayland_compositor)
 {
   MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
   GSource *wayland_event_source;
diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h
index c5690c34ec..15b7310ba7 100644
--- a/src/wayland/meta-wayland.h
+++ b/src/wayland/meta-wayland.h
@@ -37,8 +37,10 @@ void                    meta_wayland_init                       (void);
 
 void                    meta_wayland_finalize                   (void);
 
-/* We maintain a singleton MetaWaylandCompositor which can be got at via this
- * API after meta_wayland_init() has been called. */
+MetaWaylandCompositor * meta_wayland_compositor_new             (void);
+
+void                    meta_wayland_compositor_setup           (MetaWaylandCompositor *compositor);
+
 META_EXPORT_TEST
 MetaWaylandCompositor  *meta_wayland_compositor_get_default     (void);
 


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