|
|
776610 |
From 04f59617e14d266c9d82b3f37a79db9467697dcf Mon Sep 17 00:00:00 2001
|
|
|
776610 |
From: "Miguel A. Vico" <mvicomoya@nvidia.com>
|
|
|
776610 |
Date: Tue, 27 Jun 2017 16:37:30 -0700
|
|
|
776610 |
Subject: [PATCH] wayland: Create EGLStream-backed buffers through
|
|
|
776610 |
wl_eglstream_controller
|
|
|
776610 |
|
|
|
776610 |
One of the current limitations of EGLStreams is that there's no way to
|
|
|
776610 |
resize a surface consumer without re-creating the entire stream.
|
|
|
776610 |
|
|
|
776610 |
Therefore, while resizing, clients will send wl_surface::attach requests
|
|
|
776610 |
so the compositor can re-create its endpoint of the stream, but no
|
|
|
776610 |
buffer will be available actually. If we proceed with the rest of the
|
|
|
776610 |
attach operation we'll be presenting an empty buffer.
|
|
|
776610 |
|
|
|
776610 |
In order to fix this, a separate wl_eglstream_controller protocol has
|
|
|
776610 |
been introduced that clients can use to request a stream re-creation
|
|
|
776610 |
without overloading wl_surface::attach for that purpose.
|
|
|
776610 |
|
|
|
776610 |
This change adds the required logic to create the corresponding
|
|
|
776610 |
wl_eglstream_controller global interface that clients can bind to.
|
|
|
776610 |
|
|
|
776610 |
Whenever a client requests a stream to be created, we just need to
|
|
|
776610 |
create and realize the new EGLStream buffer. The same buffer resource
|
|
|
776610 |
will be given at a later time to wl_surface::attach, whenever new
|
|
|
776610 |
content is made available by the application, so we can proceed to
|
|
|
776610 |
acquire the stream buffer and update the surface state.
|
|
|
776610 |
|
|
|
776610 |
https://bugzilla.gnome.org/show_bug.cgi?id=782575
|
|
|
776610 |
|
|
|
776610 |
(cherry picked from commit 435b3c4bdb62edcbb4b400223ddf7e44613efa54)
|
|
|
776610 |
---
|
|
|
776610 |
configure.ac | 12 ++++
|
|
|
776610 |
src/Makefile.am | 8 +++
|
|
|
776610 |
src/wayland/meta-wayland-egl-stream.c | 98 +++++++++++++++++++++++++++
|
|
|
776610 |
src/wayland/meta-wayland-egl-stream.h | 2 +
|
|
|
776610 |
src/wayland/meta-wayland.c | 4 ++
|
|
|
776610 |
6 files changed, 125 insertions(+)
|
|
|
776610 |
|
|
|
776610 |
diff --git a/configure.ac b/configure.ac
|
|
|
776610 |
index e795159a1..cfb098d20 100644
|
|
|
776610 |
--- a/configure.ac
|
|
|
776610 |
+++ b/configure.ac
|
|
|
776610 |
@@ -290,13 +290,24 @@ AS_IF([test "$have_native_backend" = "yes"], [
|
|
|
776610 |
])
|
|
|
776610 |
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test "$have_native_backend" = "yes"])
|
|
|
776610 |
|
|
|
776610 |
+MUTTER_WAYLAND_EGLSTREAM_MODULES="wayland-eglstream-protocols"
|
|
|
776610 |
+
|
|
|
776610 |
AC_ARG_ENABLE(egl-device,
|
|
|
776610 |
AS_HELP_STRING([--enable-egl-device], [enable support for EGLDevice on top of KMS]),,
|
|
|
776610 |
enable_egl_device=no
|
|
|
776610 |
+ have_wayland_eglstream=no
|
|
|
776610 |
)
|
|
|
776610 |
AS_IF([test "$enable_egl_device" = "yes"], [
|
|
|
776610 |
AC_DEFINE([HAVE_EGL_DEVICE],[1], [Defined if EGLDevice support is enabled])
|
|
|
776610 |
+ PKG_CHECK_EXISTS([$MUTTER_WAYLAND_EGLSTREAM_MODULES], [have_wayland_eglstream=yes], [have_wayland_eglstream=no])
|
|
|
776610 |
+])
|
|
|
776610 |
+AS_IF([test "$have_wayland_eglstream" = "yes"], [
|
|
|
776610 |
+ AC_DEFINE([HAVE_WAYLAND_EGLSTREAM],[1],[Defined if Wayland EGLStream protocols are available])
|
|
|
776610 |
+ PKG_CHECK_MODULES(WAYLAND_EGLSTREAM, [$MUTTER_WAYLAND_EGLSTREAM_MODULES],
|
|
|
776610 |
+ [ac_wayland_eglstream_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir $MUTTER_WAYLAND_EGLSTREAM_MODULES`])
|
|
|
776610 |
+ AC_SUBST(WAYLAND_EGLSTREAM_DATADIR, $ac_wayland_eglstream_pkgdatadir)
|
|
|
776610 |
])
|
|
|
776610 |
+AM_CONDITIONAL([HAVE_WAYLAND_EGLSTREAM],[test "$have_wayland_eglstream" = "yes"])
|
|
|
776610 |
|
|
|
776610 |
MUTTER_WAYLAND_MODULES="wayland-server >= 1.13.0"
|
|
|
776610 |
|
|
|
776610 |
@@ -549,6 +560,7 @@ mutter-$VERSION
|
|
|
776610 |
Introspection: ${found_introspection}
|
|
|
776610 |
Session management: ${found_sm}
|
|
|
776610 |
Wayland: ${have_wayland}
|
|
|
776610 |
+ Wayland EGLStream: ${have_wayland_eglstream}
|
|
|
776610 |
Native (KMS) backend: ${have_native_backend}
|
|
|
776610 |
EGLDevice: ${enable_egl_device}
|
|
|
776610 |
Remote desktop: ${enable_remote_desktop}
|
|
|
776610 |
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
|
776610 |
index bcb3505c7..6c4f872cb 100644
|
|
|
776610 |
--- a/src/Makefile.am
|
|
|
776610 |
+++ b/src/Makefile.am
|
|
|
776610 |
@@ -91,6 +91,12 @@ mutter_built_sources += \
|
|
|
776610 |
gtk-text-input-protocol.c \
|
|
|
776610 |
gtk-text-input-server-protocol.h \
|
|
|
776610 |
$(NULL)
|
|
|
776610 |
+
|
|
|
776610 |
+if HAVE_WAYLAND_EGLSTREAM
|
|
|
776610 |
+mutter_built_sources += \
|
|
|
776610 |
+ wayland-eglstream-controller-server-protocol.h \
|
|
|
776610 |
+ $(NULL)
|
|
|
776610 |
+endif
|
|
|
776610 |
endif
|
|
|
776610 |
|
|
|
776610 |
wayland_protocols = \
|
|
|
776610 |
@@ -760,3 +766,5 @@ endef
|
|
|
776610 |
$(AM_V_GEN)$(WAYLAND_SCANNER) code $< $@
|
|
|
776610 |
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
|
|
|
776610 |
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@
|
|
|
776610 |
+%-server-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/%.xml
|
|
|
776610 |
+ $(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@
|
|
|
776610 |
diff --git a/src/wayland/meta-wayland-egl-stream.c b/src/wayland/meta-wayland-egl-stream.c
|
|
|
776610 |
index 39ff93433..0d7ce2304 100644
|
|
|
776610 |
--- a/src/wayland/meta-wayland-egl-stream.c
|
|
|
776610 |
+++ b/src/wayland/meta-wayland-egl-stream.c
|
|
|
776610 |
@@ -32,6 +32,104 @@
|
|
|
776610 |
#include "backends/meta-egl-ext.h"
|
|
|
776610 |
#include "meta/meta-backend.h"
|
|
|
776610 |
#include "wayland/meta-wayland-buffer.h"
|
|
|
776610 |
+#include "wayland/meta-wayland-private.h"
|
|
|
776610 |
+
|
|
|
776610 |
+#ifdef HAVE_WAYLAND_EGLSTREAM
|
|
|
776610 |
+
|
|
|
776610 |
+#include "wayland-eglstream-controller-server-protocol.h"
|
|
|
776610 |
+#include <dlfcn.h>
|
|
|
776610 |
+
|
|
|
776610 |
+static struct wl_interface *wl_eglstream_controller_interface_ptr = NULL;
|
|
|
776610 |
+
|
|
|
776610 |
+static void
|
|
|
776610 |
+attach_eglstream_consumer (struct wl_client *client,
|
|
|
776610 |
+ struct wl_resource *resource,
|
|
|
776610 |
+ struct wl_resource *wl_surface,
|
|
|
776610 |
+ struct wl_resource *wl_eglstream)
|
|
|
776610 |
+{
|
|
|
776610 |
+ MetaWaylandBuffer *buffer = meta_wayland_buffer_from_resource (wl_eglstream);
|
|
|
776610 |
+
|
|
|
776610 |
+ if (!meta_wayland_buffer_is_realized (buffer))
|
|
|
776610 |
+ meta_wayland_buffer_realize (buffer);
|
|
|
776610 |
+}
|
|
|
776610 |
+
|
|
|
776610 |
+static const struct wl_eglstream_controller_interface
|
|
|
776610 |
+meta_eglstream_controller_interface = {
|
|
|
776610 |
+ attach_eglstream_consumer
|
|
|
776610 |
+};
|
|
|
776610 |
+
|
|
|
776610 |
+static void
|
|
|
776610 |
+bind_eglstream_controller (struct wl_client *client,
|
|
|
776610 |
+ void *data,
|
|
|
776610 |
+ uint32_t version,
|
|
|
776610 |
+ uint32_t id)
|
|
|
776610 |
+{
|
|
|
776610 |
+ struct wl_resource *resource;
|
|
|
776610 |
+
|
|
|
776610 |
+ g_assert (wl_eglstream_controller_interface_ptr != NULL);
|
|
|
776610 |
+
|
|
|
776610 |
+ resource = wl_resource_create (client,
|
|
|
776610 |
+ wl_eglstream_controller_interface_ptr,
|
|
|
776610 |
+ version,
|
|
|
776610 |
+ id);
|
|
|
776610 |
+
|
|
|
776610 |
+ if (resource == NULL)
|
|
|
776610 |
+ {
|
|
|
776610 |
+ wl_client_post_no_memory(client);
|
|
|
776610 |
+ return;
|
|
|
776610 |
+ }
|
|
|
776610 |
+
|
|
|
776610 |
+ wl_resource_set_implementation (resource,
|
|
|
776610 |
+ &meta_eglstream_controller_interface,
|
|
|
776610 |
+ data,
|
|
|
776610 |
+ NULL);
|
|
|
776610 |
+}
|
|
|
776610 |
+
|
|
|
776610 |
+#endif /* HAVE_WAYLAND_EGLSTREAM */
|
|
|
776610 |
+
|
|
|
776610 |
+gboolean
|
|
|
776610 |
+meta_wayland_eglstream_controller_init (MetaWaylandCompositor *compositor)
|
|
|
776610 |
+{
|
|
|
776610 |
+#ifdef HAVE_WAYLAND_EGLSTREAM
|
|
|
776610 |
+ /*
|
|
|
776610 |
+ * wl_eglstream_controller_interface is provided by
|
|
|
776610 |
+ * libnvidia-egl-wayland.so.1
|
|
|
776610 |
+ *
|
|
|
776610 |
+ * Since it might not be available on the
|
|
|
776610 |
+ * system, dynamically load it at runtime and resolve the needed
|
|
|
776610 |
+ * symbols. If available, it should be found under any of the search
|
|
|
776610 |
+ * directories of dlopen()
|
|
|
776610 |
+ *
|
|
|
776610 |
+ * Failure to initialize wl_eglstream_controller is non-fatal
|
|
|
776610 |
+ */
|
|
|
776610 |
+
|
|
|
776610 |
+ void *lib = dlopen ("libnvidia-egl-wayland.so.1", RTLD_NOW | RTLD_LAZY);
|
|
|
776610 |
+ if (!lib)
|
|
|
776610 |
+ goto fail;
|
|
|
776610 |
+
|
|
|
776610 |
+ wl_eglstream_controller_interface_ptr =
|
|
|
776610 |
+ dlsym (lib, "wl_eglstream_controller_interface");
|
|
|
776610 |
+
|
|
|
776610 |
+ if (!wl_eglstream_controller_interface_ptr)
|
|
|
776610 |
+ goto fail;
|
|
|
776610 |
+
|
|
|
776610 |
+ if (wl_global_create (compositor->wayland_display,
|
|
|
776610 |
+ wl_eglstream_controller_interface_ptr, 1,
|
|
|
776610 |
+ NULL,
|
|
|
776610 |
+ bind_eglstream_controller) == NULL)
|
|
|
776610 |
+ goto fail;
|
|
|
776610 |
+
|
|
|
776610 |
+ return TRUE;
|
|
|
776610 |
+
|
|
|
776610 |
+fail:
|
|
|
776610 |
+ if (lib)
|
|
|
776610 |
+ dlclose(lib);
|
|
|
776610 |
+
|
|
|
776610 |
+ g_debug ("WL: Unable to initialize wl_eglstream_controller.");
|
|
|
776610 |
+#endif
|
|
|
776610 |
+
|
|
|
776610 |
+ return FALSE;
|
|
|
776610 |
+}
|
|
|
776610 |
|
|
|
776610 |
struct _MetaWaylandEglStream
|
|
|
776610 |
{
|
|
|
776610 |
diff --git a/src/wayland/meta-wayland-egl-stream.h b/src/wayland/meta-wayland-egl-stream.h
|
|
|
776610 |
index 12a011f78..fe488ed54 100644
|
|
|
776610 |
--- a/src/wayland/meta-wayland-egl-stream.h
|
|
|
776610 |
+++ b/src/wayland/meta-wayland-egl-stream.h
|
|
|
776610 |
@@ -31,6 +31,8 @@
|
|
|
776610 |
#include "cogl/cogl.h"
|
|
|
776610 |
#include "wayland/meta-wayland-types.h"
|
|
|
776610 |
|
|
|
776610 |
+gboolean meta_wayland_eglstream_controller_init (MetaWaylandCompositor *compositor);
|
|
|
776610 |
+
|
|
|
776610 |
#define META_TYPE_WAYLAND_EGL_STREAM (meta_wayland_egl_stream_get_type ())
|
|
|
776610 |
G_DECLARE_FINAL_TYPE (MetaWaylandEglStream, meta_wayland_egl_stream,
|
|
|
776610 |
META, WAYLAND_EGL_STREAM, GObject);
|
|
|
776610 |
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
|
|
|
776610 |
index bab6b4ac4..9d416b20e 100644
|
|
|
776610 |
--- a/src/wayland/meta-wayland.c
|
|
|
776610 |
+++ b/src/wayland/meta-wayland.c
|
|
|
776610 |
@@ -46,6 +46,8 @@
|
|
|
776610 |
#include "meta-wayland-inhibit-shortcuts.h"
|
|
|
776610 |
#include "meta-wayland-inhibit-shortcuts-dialog.h"
|
|
|
776610 |
#include "meta-xwayland-grab-keyboard.h"
|
|
|
776610 |
+#include "meta-xwayland.h"
|
|
|
776610 |
+#include "meta-wayland-egl-stream.h"
|
|
|
776610 |
|
|
|
776610 |
static MetaWaylandCompositor _meta_wayland_compositor;
|
|
|
776610 |
static char *_display_name_override;
|
|
|
776610 |
@@ -394,6 +396,8 @@ meta_wayland_init (void)
|
|
|
776610 |
meta_xwayland_global_filter,
|
|
|
776610 |
compositor);
|
|
|
776610 |
|
|
|
776610 |
+ meta_wayland_eglstream_controller_init (compositor);
|
|
|
776610 |
+
|
|
|
776610 |
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
|
|
|
776610 |
g_error ("Failed to start X Wayland");
|
|
|
776610 |
|
|
|
776610 |
--
|
|
|
776610 |
2.19.1
|
|
|
776610 |
|