[PATCH v3 xserver 2/2] xwayland: Cache globals to avoid multiple registry objects

Tiago Vignatti tiago.vignatti at intel.com
Thu Nov 22 12:08:53 PST 2012


Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---

Hi Kristian, I guess that was the idea we discussed on IRC?

I kept the same order of the interfaces being bound, without thinking whether
their were the most efficient or something; we we'll have to overhaul the
WM and X server binding anyway when the next protocol comes in so I hope this
is okay for now.


 hw/xfree86/xwayland/xwayland-drm.c     |   35 ++++++++------------
 hw/xfree86/xwayland/xwayland-input.c   |   42 ++++--------------------
 hw/xfree86/xwayland/xwayland-output.c  |   38 ++++++++--------------
 hw/xfree86/xwayland/xwayland-private.h |   21 ++++++++----
 hw/xfree86/xwayland/xwayland.c         |   56 ++++++++++++++++++++++++++++++--
 5 files changed, 102 insertions(+), 90 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
index c19eb84..27328c1 100644
--- a/hw/xfree86/xwayland/xwayland-drm.c
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -75,30 +75,13 @@ static const struct wl_drm_listener xwl_drm_listener =
 };
 
 static void
-drm_handler(void *data, struct wl_registry *registry, uint32_t id,
-	    const char *interface, uint32_t version)
+xwl_drm_bind(struct xwl_screen *xwl_screen)
 {
-    struct xwl_screen *xwl_screen = data;
-
-    if (strcmp (interface, "wl_drm") == 0) {
-	xwl_screen->drm = wl_registry_bind(xwl_screen->registry, id,
-                                           &wl_drm_interface, 1);
-	wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen);
-    }
-}
-
-static const struct wl_registry_listener drm_listener = {
-    drm_handler,
-};
-
-int
-xwl_drm_pre_init(struct xwl_screen *xwl_screen)
-{
-    uint32_t magic;
+    struct xwl_global *xwl_global = xwl_global_get(xwl_screen, "wl_drm");
 
-    xwl_screen->drm_registry = wl_display_get_registry(xwl_screen->display);
-    wl_registry_add_listener(xwl_screen->drm_registry, &drm_listener,
-                             xwl_screen);
+    xwl_screen->drm = wl_registry_bind(xwl_screen->registry, xwl_global->id,
+                                       &wl_drm_interface, 1);
+    wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen);
 
     /* Ensure drm_handler has seen all the interfaces */
     wl_display_roundtrip(xwl_screen->display);
@@ -107,6 +90,14 @@ xwl_drm_pre_init(struct xwl_screen *xwl_screen)
 
     ErrorF("wayland_drm_screen_init, device name %s\n",
 	   xwl_screen->device_name);
+}
+
+int
+xwl_drm_pre_init(struct xwl_screen *xwl_screen)
+{
+    uint32_t magic;
+
+    xwl_drm_bind(xwl_screen);
 
     xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR);
     if (xwl_screen->drm_fd < 0) {
diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
index 44a14ba..0c0838d 100644
--- a/hw/xfree86/xwayland/xwayland-input.c
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -53,9 +53,6 @@
 
 #include "xwayland.h"
 #include "xwayland-private.h"
-#include "xserver-client-protocol.h"
-
-extern const struct xserver_listener xwl_server_listener;
 
 static void
 xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
@@ -492,9 +489,10 @@ static const struct wl_seat_listener seat_listener = {
 	seat_handle_capabilities,
 };
 
-static void
-create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
+void
+xwl_seat_bind(struct xwl_screen *xwl_screen)
 {
+    struct xwl_global *xwl_global = xwl_global_get(xwl_screen, "wl_seat");
     struct xwl_seat *xwl_seat;
 
     xwl_seat = calloc(sizeof *xwl_seat, 1);
@@ -506,39 +504,11 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
     xwl_seat->xwl_screen = xwl_screen;
     xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list);
 
-    xwl_seat->seat =
-	wl_registry_bind(xwl_screen->registry, id, &wl_seat_interface, 1);
-    xwl_seat->id = id;
+    xwl_seat->seat = wl_registry_bind(xwl_screen->registry, xwl_global->id,
+	                              &wl_seat_interface, 1);
+    xwl_seat->id = xwl_global->id;
 
     xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor);
     wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat);
     wl_array_init(&xwl_seat->keys);
 }
-
-static void
-input_handler(void *data, struct wl_registry *registry, uint32_t id,
-	      const char *interface, uint32_t version)
-{
-    struct xwl_screen *xwl_screen = data;
-
-    if (strcmp (interface, "wl_seat") == 0) {
-        create_input_device(xwl_screen, id);
-    } else if (strcmp(interface, "xserver") == 0) {
-        xwl_screen->xorg_server =
-            wl_registry_bind(registry, id, &xserver_interface, 1);
-        xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener,
-                             xwl_screen);
-    }
-}
-
-static const struct wl_registry_listener input_listener = {
-    input_handler,
-};
-
-void
-xwl_input_init(struct xwl_screen *xwl_screen)
-{
-    xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
-    wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
-                             xwl_screen);
-}
diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c
index 8f087f6..00b410b 100644
--- a/hw/xfree86/xwayland/xwayland-output.c
+++ b/hw/xfree86/xwayland/xwayland-output.c
@@ -267,43 +267,33 @@ static const struct wl_output_listener output_listener = {
 };
 
 static void
-global_handler(void *data, struct wl_registry *registry, uint32_t id,
-	       const char *interface, uint32_t version)
+xwl_output_bind(struct xwl_screen *xwl_screen)
 {
-    struct xwl_screen *xwl_screen = data;
+    struct xwl_global *xwl_global = xwl_global_get(xwl_screen, "wl_output");
     struct xwl_output *xwl_output;
+    int ret;
+
+    xwl_output = xwl_output_create(xwl_screen);
+    xwl_output->output = wl_registry_bind(xwl_screen->registry, xwl_global->id,
+                                          &wl_output_interface, 1);
+    wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
 
-    if (strcmp (interface, "wl_output") == 0) {
-	xwl_output = xwl_output_create(xwl_screen);
-	xwl_output->output = wl_registry_bind(registry, id,
-	                                      &wl_output_interface, 1);
-	wl_output_add_listener(xwl_output->output,
-			       &output_listener, xwl_output);
+    while (!xwl_screen->xwl_output) {
+        ret = wl_display_roundtrip(xwl_screen->display);
+        if (ret == -1)
+            FatalError("failed to dispatch Wayland events: %s\n",
+	               strerror(errno));
     }
 }
 
-static const struct wl_registry_listener global_listener = {
-    global_handler,
-};
-
 void
 xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo)
 {
-    int ret;
-
     xf86CrtcConfigInit(scrninfo, &config_funcs);
 
     xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192);
 
-    xwl_screen->output_registry = wl_display_get_registry(xwl_screen->display);
-    wl_registry_add_listener(xwl_screen->output_registry, &global_listener,
-                             xwl_screen);
-
-    while (!xwl_screen->xwl_output) {
-        ret = wl_display_roundtrip(xwl_screen->display);
-        if (ret == -1)
-            FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
-    }
+    xwl_output_bind(xwl_screen);
 
     xf86InitialConfiguration(scrninfo, TRUE);
 }
diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
index 23263d0..2716ebe 100644
--- a/hw/xfree86/xwayland/xwayland-private.h
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -38,6 +38,14 @@ struct xwl_window {
 
 struct xwl_output;
 
+struct xwl_global {
+    uint32_t			 id;
+    char			*interface;
+    uint32_t			 version;
+
+    struct xorg_list		 link;
+};
+
 struct xwl_screen {
     struct xwl_driver		*driver;
     ScreenPtr			 screen;
@@ -46,10 +54,10 @@ struct xwl_screen {
     int				 wayland_fd;
     struct xwl_output		*xwl_output;
     struct wl_display		*display;
+
+    struct xorg_list		 global_list;
     struct wl_registry          *registry;
-    struct wl_registry          *drm_registry;
-    struct wl_registry          *input_registry;
-    struct wl_registry          *output_registry;
+
     struct wl_compositor	*compositor;
     struct wl_drm		*drm;
     struct wl_shm		*shm;
@@ -100,6 +108,9 @@ struct xwl_seat {
     CursorPtr                    x_cursor;
 };
 
+struct xwl_global *
+xwl_global_get(struct xwl_screen *xwl_screen, const char *interface);
+
 struct xwl_screen *xwl_screen_get(ScreenPtr screen);
 
 void xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo);
@@ -111,12 +122,10 @@ struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen);
 
 void xwl_input_teardown(pointer p);
 pointer xwl_input_setup(pointer module, pointer opts, int *errmaj, int *errmin);
-void xwl_input_init(struct xwl_screen *screen);
 
 Bool xwl_drm_initialised(struct xwl_screen *screen);
 
+void xwl_seat_bind(struct xwl_screen *screen);
 void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
 
-extern const struct xserver_listener xwl_server_listener;
-
 #endif /* _XWAYLAND_PRIVATE_H_ */
diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
index 98e036e..3396e5f 100644
--- a/hw/xfree86/xwayland/xwayland.c
+++ b/hw/xfree86/xwayland/xwayland.c
@@ -68,12 +68,23 @@ xserver_listen_socket(void *data, struct xserver *xserver, int fd)
     ListenOnOpenFD(fd, TRUE);
 }
 
-const struct xserver_listener xwl_server_listener = {
+static const struct xserver_listener xwl_server_listener = {
     xserver_client,
     xserver_listen_socket
 };
 
 static void
+xwl_xserver_bind(struct xwl_screen *xwl_screen)
+{
+    struct xwl_global *xwl_global = xwl_global_get(xwl_screen, "xserver");
+
+    xwl_screen->xorg_server = wl_registry_bind(xwl_screen->registry,
+	                             xwl_global->id, &xserver_interface, 1);
+    xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener,
+                         xwl_screen);
+}
+
+static void
 xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time)
 {
     struct xwl_screen *xwl_screen = data;
@@ -81,26 +92,59 @@ xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time)
     ErrorF("xwl_input_delayed_init\n");
 
     wl_callback_destroy(callback);
-    xwl_input_init(xwl_screen);
+
+    xwl_seat_bind(xwl_screen);
+    xwl_xserver_bind(xwl_screen);
 }
 
 static const struct wl_callback_listener delayed_init_listner = {
 	xwl_input_delayed_init
 };
 
+struct xwl_global *
+xwl_global_get(struct xwl_screen *xwl_screen, const char *interface)
+{
+    struct xwl_global *xwl_global = NULL;
+
+    xorg_list_for_each_entry(xwl_global,
+                             &xwl_screen->global_list, link) {
+        if (strcmp(xwl_global->interface, interface) == 0)
+            return xwl_global;
+    }
+
+    ErrorF("failed to find global object %s\n", interface);
+    return NULL;
+}
+
 static void
 registry_global(void *data, struct wl_registry *registry, uint32_t id,
 	        const char *interface, uint32_t version)
 {
     struct xwl_screen *xwl_screen = data;
+    struct xwl_global *xwl_global;
 
     if (strcmp (interface, "wl_compositor") == 0) {
 	xwl_screen->compositor =
             wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+	return;
     } else if (strcmp(interface, "wl_shm") == 0) {
         xwl_screen->shm =
             wl_registry_bind(registry, id, &wl_shm_interface, 1);
+	return;
     }
+
+    /* cache list of globals, so we can bind the interfaces later in a desired
+     * order */
+    xwl_global = calloc(sizeof *xwl_global, 1);
+    if (xwl_global == NULL) {
+	ErrorF("registry_global ENOMEM\n");
+	return ;
+    }
+    xwl_global->id = id;
+    xwl_global->interface = strdup(interface);
+    xwl_global->version = version;
+
+    xorg_list_add(&xwl_global->link, &xwl_screen->global_list);
 }
 
 static const struct wl_registry_listener registry_listener = {
@@ -233,6 +277,7 @@ xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
     xorg_list_init(&xwl_screen->seat_list);
     xorg_list_init(&xwl_screen->damage_window_list);
     xorg_list_init(&xwl_screen->window_list);
+    xorg_list_init(&xwl_screen->global_list);
     xwl_screen->scrninfo = scrninfo;
     xwl_screen->driver = driver;
     xwl_screen->flags = flags;
@@ -287,6 +332,7 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
 {
     struct xwl_seat *xwl_seat, *itmp;
     struct xwl_window *xwl_window, *wtmp;
+    struct xwl_global *xwl_global, *gtmp;
 
     if (xwl_screen->registry)
         wl_registry_destroy(xwl_screen->registry);
@@ -303,10 +349,16 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
 	wl_surface_destroy(xwl_window->surface);
 	free(xwl_window);
     }
+    xorg_list_for_each_entry_safe(xwl_global, gtmp,
+				  &xwl_screen->global_list, link) {
+	free(xwl_global->interface);
+	free(xwl_global);
+    }
 
     xorg_list_init(&xwl_screen->seat_list);
     xorg_list_init(&xwl_screen->damage_window_list);
     xorg_list_init(&xwl_screen->window_list);
+    xorg_list_init(&xwl_screen->global_list);
 
     wl_display_roundtrip(xwl_screen->display);
 }
-- 
1.7.9.5



More information about the wayland-devel mailing list