[PATCH v3 xserver 2/2] xwayland: Cache globals to avoid multiple registry objects
Ander Conselvan de Oliveira
conselvan2 at gmail.com
Fri Nov 23 01:09:35 PST 2012
On 11/22/2012 10:08 PM, Tiago Vignatti wrote:
> 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.
[...]
> 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");
In the case of multiple outputs, the global handler would be called
multiple times, but now xwl_global_get() will only return the first
output. So with this change you only ever create one output.
From a quick glance at the code, however, it doesn't look like it
handled multiple outputs properly before.
Cheers,
Ander
> 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);
> }
>
More information about the wayland-devel
mailing list