summaryrefslogtreecommitdiff
path: root/hw/xwayland/xwayland-glamor.c
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2018-06-05 19:38:43 +0200
committerAdam Jackson <ajax@redhat.com>2018-06-21 10:54:10 -0400
commitd7185a84b60ed03aaa84eb522dcff365218e7211 (patch)
tree27ea39486b18cda1fbbc978e1a0cce80b5752677 /hw/xwayland/xwayland-glamor.c
parent48f037a27c45b571c9750ac812977ac0a33ab12b (diff)
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@redhat.com> Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Diffstat (limited to 'hw/xwayland/xwayland-glamor.c')
-rw-r--r--hw/xwayland/xwayland-glamor.c94
1 files changed, 75 insertions, 19 deletions
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;
}