mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
wayland: Create EGLStream-backed buffers through wl_eglstream_controller
One of the current limitations of EGLStreams is that there's no way to resize a surface consumer without re-creating the entire stream. Therefore, while resizing, clients will send wl_surface::attach requests so the compositor can re-create its endpoint of the stream, but no buffer will be available actually. If we proceed with the rest of the attach operation we'll be presenting an empty buffer. In order to fix this, a separate wl_eglstream_controller protocol has been introduced that clients can use to request a stream re-creation without overloading wl_surface::attach for that purpose. This change adds the required logic to create the corresponding wl_eglstream_controller global interface that clients can bind to. Whenever a client requests a stream to be created, we just need to create and realize the new EGLStream buffer. The same buffer resource will be given at a later time to wl_surface::attach, whenever new content is made available by the application, so we can proceed to acquire the stream buffer and update the surface state. https://bugzilla.gnome.org/show_bug.cgi?id=782575
This commit is contained in:
parent
22723ca371
commit
435b3c4bdb
1
.gitignore
vendored
1
.gitignore
vendored
@ -100,6 +100,7 @@ src/linux-dmabuf-unstable-v*-protocol.c
|
|||||||
src/linux-dmabuf-unstable-v*-server-protocol.h
|
src/linux-dmabuf-unstable-v*-server-protocol.h
|
||||||
src/xdg-shell-protocol.c
|
src/xdg-shell-protocol.c
|
||||||
src/xdg-shell-server-protocol.h
|
src/xdg-shell-server-protocol.h
|
||||||
|
src/wayland-eglstream-controller-server-protocol.h
|
||||||
src/meta/meta-version.h
|
src/meta/meta-version.h
|
||||||
src/libmutter-*.pc
|
src/libmutter-*.pc
|
||||||
doc/reference/*.args
|
doc/reference/*.args
|
||||||
|
12
configure.ac
12
configure.ac
@ -290,13 +290,24 @@ AS_IF([test "$have_native_backend" = "yes"], [
|
|||||||
])
|
])
|
||||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[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,
|
AC_ARG_ENABLE(egl-device,
|
||||||
AS_HELP_STRING([--enable-egl-device], [enable support for EGLDevice on top of KMS]),,
|
AS_HELP_STRING([--enable-egl-device], [enable support for EGLDevice on top of KMS]),,
|
||||||
enable_egl_device=no
|
enable_egl_device=no
|
||||||
|
have_wayland_eglstream=no
|
||||||
)
|
)
|
||||||
AS_IF([test "$enable_egl_device" = "yes"], [
|
AS_IF([test "$enable_egl_device" = "yes"], [
|
||||||
AC_DEFINE([HAVE_EGL_DEVICE],[1], [Defined if EGLDevice support is enabled])
|
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"
|
MUTTER_WAYLAND_MODULES="wayland-server >= 1.13.0"
|
||||||
|
|
||||||
@ -549,6 +560,7 @@ mutter-$VERSION
|
|||||||
Introspection: ${found_introspection}
|
Introspection: ${found_introspection}
|
||||||
Session management: ${found_sm}
|
Session management: ${found_sm}
|
||||||
Wayland: ${have_wayland}
|
Wayland: ${have_wayland}
|
||||||
|
Wayland EGLStream: ${have_wayland_eglstream}
|
||||||
Native (KMS) backend: ${have_native_backend}
|
Native (KMS) backend: ${have_native_backend}
|
||||||
EGLDevice: ${enable_egl_device}
|
EGLDevice: ${enable_egl_device}
|
||||||
Remote desktop: ${enable_remote_desktop}
|
Remote desktop: ${enable_remote_desktop}
|
||||||
|
@ -91,6 +91,12 @@ mutter_built_sources += \
|
|||||||
gtk-text-input-protocol.c \
|
gtk-text-input-protocol.c \
|
||||||
gtk-text-input-server-protocol.h \
|
gtk-text-input-server-protocol.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
if HAVE_WAYLAND_EGLSTREAM
|
||||||
|
mutter_built_sources += \
|
||||||
|
wayland-eglstream-controller-server-protocol.h \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
wayland_protocols = \
|
wayland_protocols = \
|
||||||
@ -766,3 +772,5 @@ endef
|
|||||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code $< $@
|
$(AM_V_GEN)$(WAYLAND_SCANNER) code $< $@
|
||||||
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
|
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
|
||||||
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@
|
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@
|
||||||
|
%-server-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/%.xml
|
||||||
|
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@
|
||||||
|
@ -32,6 +32,104 @@
|
|||||||
#include "backends/meta-egl-ext.h"
|
#include "backends/meta-egl-ext.h"
|
||||||
#include "meta/meta-backend.h"
|
#include "meta/meta-backend.h"
|
||||||
#include "wayland/meta-wayland-buffer.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 <dlfcn.h>
|
||||||
|
|
||||||
|
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
|
struct _MetaWaylandEglStream
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include "cogl/cogl.h"
|
#include "cogl/cogl.h"
|
||||||
#include "wayland/meta-wayland-types.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 ())
|
#define META_TYPE_WAYLAND_EGL_STREAM (meta_wayland_egl_stream_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (MetaWaylandEglStream, meta_wayland_egl_stream,
|
G_DECLARE_FINAL_TYPE (MetaWaylandEglStream, meta_wayland_egl_stream,
|
||||||
META, WAYLAND_EGL_STREAM, GObject);
|
META, WAYLAND_EGL_STREAM, GObject);
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "meta-wayland-inhibit-shortcuts-dialog.h"
|
#include "meta-wayland-inhibit-shortcuts-dialog.h"
|
||||||
#include "meta-xwayland-grab-keyboard.h"
|
#include "meta-xwayland-grab-keyboard.h"
|
||||||
#include "meta-xwayland.h"
|
#include "meta-xwayland.h"
|
||||||
|
#include "meta-wayland-egl-stream.h"
|
||||||
|
|
||||||
static MetaWaylandCompositor _meta_wayland_compositor;
|
static MetaWaylandCompositor _meta_wayland_compositor;
|
||||||
static char *_display_name_override;
|
static char *_display_name_override;
|
||||||
@ -397,6 +398,8 @@ meta_wayland_init (void)
|
|||||||
meta_xwayland_global_filter,
|
meta_xwayland_global_filter,
|
||||||
compositor);
|
compositor);
|
||||||
|
|
||||||
|
meta_wayland_eglstream_controller_init (compositor);
|
||||||
|
|
||||||
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
|
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
|
||||||
g_error ("Failed to start X Wayland");
|
g_error ("Failed to start X Wayland");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user