diff --git a/configure.ac b/configure.ac index 9adb14b5b..2aa9c4352 100644 --- a/configure.ac +++ b/configure.ac @@ -290,13 +290,24 @@ AS_IF([test "$have_native_backend" = "yes"], [ ]) AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test "$have_native_backend" = "yes"]) +MUTTER_WAYLAND_EGLSTREAM_MODULES="wayland-eglstream-protocols" + AC_ARG_ENABLE(egl-device, AS_HELP_STRING([--enable-egl-device], [enable support for EGLDevice on top of KMS]),, enable_egl_device=no + have_wayland_eglstream=no ) AS_IF([test "$enable_egl_device" = "yes"], [ AC_DEFINE([HAVE_EGL_DEVICE],[1], [Defined if EGLDevice support is enabled]) + PKG_CHECK_EXISTS([$MUTTER_WAYLAND_EGLSTREAM_MODULES], [have_wayland_eglstream=yes], [have_wayland_eglstream=no]) ]) +AS_IF([test "$have_wayland_eglstream" = "yes"], [ + AC_DEFINE([HAVE_WAYLAND_EGLSTREAM],[1],[Defined if Wayland EGLStream protocols are available]) + PKG_CHECK_MODULES(WAYLAND_EGLSTREAM, [$MUTTER_WAYLAND_EGLSTREAM_MODULES], + [ac_wayland_eglstream_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir $MUTTER_WAYLAND_EGLSTREAM_MODULES`]) + AC_SUBST(WAYLAND_EGLSTREAM_DATADIR, $ac_wayland_eglstream_pkgdatadir) +]) +AM_CONDITIONAL([HAVE_WAYLAND_EGLSTREAM],[test "$have_wayland_eglstream" = "yes"]) MUTTER_WAYLAND_MODULES="wayland-server >= 1.13.0" @@ -549,6 +560,7 @@ mutter-$VERSION Introspection: ${found_introspection} Session management: ${found_sm} Wayland: ${have_wayland} + Wayland EGLStream: ${have_wayland_eglstream} Native (KMS) backend: ${have_native_backend} EGLDevice: ${enable_egl_device} Remote desktop: ${enable_remote_desktop} diff --git a/src/Makefile.am b/src/Makefile.am index aaf7c9c80..bd879f203 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -91,6 +91,12 @@ mutter_built_sources += \ gtk-text-input-protocol.c \ gtk-text-input-server-protocol.h \ $(NULL) + +if HAVE_WAYLAND_EGLSTREAM +mutter_built_sources += \ + wayland-eglstream-controller-server-protocol.h \ + $(NULL) +endif endif wayland_protocols = \ @@ -770,3 +776,5 @@ endef $(AM_V_GEN)$(WAYLAND_SCANNER) code $< $@ %-server-protocol.h : $(srcdir)/wayland/protocol/%.xml $(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@ +%-server-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/%.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@ diff --git a/src/wayland/meta-wayland-egl-stream.c b/src/wayland/meta-wayland-egl-stream.c index 39ff93433..0d7ce2304 100644 --- a/src/wayland/meta-wayland-egl-stream.c +++ b/src/wayland/meta-wayland-egl-stream.c @@ -32,6 +32,104 @@ #include "backends/meta-egl-ext.h" #include "meta/meta-backend.h" #include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-private.h" + +#ifdef HAVE_WAYLAND_EGLSTREAM + +#include "wayland-eglstream-controller-server-protocol.h" +#include + +static struct wl_interface *wl_eglstream_controller_interface_ptr = NULL; + +static void +attach_eglstream_consumer (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *wl_surface, + struct wl_resource *wl_eglstream) +{ + MetaWaylandBuffer *buffer = meta_wayland_buffer_from_resource (wl_eglstream); + + if (!meta_wayland_buffer_is_realized (buffer)) + meta_wayland_buffer_realize (buffer); +} + +static const struct wl_eglstream_controller_interface +meta_eglstream_controller_interface = { + attach_eglstream_consumer +}; + +static void +bind_eglstream_controller (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + g_assert (wl_eglstream_controller_interface_ptr != NULL); + + resource = wl_resource_create (client, + wl_eglstream_controller_interface_ptr, + version, + id); + + if (resource == NULL) + { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation (resource, + &meta_eglstream_controller_interface, + data, + NULL); +} + +#endif /* HAVE_WAYLAND_EGLSTREAM */ + +gboolean +meta_wayland_eglstream_controller_init (MetaWaylandCompositor *compositor) +{ +#ifdef HAVE_WAYLAND_EGLSTREAM + /* + * wl_eglstream_controller_interface is provided by + * libnvidia-egl-wayland.so.1 + * + * Since it might not be available on the + * system, dynamically load it at runtime and resolve the needed + * symbols. If available, it should be found under any of the search + * directories of dlopen() + * + * Failure to initialize wl_eglstream_controller is non-fatal + */ + + void *lib = dlopen ("libnvidia-egl-wayland.so.1", RTLD_NOW | RTLD_LAZY); + if (!lib) + goto fail; + + wl_eglstream_controller_interface_ptr = + dlsym (lib, "wl_eglstream_controller_interface"); + + if (!wl_eglstream_controller_interface_ptr) + goto fail; + + if (wl_global_create (compositor->wayland_display, + wl_eglstream_controller_interface_ptr, 1, + NULL, + bind_eglstream_controller) == NULL) + goto fail; + + return TRUE; + +fail: + if (lib) + dlclose(lib); + + g_debug ("WL: Unable to initialize wl_eglstream_controller."); +#endif + + return FALSE; +} struct _MetaWaylandEglStream { diff --git a/src/wayland/meta-wayland-egl-stream.h b/src/wayland/meta-wayland-egl-stream.h index 12a011f78..fe488ed54 100644 --- a/src/wayland/meta-wayland-egl-stream.h +++ b/src/wayland/meta-wayland-egl-stream.h @@ -31,6 +31,8 @@ #include "cogl/cogl.h" #include "wayland/meta-wayland-types.h" +gboolean meta_wayland_eglstream_controller_init (MetaWaylandCompositor *compositor); + #define META_TYPE_WAYLAND_EGL_STREAM (meta_wayland_egl_stream_get_type ()) G_DECLARE_FINAL_TYPE (MetaWaylandEglStream, meta_wayland_egl_stream, META, WAYLAND_EGL_STREAM, GObject); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index bab6b4ac4..9d416b20e 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -46,6 +46,8 @@ #include "meta-wayland-inhibit-shortcuts.h" #include "meta-wayland-inhibit-shortcuts-dialog.h" #include "meta-xwayland-grab-keyboard.h" +#include "meta-xwayland.h" +#include "meta-wayland-egl-stream.h" static MetaWaylandCompositor _meta_wayland_compositor; static char *_display_name_override; @@ -394,6 +396,8 @@ meta_wayland_init (void) meta_xwayland_global_filter, compositor); + meta_wayland_eglstream_controller_init (compositor); + if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display)) g_error ("Failed to start X Wayland");