kathenas / rpms / mutter

Forked from rpms/mutter 5 years ago
Clone

Blame SOURCES/0001-wayland-Create-EGLStream-backed-buffers-through-wl_e.patch

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