xserver: Branch 'master' - 17 commits

Adam Jackson ajax at kemper.freedesktop.org
Thu Jun 21 14:56:55 UTC 2018


 hw/xwayland/xwayland-glamor-eglstream.c |  154 ++++++++++++++++++++++----
 hw/xwayland/xwayland-glamor-gbm.c       |   73 +++++++++---
 hw/xwayland/xwayland-glamor.c           |  183 +++++++++++++++-----------------
 hw/xwayland/xwayland-output.c           |    4 
 hw/xwayland/xwayland-present.c          |   10 -
 hw/xwayland/xwayland.c                  |   46 +++-----
 hw/xwayland/xwayland.h                  |  150 +++++++++++++-------------
 7 files changed, 374 insertions(+), 246 deletions(-)

New commits:
commit 92daeb31fa3235dc791e0444b072ec4bbc6e35ab
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Jun 11 09:21:08 2018 +0200

    xwayland: mandatory EGL backend API
    
    The API init_wl_registry() and has_wl_interfaces() are marked as being
    optional, but both GBM And EGLStream backends implement them so there is
    point in keeping those optional.
    
    Suggested-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 61418e707..f17914344 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -72,14 +72,12 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                             uint32_t version)
 {
     if (xwl_screen->gbm_backend.is_available &&
-        xwl_screen->gbm_backend.init_wl_registry &&
         xwl_screen->gbm_backend.init_wl_registry(xwl_screen,
                                                  registry,
                                                  id,
                                                  interface,
                                                  version)); /* no-op */
     else if (xwl_screen->eglstream_backend.is_available &&
-             xwl_screen->eglstream_backend.init_wl_registry &&
              xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
                                                             registry,
                                                             id,
@@ -91,11 +89,7 @@ Bool
 xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
                             struct xwl_egl_backend *xwl_egl_backend)
 {
-    if (xwl_egl_backend->has_wl_interfaces)
-        return xwl_egl_backend->has_wl_interfaces(xwl_screen);
-
-    /* If the backend has no requirement wrt WL interfaces, we're fine */
-    return TRUE;
+    return xwl_egl_backend->has_wl_interfaces(xwl_screen);
 }
 
 struct wl_buffer *
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index dc01c747c..d70ad54bf 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -64,16 +64,14 @@ struct xwl_egl_backend {
     Bool is_available;
 
     /* Called once for each interface in the global registry. Backends
-     * should use this to bind to any wayland interfaces they need. This
-     * callback is optional.
+     * should use this to bind to any wayland interfaces they need.
      */
     Bool (*init_wl_registry)(struct xwl_screen *xwl_screen,
                              struct wl_registry *wl_registry,
                              uint32_t id, const char *name,
                              uint32_t version);
 
-    /* Check that the required Wayland interfaces are available. This
-     * callback is optional.
+    /* Check that the required Wayland interfaces are available.
      */
     Bool (*has_wl_interfaces)(struct xwl_screen *xwl_screen);
 
commit 792359057bd54548555674d2d309c0cfeebac12d
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Jun 11 09:13:30 2018 +0200

    xwayland: simplify xwl_glamor_pixmap_get_wl_buffer()
    
    When retrieving the Wayland buffer from a pixmap, if the buffer already
    exists, the GBM backend will return that existing buffer.
    
    However, as seen with the Present issues, if the call had previously
    passed a wrong size, that buffer will remain at the wrong size for as
    long as the buffer exists, which is error prone.
    
    Considering that the width/height passed to get_wl_buffer() is always the
    actual pixmap  drawable size, and considering that the EGLStream backend
    makes no use of the size either, there is really no point in passing the
    width/height around.
    
    Simplify the xwl_glamor_pixmap_get_wl_buffer() and EGL backends API by
    removing the pixmap size, and use the drawable size instead.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 43f34eed1..9950be94d 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -308,8 +308,6 @@ xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap)
 
 static struct wl_buffer *
 xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap,
-                                              unsigned short width,
-                                              unsigned short height,
                                               Bool *created)
 {
     /* XXX created? */
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index bb29cc28e..42d758e93 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -230,13 +230,13 @@ xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap)
 
 static struct wl_buffer *
 xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap,
-                                        unsigned short width,
-                                        unsigned short height,
                                         Bool *created)
 {
     struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
     struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
     struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
+    unsigned short width = pixmap->drawable.width;
+    unsigned short height = pixmap->drawable.height;
     int prime_fd;
     int num_planes;
     uint32_t strides[4];
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 2f64d0500..61418e707 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -100,17 +100,13 @@ xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
 
 struct wl_buffer *
 xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,
-                                unsigned short width,
-                                unsigned short height,
                                 Bool *created)
 {
     struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
 
     if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap)
         return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap,
-                                                                width,
-                                                                height,
-                                                                created);
+                                                                 created);
 
     return NULL;
 }
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 29014a300..81e0eb9ce 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -456,10 +456,7 @@ xwl_present_flip(WindowPtr present_window,
 
     xwl_window->present_window = present_window;
 
-    buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap,
-                                             pixmap->drawable.width,
-                                             pixmap->drawable.height,
-                                             &buffer_created);
+    buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, &buffer_created);
 
     event->event_id = event_id;
     event->xwl_present_window = xwl_present_window;
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 7ea01ab86..96b4db18c 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -678,8 +678,6 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
 #ifdef XWL_HAS_GLAMOR
     if (xwl_screen->glamor)
         buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap,
-                                                 pixmap->drawable.width,
-                                                 pixmap->drawable.height,
                                                  NULL);
     else
 #endif
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 0fa5cb588..dc01c747c 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -96,8 +96,6 @@ struct xwl_egl_backend {
       * pixmap they've prepared beforehand.
       */
      struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap,
-                                                   unsigned short width,
-                                                   unsigned short height,
                                                    Bool *created);
 
      /* Called by Xwayland to perform any pre-wl_surface damage routines
@@ -439,8 +437,6 @@ Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
 Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
                                      uint32_t id, uint32_t version);
 struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,
-                                                  unsigned short width,
-                                                  unsigned short height,
                                                   Bool *created);
 void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                                  struct wl_registry *registry,
commit bdadaa25f5c1f62d30d8e76b4ebfcef414ed9c90
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:45 2018 +0200

    xwayland: EGL_IMG_context_priority required by EGLStream
    
    xwl_glamor_eglstream_init_egl() uses "EGL_IMG_context_priority"
    extension, make sure it's actually available before using it.
    
    Suggested-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index c226c0089..43f34eed1 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -794,6 +794,12 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
         goto error;
     }
 
+    if (!epoxy_has_egl_extension(xwl_screen->egl_display,
+                                 "EGL_IMG_context_priority")) {
+        ErrorF("EGL_IMG_context_priority not available\n");
+        goto error;
+    }
+
     eglChooseConfig(xwl_screen->egl_display, config_attribs, &config, 1, &n);
     if (!n) {
         ErrorF("No acceptable EGL configs found\n");
commit 5d843f6947538dabde258584a5795e0b25ea8779
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:44 2018 +0200

    xwayland: check for EGLStream backend explicitly
    
    Now that we have separate backends for EGLStream and GBM, we can
    explicitly check for the EGLStream backend to disable present support
    in that case.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 410f0f16e..29014a300 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -546,10 +546,9 @@ xwl_present_init(ScreenPtr screen)
     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
 
     /*
-     * doesn't work with the streams backend. we don't have an explicit
-     * boolean for that, but we do know gbm doesn't fill in this hook...
+     * doesn't work with the EGLStream backend.
      */
-    if (xwl_screen->egl_backend->post_damage != NULL)
+    if (xwl_screen->egl_backend == &xwl_screen->eglstream_backend)
         return FALSE;
 
     if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
commit d7185a84b60ed03aaa84eb522dcff365218e7211
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:43 2018 +0200

    xwayland: refactor EGL backends for wayland registry
    
    To be able to check for availability of the Wayland interfaces required
    to run a given EGL backend (either GBM or EGLStream for now), we need
    to have each backend structures and vfuncs in place before we enter the
    Wayland registry dance.
    
    That basically means that we should init all backends at first, connect
    to the Wayland compositor and query the available interfaces and then
    decide which backend is available and should be used (or none if either
    the Wayland interfaces or the EGL extensions are not available).
    
    For this purpose, hold an egl_backend struct for each backend we are to
    consider prior to connect to the Wayland display so that, when we get to
    query the Wayland interfaces, everything is in place for each backend to
    handle the various Wayland interfaces.
    
    Eventually, when we need to chose which EGL backend to use for glamor,
    the available Wayland interfaces and EGL extensions available are all
    known to Xwayland.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index bf74ae329..c226c0089 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -638,7 +638,7 @@ const struct wl_eglstream_display_listener eglstream_display_listener = {
     .swapinterval_override = xwl_eglstream_display_handle_swapinterval_override,
 };
 
-static void
+static Bool
 xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
                                       struct wl_registry *wl_registry,
                                       uint32_t id, const char *name,
@@ -654,10 +654,15 @@ xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
         wl_eglstream_display_add_listener(xwl_eglstream->display,
                                           &eglstream_display_listener,
                                           xwl_screen);
+        return TRUE;
     } else if (strcmp(name, "wl_eglstream_controller") == 0) {
         xwl_eglstream->controller = wl_registry_bind(
             wl_registry, id, &wl_eglstream_controller_interface, version);
+        return TRUE;
     }
+
+    /* no match */
+    return FALSE;
 }
 
 static Bool
@@ -882,23 +887,24 @@ out:
     return device;
 }
 
-Bool
+void
 xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
 {
     struct xwl_eglstream_private *xwl_eglstream;
     EGLDeviceEXT egl_device;
 
+    xwl_screen->eglstream_backend.is_available = FALSE;
     egl_device = xwl_eglstream_get_device(xwl_screen);
     if (egl_device == EGL_NO_DEVICE_EXT)
-        return FALSE;
+        return;
 
     if (!dixRegisterPrivateKey(&xwl_eglstream_private_key, PRIVATE_SCREEN, 0))
-        return FALSE;
+        return;
 
     xwl_eglstream = calloc(sizeof(*xwl_eglstream), 1);
     if (!xwl_eglstream) {
-        ErrorF("Failed to allocate memory required to init eglstream support\n");
-        return FALSE;
+        ErrorF("Failed to allocate memory required to init EGLStream support\n");
+        return;
     }
 
     dixSetPrivate(&xwl_screen->screen->devPrivates,
@@ -907,15 +913,12 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
     xwl_eglstream->egl_device = egl_device;
     xorg_list_init(&xwl_eglstream->pending_streams);
 
-    xwl_screen->egl_backend.init_egl = xwl_glamor_eglstream_init_egl;
-    xwl_screen->egl_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry;
-    xwl_screen->egl_backend.has_wl_interfaces = xwl_glamor_eglstream_has_wl_interfaces;
-    xwl_screen->egl_backend.init_screen = xwl_glamor_eglstream_init_screen;
-    xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap;
-    xwl_screen->egl_backend.post_damage = xwl_glamor_eglstream_post_damage;
-    xwl_screen->egl_backend.allow_commits = xwl_glamor_eglstream_allow_commits;
-
-    ErrorF("glamor: Using nvidia's eglstream interface, direct rendering impossible.\n");
-    ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n");
-    return TRUE;
+    xwl_screen->eglstream_backend.init_egl = xwl_glamor_eglstream_init_egl;
+    xwl_screen->eglstream_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry;
+    xwl_screen->eglstream_backend.has_wl_interfaces = xwl_glamor_eglstream_has_wl_interfaces;
+    xwl_screen->eglstream_backend.init_screen = xwl_glamor_eglstream_init_screen;
+    xwl_screen->eglstream_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap;
+    xwl_screen->eglstream_backend.post_damage = xwl_glamor_eglstream_post_damage;
+    xwl_screen->eglstream_backend.allow_commits = xwl_glamor_eglstream_allow_commits;
+    xwl_screen->eglstream_backend.is_available = TRUE;
 }
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 8a56801e6..bb29cc28e 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -734,16 +734,29 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
     return TRUE;
 }
 
-static void
+static Bool
 xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
                                 struct wl_registry *wl_registry,
                                 uint32_t id, const char *name,
                                 uint32_t version)
 {
-    if (strcmp(name, "wl_drm") == 0)
+    if (strcmp(name, "wl_drm") == 0) {
         xwl_screen_set_drm_interface(xwl_screen, id, version);
-    else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0)
+        return TRUE;
+    } else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) {
         xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
+        return TRUE;
+    }
+
+    /* no match */
+    return FALSE;
+}
+
+static Bool
+xwl_glamor_gbm_has_egl_extension(void)
+{
+    return (epoxy_has_egl_extension(NULL, "EGL_MESA_platform_gbm") ||
+            epoxy_has_egl_extension(NULL, "EGL_KHR_platform_gbm"));
 }
 
 static Bool
@@ -882,28 +895,32 @@ error:
     return FALSE;
 }
 
-Bool
+void
 xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
 {
     struct xwl_gbm_private *xwl_gbm;
 
+    xwl_screen->gbm_backend.is_available = FALSE;
+
+    if (!xwl_glamor_gbm_has_egl_extension())
+        return;
+
     if (!dixRegisterPrivateKey(&xwl_gbm_private_key, PRIVATE_SCREEN, 0))
-        return FALSE;
+        return;
 
     xwl_gbm = calloc(sizeof(*xwl_gbm), 1);
     if (!xwl_gbm) {
         ErrorF("glamor: Not enough memory to setup GBM, disabling\n");
-        return FALSE;
+        return;
     }
 
     dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key,
                   xwl_gbm);
 
-    xwl_screen->egl_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry;
-    xwl_screen->egl_backend.has_wl_interfaces = xwl_glamor_gbm_has_wl_interfaces;
-    xwl_screen->egl_backend.init_egl = xwl_glamor_gbm_init_egl;
-    xwl_screen->egl_backend.init_screen = xwl_glamor_gbm_init_screen;
-    xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
-
-    return TRUE;
+    xwl_screen->gbm_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry;
+    xwl_screen->gbm_backend.has_wl_interfaces = xwl_glamor_gbm_has_wl_interfaces;
+    xwl_screen->gbm_backend.init_egl = xwl_glamor_gbm_init_egl;
+    xwl_screen->gbm_backend.init_screen = xwl_glamor_gbm_init_screen;
+    xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
+    xwl_screen->gbm_backend.is_available = TRUE;
 }
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 3792dfa8c..2f64d0500 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -71,9 +71,20 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                             uint32_t id, const char *interface,
                             uint32_t version)
 {
-    if (xwl_screen->egl_backend.init_wl_registry)
-        xwl_screen->egl_backend.init_wl_registry(xwl_screen, registry,
-                                                 id, interface, version);
+    if (xwl_screen->gbm_backend.is_available &&
+        xwl_screen->gbm_backend.init_wl_registry &&
+        xwl_screen->gbm_backend.init_wl_registry(xwl_screen,
+                                                 registry,
+                                                 id,
+                                                 interface,
+                                                 version)); /* no-op */
+    else if (xwl_screen->eglstream_backend.is_available &&
+             xwl_screen->eglstream_backend.init_wl_registry &&
+             xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
+                                                            registry,
+                                                            id,
+                                                            interface,
+                                                            version)); /* no-op */
 }
 
 Bool
@@ -95,8 +106,8 @@ xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,
 {
     struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
 
-    if (xwl_screen->egl_backend.get_wl_buffer_for_pixmap)
-        return xwl_screen->egl_backend.get_wl_buffer_for_pixmap(pixmap,
+    if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap)
+        return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap,
                                                                 width,
                                                                 height,
                                                                 created);
@@ -110,8 +121,8 @@ xwl_glamor_post_damage(struct xwl_window *xwl_window,
 {
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
 
-    if (xwl_screen->egl_backend.post_damage)
-        xwl_screen->egl_backend.post_damage(xwl_window, pixmap, region);
+    if (xwl_screen->egl_backend->post_damage)
+        xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
 }
 
 Bool
@@ -119,8 +130,8 @@ xwl_glamor_allow_commits(struct xwl_window *xwl_window)
 {
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
 
-    if (xwl_screen->egl_backend.allow_commits)
-        return xwl_screen->egl_backend.allow_commits(xwl_window);
+    if (xwl_screen->egl_backend->allow_commits)
+        return xwl_screen->egl_backend->allow_commits(xwl_window);
     else
         return TRUE;
 }
@@ -165,17 +176,62 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
 void
 xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream)
 {
+#ifdef GLAMOR_HAS_GBM
+    xwl_glamor_init_gbm(xwl_screen);
+    if (!xwl_screen->gbm_backend.is_available && !use_eglstream)
+        ErrorF("xwayland glamor: GBM backend (default) is not available\n");
+#endif
 #ifdef XWL_HAS_EGLSTREAM
-    if (use_eglstream) {
-        if (!xwl_glamor_init_eglstream(xwl_screen)) {
-            ErrorF("xwayland glamor: failed to setup EGLStream backend\n");
-            use_eglstream = FALSE;
-        }
+    xwl_glamor_init_eglstream(xwl_screen);
+    if (!xwl_screen->eglstream_backend.is_available && use_eglstream)
+        ErrorF("xwayland glamor: EGLStream backend requested but not available\n");
+#endif
+}
+
+static Bool
+xwl_glamor_select_gbm_backend(struct xwl_screen *xwl_screen)
+{
+#ifdef GLAMOR_HAS_GBM
+    if (xwl_screen->gbm_backend.is_available &&
+        xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->gbm_backend)) {
+        xwl_screen->egl_backend = &xwl_screen->gbm_backend;
+        return TRUE;
     }
+    else
+        ErrorF("Missing Wayland requirements for glamor GBM backend\n");
 #endif
-    if (!use_eglstream && !xwl_glamor_init_gbm(xwl_screen)) {
-        ErrorF("xwayland glamor: failed to setup GBM backend, falling back to sw accel\n");
-        xwl_screen->glamor = 0;
+
+    return FALSE;
+}
+
+static Bool
+xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
+{
+#ifdef XWL_HAS_EGLSTREAM
+    if (xwl_screen->eglstream_backend.is_available &&
+        xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) {
+        ErrorF("glamor: Using nvidia's EGLStream interface, direct rendering impossible.\n");
+        ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n");
+        xwl_screen->egl_backend = &xwl_screen->eglstream_backend;
+        return TRUE;
+    }
+    else
+        ErrorF("Missing Wayland requirements for glamor EGLStream backend\n");
+#endif
+
+    return FALSE;
+}
+
+void
+xwl_glamor_select_backend(struct xwl_screen *xwl_screen, Bool use_eglstream)
+{
+    if (use_eglstream) {
+        if (!xwl_glamor_select_eglstream_backend(xwl_screen))
+            xwl_glamor_select_gbm_backend(xwl_screen);
+    }
+    else {
+        if (!xwl_glamor_select_gbm_backend(xwl_screen))
+            xwl_glamor_select_eglstream_backend(xwl_screen);
     }
 }
 
@@ -191,7 +247,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
         return FALSE;
     }
 
-    if (!xwl_screen->egl_backend.init_egl(xwl_screen)) {
+    if (!xwl_screen->egl_backend->init_egl(xwl_screen)) {
         ErrorF("EGL setup failed, disabling glamor\n");
         return FALSE;
     }
@@ -201,7 +257,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
         return FALSE;
     }
 
-    if (!xwl_screen->egl_backend.init_screen(xwl_screen)) {
+    if (!xwl_screen->egl_backend->init_screen(xwl_screen)) {
         ErrorF("EGL backend init_screen() failed, disabling glamor\n");
         return FALSE;
     }
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index c043da1d5..410f0f16e 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -549,7 +549,7 @@ xwl_present_init(ScreenPtr screen)
      * doesn't work with the streams backend. we don't have an explicit
      * boolean for that, but we do know gbm doesn't fill in this hook...
      */
-    if (xwl_screen->egl_backend.post_damage != NULL)
+    if (xwl_screen->egl_backend->post_damage != NULL)
         return FALSE;
 
     if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 8c02c02f8..7ea01ab86 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -737,7 +737,7 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
             continue;
 
 #ifdef XWL_HAS_GLAMOR
-        if (!xwl_glamor_allow_commits(xwl_window))
+        if (xwl_screen->glamor && !xwl_glamor_allow_commits(xwl_window))
             continue;
 #endif
 
@@ -1079,9 +1079,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
         return FALSE;
 
 #ifdef XWL_HAS_GLAMOR
-    if (xwl_screen->glamor && !xwl_glamor_init(xwl_screen)) {
-        ErrorF("Failed to initialize glamor, falling back to sw\n");
-        xwl_screen->glamor = 0;
+    if (xwl_screen->glamor) {
+        xwl_glamor_select_backend(xwl_screen, use_eglstreams);
+
+        if (xwl_screen->egl_backend == NULL || !xwl_glamor_init(xwl_screen)) {
+           ErrorF("Failed to initialize glamor, falling back to sw\n");
+           xwl_screen->glamor = 0;
+        }
     }
 
     if (xwl_screen->glamor && xwl_screen->rootless)
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 304484ccc..0fa5cb588 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -60,11 +60,14 @@ struct xwl_window;
 struct xwl_screen;
 
 struct xwl_egl_backend {
+    /* Set by the backend if available */
+    Bool is_available;
+
     /* Called once for each interface in the global registry. Backends
      * should use this to bind to any wayland interfaces they need. This
      * callback is optional.
      */
-    void (*init_wl_registry)(struct xwl_screen *xwl_screen,
+    Bool (*init_wl_registry)(struct xwl_screen *xwl_screen,
                              struct wl_registry *wl_registry,
                              uint32_t id, const char *name,
                              uint32_t version);
@@ -164,8 +167,10 @@ struct xwl_screen {
     struct xwl_format *formats;
     void *egl_display, *egl_context;
 
-    /* the current backend for creating pixmaps on wayland */
-    struct xwl_egl_backend egl_backend;
+    struct xwl_egl_backend gbm_backend;
+    struct xwl_egl_backend eglstream_backend;
+    /* pointer to the current backend for creating pixmaps on wayland */
+    struct xwl_egl_backend *egl_backend;
 
     struct glamor_context *glamor_ctx;
 
@@ -425,6 +430,8 @@ struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap);
 #ifdef XWL_HAS_GLAMOR
 void xwl_glamor_init_backends(struct xwl_screen *xwl_screen,
                               Bool use_eglstream);
+void xwl_glamor_select_backend(struct xwl_screen *xwl_screen,
+                               Bool use_eglstream);
 Bool xwl_glamor_init(struct xwl_screen *xwl_screen);
 
 Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
@@ -467,20 +474,18 @@ void xwlVidModeExtensionInit(void);
 #endif
 
 #ifdef GLAMOR_HAS_GBM
-Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen);
+void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen);
 #else
-static inline Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
+static inline void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
 {
-    return FALSE;
 }
 #endif
 
 #ifdef XWL_HAS_EGLSTREAM
-Bool xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen);
+void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen);
 #else
-static inline Bool xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
+static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
 {
-    return FALSE;
 }
 #endif
 
commit 48f037a27c45b571c9750ac812977ac0a33ab12b
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:42 2018 +0200

    xwayland: move EGL backend init to glamor
    
    Move EGL backends initialization to its own function in
    xwayland-glamor.c
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 72995de00..3792dfa8c 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -162,6 +162,23 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
     return 0;
 }
 
+void
+xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream)
+{
+#ifdef XWL_HAS_EGLSTREAM
+    if (use_eglstream) {
+        if (!xwl_glamor_init_eglstream(xwl_screen)) {
+            ErrorF("xwayland glamor: failed to setup EGLStream backend\n");
+            use_eglstream = FALSE;
+        }
+    }
+#endif
+    if (!use_eglstream && !xwl_glamor_init_gbm(xwl_screen)) {
+        ErrorF("xwayland glamor: failed to setup GBM backend, falling back to sw accel\n");
+        xwl_screen->glamor = 0;
+    }
+}
+
 Bool
 xwl_glamor_init(struct xwl_screen *xwl_screen)
 {
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 806d45675..8c02c02f8 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -992,20 +992,8 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     }
 
 #ifdef XWL_HAS_GLAMOR
-    if (xwl_screen->glamor) {
-#ifdef XWL_HAS_EGLSTREAM
-        if (use_eglstreams) {
-            if (!xwl_glamor_init_eglstream(xwl_screen)) {
-                ErrorF("xwayland glamor: failed to setup EGLStream backend\n");
-                use_eglstreams = FALSE;
-            }
-        }
-#endif
-        if (!use_eglstreams && !xwl_glamor_init_gbm(xwl_screen)) {
-            ErrorF("xwayland glamor: failed to setup GBM backend, falling back to sw accel\n");
-            xwl_screen->glamor = 0;
-        }
-    }
+    if (xwl_screen->glamor)
+        xwl_glamor_init_backends(xwl_screen, use_eglstreams);
 #endif
 
     /* In rootless mode, we don't have any screen storage, and the only
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 191f1b297..304484ccc 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -423,6 +423,8 @@ Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap);
 struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap);
 
 #ifdef XWL_HAS_GLAMOR
+void xwl_glamor_init_backends(struct xwl_screen *xwl_screen,
+                              Bool use_eglstream);
 Bool xwl_glamor_init(struct xwl_screen *xwl_screen);
 
 Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
commit f2fcb4877e976d078b0eb4755177170467341484
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:41 2018 +0200

    xwayland: Add Wayland interfaces check
    
    Introduces a new egl_backend function to let the EGL backend check for
    the presence of the required Wayland interfaces.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index f3fd97e6e..bf74ae329 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -660,6 +660,25 @@ xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
     }
 }
 
+static Bool
+xwl_glamor_eglstream_has_wl_interfaces(struct xwl_screen *xwl_screen)
+{
+    struct xwl_eglstream_private *xwl_eglstream =
+        xwl_eglstream_get(xwl_screen);
+
+    if (xwl_eglstream->display == NULL) {
+        ErrorF("glamor: 'wl_eglstream_display' not supported\n");
+        return FALSE;
+    }
+
+    if (xwl_eglstream->controller == NULL) {
+        ErrorF("glamor: 'wl_eglstream_controller' not supported\n");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 static inline void
 xwl_eglstream_init_shaders(struct xwl_screen *xwl_screen)
 {
@@ -819,14 +838,6 @@ xwl_glamor_eglstream_init_screen(struct xwl_screen *xwl_screen)
         xwl_eglstream_get(xwl_screen);
     ScreenPtr screen = xwl_screen->screen;
 
-    if (!xwl_eglstream->controller) {
-        ErrorF("No eglstream controller was exposed in the wayland registry. "
-               "This means your version of nvidia's EGL wayland libraries "
-               "are too old, as we require support for this.\n");
-        xwl_eglstream_cleanup(xwl_screen);
-        return FALSE;
-    }
-
     /* We can just let glamor handle CreatePixmap */
     screen->DestroyPixmap = xwl_glamor_eglstream_destroy_pixmap;
 
@@ -898,6 +909,7 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
 
     xwl_screen->egl_backend.init_egl = xwl_glamor_eglstream_init_egl;
     xwl_screen->egl_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry;
+    xwl_screen->egl_backend.has_wl_interfaces = xwl_glamor_eglstream_has_wl_interfaces;
     xwl_screen->egl_backend.init_screen = xwl_glamor_eglstream_init_screen;
     xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap;
     xwl_screen->egl_backend.post_damage = xwl_glamor_eglstream_post_damage;
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 4ac7d50f6..8a56801e6 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -747,6 +747,19 @@ xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
 }
 
 static Bool
+xwl_glamor_gbm_has_wl_interfaces(struct xwl_screen *xwl_screen)
+{
+    struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
+
+    if (xwl_gbm->drm == NULL) {
+        ErrorF("glamor: 'wl_drm' not supported\n");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static Bool
 xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
 {
     struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
@@ -887,6 +900,7 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
                   xwl_gbm);
 
     xwl_screen->egl_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry;
+    xwl_screen->egl_backend.has_wl_interfaces = xwl_glamor_gbm_has_wl_interfaces;
     xwl_screen->egl_backend.init_egl = xwl_glamor_gbm_init_egl;
     xwl_screen->egl_backend.init_screen = xwl_glamor_gbm_init_screen;
     xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 14706f6e8..72995de00 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -76,6 +76,17 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                                                  id, interface, version);
 }
 
+Bool
+xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
+                            struct xwl_egl_backend *xwl_egl_backend)
+{
+    if (xwl_egl_backend->has_wl_interfaces)
+        return xwl_egl_backend->has_wl_interfaces(xwl_screen);
+
+    /* If the backend has no requirement wrt WL interfaces, we're fine */
+    return TRUE;
+}
+
 struct wl_buffer *
 xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,
                                 unsigned short width,
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 6bbe72e46..191f1b297 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -69,6 +69,11 @@ struct xwl_egl_backend {
                              uint32_t id, const char *name,
                              uint32_t version);
 
+    /* Check that the required Wayland interfaces are available. This
+     * callback is optional.
+     */
+    Bool (*has_wl_interfaces)(struct xwl_screen *xwl_screen);
+
     /* Called before glamor has been initialized. Backends should setup a
      * valid, glamor compatible EGL context in this hook.
      */
@@ -432,6 +437,8 @@ void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                                  struct wl_registry *registry,
                                  uint32_t id, const char *interface,
                                  uint32_t version);
+Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
+                                 struct xwl_egl_backend *xwl_egl_backend);
 void xwl_glamor_post_damage(struct xwl_window *xwl_window,
                             PixmapPtr pixmap, RegionPtr region);
 Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
commit b74b0f18b8d3032317e38453ee63ae9efd33a098
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:40 2018 +0200

    xwayland: move egl_backend to its own struct
    
    EGL backend availability requires both EGL extensions and Wayland
    interfaces to be present, so we will need to consider multiple backends
    during initialization.
    
    As a preliminary work, move the egl_backend to its own struct so that we
    can have more than one backend at any given time.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index a32fcf6a5..6bbe72e46 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -57,6 +57,56 @@ struct xwl_format {
 
 struct xwl_pixmap;
 struct xwl_window;
+struct xwl_screen;
+
+struct xwl_egl_backend {
+    /* Called once for each interface in the global registry. Backends
+     * should use this to bind to any wayland interfaces they need. This
+     * callback is optional.
+     */
+    void (*init_wl_registry)(struct xwl_screen *xwl_screen,
+                             struct wl_registry *wl_registry,
+                             uint32_t id, const char *name,
+                             uint32_t version);
+
+    /* Called before glamor has been initialized. Backends should setup a
+     * valid, glamor compatible EGL context in this hook.
+     */
+    Bool (*init_egl)(struct xwl_screen *xwl_screen);
+
+    /* Called after glamor has been initialized, and after all of the
+     * common Xwayland DDX hooks have been connected. Backends should use
+     * this to setup any required wraps around X server callbacks like
+     * CreatePixmap.
+     */
+     Bool (*init_screen)(struct xwl_screen *xwl_screen);
+
+     /* Called by Xwayland to retrieve a pointer to a valid wl_buffer for
+      * the given window/pixmap combo so that damage to the pixmap may be
+      * displayed on-screen. Backends should use this to create a new
+      * wl_buffer for a currently buffer-less pixmap, or simply return the
+      * pixmap they've prepared beforehand.
+      */
+     struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap,
+                                                   unsigned short width,
+                                                   unsigned short height,
+                                                   Bool *created);
+
+     /* Called by Xwayland to perform any pre-wl_surface damage routines
+      * that are required by the backend. If your backend is poorly
+      * designed and lacks the ability to render directly to a surface,
+      * you should implement blitting from the glamor pixmap to the wayland
+      * pixmap here. Otherwise, this callback is optional.
+      */
+     void (*post_damage)(struct xwl_window *xwl_window,
+                         PixmapPtr pixmap, RegionPtr region);
+
+     /* Called by Xwayland to confirm with the egl backend that the given
+      * pixmap is completely setup and ready for display on-screen. This
+      * callback is optional.
+      */
+     Bool (*allow_commits)(struct xwl_window *xwl_window);
+};
 
 struct xwl_screen {
     int width;
@@ -110,54 +160,7 @@ struct xwl_screen {
     void *egl_display, *egl_context;
 
     /* the current backend for creating pixmaps on wayland */
-    struct {
-        /* Called once for each interface in the global registry. Backends
-         * should use this to bind to any wayland interfaces they need. This
-         * callback is optional.
-         */
-        void (*init_wl_registry)(struct xwl_screen *xwl_screen,
-                                 struct wl_registry *wl_registry,
-                                 uint32_t id, const char *name,
-                                 uint32_t version);
-
-        /* Called before glamor has been initialized. Backends should setup a
-         * valid, glamor compatible EGL context in this hook.
-         */
-        Bool (*init_egl)(struct xwl_screen *xwl_screen);
-
-        /* Called after glamor has been initialized, and after all of the
-         * common Xwayland DDX hooks have been connected. Backends should use
-         * this to setup any required wraps around X server callbacks like
-         * CreatePixmap.
-         */
-        Bool (*init_screen)(struct xwl_screen *xwl_screen);
-
-        /* Called by Xwayland to retrieve a pointer to a valid wl_buffer for
-         * the given window/pixmap combo so that damage to the pixmap may be
-         * displayed on-screen. Backends should use this to create a new
-         * wl_buffer for a currently buffer-less pixmap, or simply return the
-         * pixmap they've prepared beforehand.
-         */
-        struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap,
-                                                      unsigned short width,
-                                                      unsigned short height,
-                                                      Bool *created);
-
-        /* Called by Xwayland to perform any pre-wl_surface damage routines
-         * that are required by the backend. If your backend is poorly
-         * designed and lacks the ability to render directly to a surface,
-         * you should implement blitting from the glamor pixmap to the wayland
-         * pixmap here. Otherwise, this callback is optional.
-         */
-        void (*post_damage)(struct xwl_window *xwl_window,
-                            PixmapPtr pixmap, RegionPtr region);
-
-        /* Called by Xwayland to confirm with the egl backend that the given
-         * pixmap is completely setup and ready for display on-screen. This
-         * callback is optional.
-         */
-        Bool (*allow_commits)(struct xwl_window *xwl_window);
-    } egl_backend;
+    struct xwl_egl_backend egl_backend;
 
     struct glamor_context *glamor_ctx;
 
commit de004eefc60ec595f5d6d81658468e082f8df930
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:39 2018 +0200

    xwayland: skip drm authentication with render node
    
    If using a render node, we can skip DRM authentication.
    
    Suggested-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 939a3c030..4ac7d50f6 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -837,11 +837,16 @@ error:
 static Bool
 xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen)
 {
+    struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
+
     if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
         ErrorF("Failed to initialize dri3\n");
         goto error;
     }
 
+    if (xwl_gbm->fd_render_node)
+        goto skip_drm_auth;
+
     if (!dixRegisterPrivateKey(&xwl_auth_state_private_key, PRIVATE_CLIENT,
                                0)) {
         ErrorF("Failed to register private key\n");
@@ -854,6 +859,7 @@ xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen)
         goto error;
     }
 
+skip_drm_auth:
     xwl_screen->screen->CreatePixmap = xwl_glamor_gbm_create_pixmap;
     xwl_screen->screen->DestroyPixmap = xwl_glamor_gbm_destroy_pixmap;
 
commit b823b43dca143810146f563d09e8996058b9d09e
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:38 2018 +0200

    xwayland: GBM should fail w/out "GL_OES_EGL_image"
    
    Surely, we should fail to init GBM backend if "GL_OES_EGL_image" is
    missing.
    
    This seems to have been lost with commit 1545e2dba ("xwayland: Decouple
    GBM from glamor").
    
    Suggested-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index f6e5706ce..939a3c030 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -807,8 +807,10 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
         goto error;
     }
 
-    if (!epoxy_has_gl_extension("GL_OES_EGL_image"))
+    if (!epoxy_has_gl_extension("GL_OES_EGL_image")) {
         ErrorF("GL_OES_EGL_image not available\n");
+        goto error;
+    }
 
     if (epoxy_has_egl_extension(xwl_screen->egl_display,
                                 "EXT_image_dma_buf_import") &&
commit 78ce4aa979ff3f5870fbc12a7e5c53547084a61a
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:37 2018 +0200

    xwayland: swap "name" and "id" in init_wl_registry()
    
    Both xwl_glamor_init_wl_registry() and the Wayland global registry
    handler use the interface id/name in that order, using name/id in the
    egl_backend vfunc makes things confusing and error prone.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 89c531f4a..f3fd97e6e 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -641,8 +641,8 @@ const struct wl_eglstream_display_listener eglstream_display_listener = {
 static void
 xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
                                       struct wl_registry *wl_registry,
-                                      const char *name,
-                                      uint32_t id, uint32_t version)
+                                      uint32_t id, const char *name,
+                                      uint32_t version)
 {
     struct xwl_eglstream_private *xwl_eglstream =
         xwl_eglstream_get(xwl_screen);
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 68c2cc32e..f6e5706ce 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -737,8 +737,8 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
 static void
 xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
                                 struct wl_registry *wl_registry,
-                                const char *name,
-                                uint32_t id, uint32_t version)
+                                uint32_t id, const char *name,
+                                uint32_t version)
 {
     if (strcmp(name, "wl_drm") == 0)
         xwl_screen_set_drm_interface(xwl_screen, id, version);
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index c7ae51336..14706f6e8 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -73,7 +73,7 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
 {
     if (xwl_screen->egl_backend.init_wl_registry)
         xwl_screen->egl_backend.init_wl_registry(xwl_screen, registry,
-                                                 interface, id, version);
+                                                 id, interface, version);
 }
 
 struct wl_buffer *
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 0d4afdf8a..a32fcf6a5 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -117,7 +117,7 @@ struct xwl_screen {
          */
         void (*init_wl_registry)(struct xwl_screen *xwl_screen,
                                  struct wl_registry *wl_registry,
-                                 const char *name, uint32_t id,
+                                 uint32_t id, const char *name,
                                  uint32_t version);
 
         /* Called before glamor has been initialized. Backends should setup a
commit f6b2109c1b49484af772df518314ec8e8432febe
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:38:36 2018 +0200

    xwayland: move glamor specific routines
    
    Functions such as:
    
      xwl_glamor_egl_supports_device_probing()
      xwl_glamor_egl_get_devices()
      xwl_glamor_egl_device_has_egl_extensions()
    
    Are of no use outside of EGLStream support, move them to the relevant
    source file.
    
    Similarly, the other glamor functions such as:
    
      xwl_glamor_init()
      xwl_screen_set_drm_interface()
      xwl_screen_set_dmabuf_interface()
      xwl_glamor_pixmap_get_wl_buffer()
      xwl_glamor_init_wl_registry()
      xwl_glamor_post_damage()
      xwl_glamor_allow_commits()
      xwl_glamor_egl_make_current()
    
    Are useless without glamor support enabled, move those within a
    a "#ifdef XWL_HAS_GLAMOR" in xwayland.h
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 8dd1cc304..89c531f4a 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -187,6 +187,85 @@ xwl_eglstream_cleanup(struct xwl_screen *xwl_screen)
     free(xwl_eglstream);
 }
 
+static Bool
+xwl_glamor_egl_supports_device_probing(void)
+{
+    return epoxy_has_egl_extension(NULL, "EGL_EXT_device_base");
+}
+
+static void **
+xwl_glamor_egl_get_devices(int *num_devices)
+{
+    EGLDeviceEXT *devices;
+    Bool ret;
+    int drm_dev_count = 0;
+    int i;
+
+    if (!xwl_glamor_egl_supports_device_probing())
+        return NULL;
+
+    /* Get the number of devices */
+    ret = eglQueryDevicesEXT(0, NULL, num_devices);
+    if (!ret || *num_devices < 1)
+        return NULL;
+
+    devices = calloc(*num_devices, sizeof(EGLDeviceEXT));
+    if (!devices)
+        return NULL;
+
+    ret = eglQueryDevicesEXT(*num_devices, devices, num_devices);
+    if (!ret)
+        goto error;
+
+    /* We're only ever going to care about devices that support
+     * EGL_EXT_device_drm, so filter out the ones that don't
+     */
+    for (i = 0; i < *num_devices; i++) {
+        const char *extension_str =
+            eglQueryDeviceStringEXT(devices[i], EGL_EXTENSIONS);
+
+        if (!epoxy_extension_in_string(extension_str, "EGL_EXT_device_drm"))
+            continue;
+
+        devices[drm_dev_count++] = devices[i];
+    }
+    if (!drm_dev_count)
+        goto error;
+
+    *num_devices = drm_dev_count;
+    devices = realloc(devices, sizeof(EGLDeviceEXT) * drm_dev_count);
+
+    return devices;
+
+error:
+    free(devices);
+
+    return NULL;
+}
+
+static Bool
+xwl_glamor_egl_device_has_egl_extensions(void *device,
+                                         const char **ext_list, size_t size)
+{
+    EGLDisplay egl_display;
+    int i;
+    Bool has_exts = TRUE;
+
+    egl_display = glamor_egl_get_display(EGL_PLATFORM_DEVICE_EXT, device);
+    if (!egl_display || !eglInitialize(egl_display, NULL, NULL))
+        return FALSE;
+
+    for (i = 0; i < size; i++) {
+        if (!epoxy_has_egl_extension(egl_display, ext_list[i])) {
+            has_exts = FALSE;
+            break;
+        }
+    }
+
+    eglTerminate(egl_display);
+    return has_exts;
+}
+
 static void
 xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
 {
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index f543f321d..c7ae51336 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -52,86 +52,6 @@ xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen)
     xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx);
 }
 
-Bool
-xwl_glamor_egl_supports_device_probing(void)
-{
-    return epoxy_has_egl_extension(NULL, "EGL_EXT_device_base");
-}
-
-void **
-xwl_glamor_egl_get_devices(int *num_devices)
-{
-#ifdef XWL_HAS_EGLSTREAM
-    EGLDeviceEXT *devices;
-    Bool ret;
-    int drm_dev_count = 0;
-    int i;
-
-    if (!xwl_glamor_egl_supports_device_probing())
-        return NULL;
-
-    /* Get the number of devices */
-    ret = eglQueryDevicesEXT(0, NULL, num_devices);
-    if (!ret || *num_devices < 1)
-        return NULL;
-
-    devices = calloc(*num_devices, sizeof(EGLDeviceEXT));
-    if (!devices)
-        return NULL;
-
-    ret = eglQueryDevicesEXT(*num_devices, devices, num_devices);
-    if (!ret)
-        goto error;
-
-    /* We're only ever going to care about devices that support
-     * EGL_EXT_device_drm, so filter out the ones that don't
-     */
-    for (i = 0; i < *num_devices; i++) {
-        const char *extension_str =
-            eglQueryDeviceStringEXT(devices[i], EGL_EXTENSIONS);
-
-        if (!epoxy_extension_in_string(extension_str, "EGL_EXT_device_drm"))
-            continue;
-
-        devices[drm_dev_count++] = devices[i];
-    }
-    if (!drm_dev_count)
-        goto error;
-
-    *num_devices = drm_dev_count;
-    devices = realloc(devices, sizeof(EGLDeviceEXT) * drm_dev_count);
-
-    return devices;
-
-error:
-    free(devices);
-#endif
-    return NULL;
-}
-
-Bool
-xwl_glamor_egl_device_has_egl_extensions(void *device,
-                                         const char **ext_list, size_t size)
-{
-    EGLDisplay egl_display;
-    int i;
-    Bool has_exts = TRUE;
-
-    egl_display = glamor_egl_get_display(EGL_PLATFORM_DEVICE_EXT, device);
-    if (!egl_display || !eglInitialize(egl_display, NULL, NULL))
-        return FALSE;
-
-    for (i = 0; i < size; i++) {
-        if (!epoxy_has_egl_extension(egl_display, ext_list[i])) {
-            has_exts = FALSE;
-            break;
-        }
-    }
-
-    eglTerminate(egl_display);
-    return has_exts;
-}
-
 void
 glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 {
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 39bc20a7e..0d4afdf8a 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -414,7 +414,7 @@ PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height,
 Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap);
 struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap);
 
-
+#ifdef XWL_HAS_GLAMOR
 Bool xwl_glamor_init(struct xwl_screen *xwl_screen);
 
 Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
@@ -432,27 +432,23 @@ void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
 void xwl_glamor_post_damage(struct xwl_window *xwl_window,
                             PixmapPtr pixmap, RegionPtr region);
 Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
+void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
 
 #ifdef GLAMOR_HAS_GBM
 Bool xwl_present_init(ScreenPtr screen);
 void xwl_present_cleanup(WindowPtr window);
-#endif
-
-void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
-
-void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
-
-void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
-Bool xwl_glamor_egl_supports_device_probing(void);
-void **xwl_glamor_egl_get_devices(int *num_devices);
-Bool xwl_glamor_egl_device_has_egl_extensions(void *device,
-                                              const char **ext_list,
-                                              size_t size);
+#endif /* GLAMOR_HAS_GBM */
 
 #ifdef XV
 /* glamor Xv Adaptor */
 Bool xwl_glamor_xv_init(ScreenPtr pScreen);
-#endif
+#endif /* XV */
+
+#endif /* XWL_HAS_GLAMOR */
+
+void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
+
+void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
 
 #ifdef XF86VIDMODE
 void xwlVidModeExtensionInit(void);
commit d31a7be15e259275599a9f67e0d921471ae64913
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:37:58 2018 +0200

    xwayland: make xwl_output_get_xdg_output() static
    
    Make xwl_output_get_xdg_output() private, it doesn't need to be
    available elsewhere.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Lyude Paul <lyude at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 48faeb142..379062549 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -38,6 +38,8 @@
                        RR_Reflect_X  | \
                        RR_Reflect_Y)
 
+static void xwl_output_get_xdg_output(struct xwl_output *xwl_output);
+
 static Rotation
 wl_transform_to_xrandr(enum wl_output_transform transform)
 {
@@ -435,7 +437,7 @@ xwl_screen_init_output(struct xwl_screen *xwl_screen)
     return TRUE;
 }
 
-void
+static void
 xwl_output_get_xdg_output(struct xwl_output *xwl_output)
 {
     struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 25112e2cb..39bc20a7e 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -440,7 +440,6 @@ void xwl_present_cleanup(WindowPtr window);
 
 void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
 
-void xwl_output_get_xdg_output(struct xwl_output *xwl_output);
 void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
 
 void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
commit e16a6da79dea793a335be70ba07d5e1c1295b5eb
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:37:57 2018 +0200

    xwayland: do not disable glamor if EGLStream failed
    
    EGLStream requires glamor, but the opposite is not true. So if someone
    passes "-eglstream" with a GPU which does not support EGLStream, we
    could maybe still try GBM and be lucky.
    
    That allows Wayland compositors to pass "-eglstream" regardless of the
    actual hardware, if they want to enable EGLStream on GPU which support
    it.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Lyude Paul <lyude at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 9121ef666..806d45675 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -939,9 +939,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     struct xwl_screen *xwl_screen;
     Pixel red_mask, blue_mask, green_mask;
     int ret, bpc, green_bpc, i;
-#ifdef XWL_HAS_EGLSTREAM
     Bool use_eglstreams = FALSE;
-#endif
 
     xwl_screen = calloc(1, sizeof *xwl_screen);
     if (xwl_screen == NULL)
@@ -998,12 +996,12 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
 #ifdef XWL_HAS_EGLSTREAM
         if (use_eglstreams) {
             if (!xwl_glamor_init_eglstream(xwl_screen)) {
-                ErrorF("xwayland glamor: failed to setup eglstream backend, falling back to swaccel\n");
-                xwl_screen->glamor = 0;
+                ErrorF("xwayland glamor: failed to setup EGLStream backend\n");
+                use_eglstreams = FALSE;
             }
-        } else
+        }
 #endif
-        if (!xwl_glamor_init_gbm(xwl_screen)) {
+        if (!use_eglstreams && !xwl_glamor_init_gbm(xwl_screen)) {
             ErrorF("xwayland glamor: failed to setup GBM backend, falling back to sw accel\n");
             xwl_screen->glamor = 0;
         }
commit 44560af02823239e1b5b236e8cb365b5bdf24b6a
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:37:56 2018 +0200

    xwayland: process Wayland events after adding screen
    
    When we're done adding a new screen, we need to process any pending
    Wayland events again.
    
    Hence we don't end up processing xdg_output events unexpectedly when
    glamor is disabled. Be that because "-shm" was passed or "-eglstream"
    has failed.
    
    Failing to do that could lead to a crash at startup:
    
        Xwayland: dixGetPrivateAddr: Assertion `key->initialized' failed.
        (EE)
        (EE) Backtrace:
        (EE) 0: Xwayland (OsSigHandler)
        (EE) 1: libpthread.so.0 (funlockfile)
        (EE) 2: libc.so.6 (gsignal)
        (EE) 3: libc.so.6 (abort)
        (EE) 4: libc.so.6 (?+0x0)
        (EE) 5: libc.so.6 (__assert_fail)
        (EE) 6: Xwayland (dixGetPrivateAddr)
        (EE) 7: Xwayland (_fbGetWindowPixmap)
        (EE) 8: Xwayland (getDrawableDamageRef)
        (EE) 9: Xwayland (damageRegionProcessPending)
        (EE) 10: Xwayland (damagePolyFillRect)
        (EE) 11: Xwayland (miPaintWindow)
        (EE) 12: Xwayland (miWindowExposures)
        (EE) 13: Xwayland (miHandleValidateExposures)
        (EE) 14: Xwayland (SetRootClip)
        (EE) 15: Xwayland (update_screen_size)
        (EE) 16: Xwayland (apply_output_change)
        (EE) 17: libffi.so.6 (ffi_call_unix64)
        (EE) 18: libffi.so.6 (ffi_call)
        (EE) 19: libwayland-client.so.0 (wl_log_set_handler_client)
        (EE) 20: libwayland-client.so.0 (_init)
        (EE) 21: libwayland-client.so.0 (wl_display_dispatch_queue_pending)
        (EE) 22: libwayland-client.so.0 (wl_display_roundtrip_queue)
        (EE) 23: Xwayland (InitInput)
        (EE) 24: Xwayland (dix_main)
        (EE) 25: libc.so.6 (__libc_start_main)
        (EE) 26: Xwayland (_start)
        (EE)
        (EE)
        Fatal server error:
        (EE) Caught signal 6 (Aborted). Server aborting
        (EE)
        Aborted (core dumped)
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Lyude Paul <lyude at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index d9548a874..9121ef666 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -1132,6 +1132,10 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
 
     AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
 
+    wl_display_roundtrip(xwl_screen->display);
+    while (xwl_screen->expecting_event)
+        wl_display_roundtrip(xwl_screen->display);
+
     return ret;
 }
 
commit dbde3fec32641ae23389cffa12a04d3608936795
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:37:55 2018 +0200

    xwayland: "EGL_EXT_device_base" required for EGLStream
    
    eglQueryDevicesEXT() would abort if the required extensions are not
    available, meaning that enabling “-eglstream” on a non-EGLStream
    capable hardware would lead to an abort().
    
    Check that "EGL_EXT_device_base" extension is available and bail out
    early if not, so we don't abort() later in eglQueryDevicesEXT().
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Lyude Paul <lyude at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index cdca072ed..f543f321d 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -67,6 +67,9 @@ xwl_glamor_egl_get_devices(int *num_devices)
     int drm_dev_count = 0;
     int i;
 
+    if (!xwl_glamor_egl_supports_device_probing())
+        return NULL;
+
     /* Get the number of devices */
     ret = eglQueryDevicesEXT(0, NULL, num_devices);
     if (!ret || *num_devices < 1)
commit 06c31e782e360363238cf20e7afd3e4990a2c304
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 5 19:37:54 2018 +0200

    xwayland: allow "-eglstream" option
    
    The command line option "-eglstream" used to enable EGLStream support
    for NVidia GPU was made available only when Xwayland was built with
    EGLStream support enabled.
    
    Wayland compositors who spawn Xwayland have no easy way to tell whether
    or not Xwayland was built with EGLStream support enabled, and adding
    "-eglstream" command line option to Xwayland when it wasn't built with
    EGLStream support would prevent Xwayland from starting (“Unrecognized
    option” error).
    
    Make sure we support the command line option "-eglstream" regardless of
    EGLStream support in Xwayland. Obviously, if Xwayland was built without
    EGLStream support, this has no effect.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Lyude Paul <lyude at redhat.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 1d6b49979..d9548a874 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -96,9 +96,7 @@ ddxUseMsg(void)
     ErrorF("-rootless              run rootless, requires wm support\n");
     ErrorF("-wm fd                 create X client for wm on given fd\n");
     ErrorF("-listen fd             add give fd as a listen socket\n");
-#ifdef XWL_HAS_EGLSTREAM
     ErrorF("-eglstream             use eglstream backend for nvidia GPUs\n");
-#endif
 }
 
 int
@@ -117,11 +115,9 @@ ddxProcessArgument(int argc, char *argv[], int i)
     else if (strcmp(argv[i], "-shm") == 0) {
         return 1;
     }
-#ifdef XWL_HAS_EGLSTREAM
     else if (strcmp(argv[i], "-eglstream") == 0) {
         return 1;
     }
-#endif
 
     return 0;
 }
@@ -988,11 +984,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
         else if (strcmp(argv[i], "-shm") == 0) {
             xwl_screen->glamor = 0;
         }
-#ifdef XWL_HAS_EGLSTREAM
         else if (strcmp(argv[i], "-eglstream") == 0) {
+#ifdef XWL_HAS_EGLSTREAM
             use_eglstreams = TRUE;
-        }
+#else
+            ErrorF("xwayland glamor: this build does not have EGLStream support\n");
 #endif
+        }
     }
 
 #ifdef XWL_HAS_GLAMOR


More information about the xorg-commit mailing list