[PATCH xserver 1/4] xwayland: Cache globals to avoid multiple registry objects
Tiago Vignatti
tiago.vignatti at intel.com
Wed Dec 12 07:26:29 PST 2012
Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
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 39a487d..c78db36 100644
--- a/hw/xfree86/xwayland/xwayland-input.c
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -54,9 +54,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)
@@ -504,9 +501,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);
@@ -518,39 +516,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