Backport linux-dmabuf v4 support
Resolves: https://issues.redhat.com/browse/RHEL-129832
This commit is contained in:
parent
514647f182
commit
b8d17ac25e
80
0001-egl-Add-eglQueryDisplayAttribEXT-helper.patch
Normal file
80
0001-egl-Add-eglQueryDisplayAttribEXT-helper.patch
Normal file
@ -0,0 +1,80 @@
|
||||
From 0e6889f3ad3e417b29c5ea29fe6dfe485e5f6218 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Wed, 4 Aug 2021 09:59:50 +0200
|
||||
Subject: [PATCH 01/18] egl: Add eglQueryDisplayAttribEXT() helper
|
||||
|
||||
To be used to fetch the EGLDevice used for an EGL display.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 7ce481bf6996b2d99314311bf68afc6bd703c480)
|
||||
---
|
||||
src/backends/meta-egl.c | 23 +++++++++++++++++++++++
|
||||
src/backends/meta-egl.h | 6 ++++++
|
||||
2 files changed, 29 insertions(+)
|
||||
|
||||
diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c
|
||||
index fdeff4f779..c2777271ff 100644
|
||||
--- a/src/backends/meta-egl.c
|
||||
+++ b/src/backends/meta-egl.c
|
||||
@@ -71,6 +71,8 @@ struct _MetaEgl
|
||||
|
||||
PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT;
|
||||
PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT;
|
||||
+
|
||||
+ PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaEgl, meta_egl, G_TYPE_OBJECT)
|
||||
@@ -1064,6 +1066,25 @@ meta_egl_query_dma_buf_modifiers (MetaEgl *egl,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+gboolean
|
||||
+meta_egl_query_display_attrib (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLint attribute,
|
||||
+ EGLAttrib *value,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ if (!is_egl_proc_valid (egl->eglQueryDisplayAttribEXT, error))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!egl->eglQueryDisplayAttribEXT (display, attribute, value))
|
||||
+ {
|
||||
+ set_egl_error (error);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
#define GET_EGL_PROC_ADDR(proc) \
|
||||
egl->proc = (void *) eglGetProcAddress (#proc);
|
||||
|
||||
@@ -1102,6 +1123,8 @@ meta_egl_constructed (GObject *object)
|
||||
|
||||
GET_EGL_PROC_ADDR (eglQueryDmaBufFormatsEXT);
|
||||
GET_EGL_PROC_ADDR (eglQueryDmaBufModifiersEXT);
|
||||
+
|
||||
+ GET_EGL_PROC_ADDR (eglQueryDisplayAttribEXT);
|
||||
}
|
||||
|
||||
#undef GET_EGL_PROC_ADDR
|
||||
diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h
|
||||
index 4591e7d853..5c0aacd520 100644
|
||||
--- a/src/backends/meta-egl.h
|
||||
+++ b/src/backends/meta-egl.h
|
||||
@@ -260,4 +260,10 @@ gboolean meta_egl_query_dma_buf_modifiers (MetaEgl *egl,
|
||||
EGLint *num_formats,
|
||||
GError **error);
|
||||
|
||||
+gboolean meta_egl_query_display_attrib (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLint attribute,
|
||||
+ EGLAttrib *value,
|
||||
+ GError **error);
|
||||
+
|
||||
#endif /* META_EGL_H */
|
||||
--
|
||||
2.51.1
|
||||
|
||||
217
0002-wayland-dma-buf-Add-manager-struct.patch
Normal file
217
0002-wayland-dma-buf-Add-manager-struct.patch
Normal file
@ -0,0 +1,217 @@
|
||||
From bc73828642ed3ba6e7bee5ee8e8c83f8f15b1e14 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Wed, 4 Aug 2021 10:12:33 +0200
|
||||
Subject: [PATCH 02/18] wayland/dma-buf: Add manager struct
|
||||
|
||||
It'll be used to store state related to DMA buffer Wayland support.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 51308a9d78ba712a9a25438e257c430d517f35ac)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 49 ++++++++++++++++++++++--------
|
||||
src/wayland/meta-wayland-dma-buf.h | 5 ++-
|
||||
src/wayland/meta-wayland-private.h | 1 +
|
||||
src/wayland/meta-wayland-types.h | 2 ++
|
||||
src/wayland/meta-wayland.c | 28 ++++++++++++++++-
|
||||
5 files changed, 71 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index 230b13bc8a..0803a942db 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -66,6 +66,11 @@
|
||||
|
||||
#define META_WAYLAND_DMA_BUF_MAX_FDS 4
|
||||
|
||||
+struct _MetaWaylandDmaBufManager
|
||||
+{
|
||||
+ MetaWaylandCompositor *compositor;
|
||||
+};
|
||||
+
|
||||
struct _MetaWaylandDmaBufBuffer
|
||||
{
|
||||
GObject parent;
|
||||
@@ -696,17 +701,17 @@ send_modifiers (struct wl_resource *resource,
|
||||
|
||||
static void
|
||||
dma_buf_bind (struct wl_client *client,
|
||||
- void *data,
|
||||
+ void *user_data,
|
||||
uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
- MetaWaylandCompositor *compositor = data;
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager = user_data;
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &zwp_linux_dmabuf_v1_interface,
|
||||
version, id);
|
||||
wl_resource_set_implementation (resource, &dma_buf_implementation,
|
||||
- compositor, NULL);
|
||||
+ dma_buf_manager, NULL);
|
||||
send_modifiers (resource, DRM_FORMAT_ARGB8888);
|
||||
send_modifiers (resource, DRM_FORMAT_ABGR8888);
|
||||
send_modifiers (resource, DRM_FORMAT_XRGB8888);
|
||||
@@ -722,38 +727,58 @@ dma_buf_bind (struct wl_client *client,
|
||||
}
|
||||
|
||||
/**
|
||||
- * meta_wayland_dma_buf_init:
|
||||
+ * meta_wayland_dma_buf_manager_new:
|
||||
* @compositor: The #MetaWaylandCompositor
|
||||
*
|
||||
* Creates the global Wayland object that exposes the linux-dmabuf protocol.
|
||||
*
|
||||
- * Returns: Whether the initialization was successful. If this is %FALSE,
|
||||
- * clients won't be able to use the linux-dmabuf protocol to pass buffers.
|
||||
+ * Returns: (transfer full): The MetaWaylandDmaBufManager instance.
|
||||
*/
|
||||
-gboolean
|
||||
-meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor)
|
||||
+MetaWaylandDmaBufManager *
|
||||
+meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
+ GError **error)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaEgl *egl = meta_backend_get_egl (backend);
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
||||
+ g_autoptr (GError) local_error = NULL;
|
||||
+ g_autofree MetaWaylandDmaBufManager *dma_buf_manager = NULL;
|
||||
|
||||
g_assert (backend && egl && clutter_backend && cogl_context && egl_display);
|
||||
|
||||
if (!meta_egl_has_extensions (egl, egl_display, NULL,
|
||||
"EGL_EXT_image_dma_buf_import_modifiers",
|
||||
NULL))
|
||||
- return FALSE;
|
||||
+ {
|
||||
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
+ "Missing 'EGL_EXT_image_dma_buf_import_modifiers'");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ dma_buf_manager = g_new0 (MetaWaylandDmaBufManager, 1);
|
||||
|
||||
if (!wl_global_create (compositor->wayland_display,
|
||||
&zwp_linux_dmabuf_v1_interface,
|
||||
META_ZWP_LINUX_DMABUF_V1_VERSION,
|
||||
- compositor,
|
||||
+ dma_buf_manager,
|
||||
dma_buf_bind))
|
||||
- return FALSE;
|
||||
+ {
|
||||
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
+ "Failed to create zwp_linux_dmabuf_v1 global");
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- return TRUE;
|
||||
+ dma_buf_manager->compositor = compositor;
|
||||
+
|
||||
+ return g_steal_pointer (&dma_buf_manager);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+meta_wayland_dma_buf_manager_free (MetaWaylandDmaBufManager *dma_buf_manager)
|
||||
+{
|
||||
+ g_free (dma_buf_manager);
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.h b/src/wayland/meta-wayland-dma-buf.h
|
||||
index cdc65aeb5b..72fd0b16a0 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.h
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.h
|
||||
@@ -39,7 +39,10 @@ G_DECLARE_FINAL_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer,
|
||||
|
||||
typedef struct _MetaWaylandDmaBufBuffer MetaWaylandDmaBufBuffer;
|
||||
|
||||
-gboolean meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor);
|
||||
+MetaWaylandDmaBufManager * meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
+ GError **error);
|
||||
+
|
||||
+void meta_wayland_dma_buf_manager_free (MetaWaylandDmaBufManager *dma_buf_manager);
|
||||
|
||||
gboolean
|
||||
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
|
||||
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
|
||||
index 3306c192c9..3a2724256f 100644
|
||||
--- a/src/wayland/meta-wayland-private.h
|
||||
+++ b/src/wayland/meta-wayland-private.h
|
||||
@@ -97,6 +97,7 @@ struct _MetaWaylandCompositor
|
||||
GHashTable *scheduled_surface_associations;
|
||||
|
||||
MetaWaylandPresentationTime presentation_time;
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager;
|
||||
};
|
||||
|
||||
#define META_TYPE_WAYLAND_COMPOSITOR (meta_wayland_compositor_get_type ())
|
||||
diff --git a/src/wayland/meta-wayland-types.h b/src/wayland/meta-wayland-types.h
|
||||
index 00712ad1f1..8ad9084827 100644
|
||||
--- a/src/wayland/meta-wayland-types.h
|
||||
+++ b/src/wayland/meta-wayland-types.h
|
||||
@@ -61,4 +61,6 @@ typedef struct _MetaWaylandWindowConfiguration MetaWaylandWindowConfiguration;
|
||||
|
||||
typedef struct _MetaWaylandPointerClient MetaWaylandPointerClient;
|
||||
|
||||
+typedef struct _MetaWaylandDmaBufManager MetaWaylandDmaBufManager;
|
||||
+
|
||||
#endif
|
||||
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
|
||||
index 8f16aa429d..a566a35449 100644
|
||||
--- a/src/wayland/meta-wayland.c
|
||||
+++ b/src/wayland/meta-wayland.c
|
||||
@@ -454,6 +454,29 @@ meta_wayland_get_xwayland_auth_file (MetaWaylandCompositor *compositor)
|
||||
return compositor->xwayland_manager.auth_file;
|
||||
}
|
||||
|
||||
+static void
|
||||
+init_dma_buf_support (MetaWaylandCompositor *compositor)
|
||||
+{
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+
|
||||
+ compositor->dma_buf_manager = meta_wayland_dma_buf_manager_new (compositor,
|
||||
+ &error);
|
||||
+ if (!compositor->dma_buf_manager)
|
||||
+ {
|
||||
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
||||
+ {
|
||||
+ meta_topic (META_DEBUG_WAYLAND,
|
||||
+ "Wayland DMA buffer protocol support not enabled: %s",
|
||||
+ error->message);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_warning ("Wayland DMA buffer protocol support not enabled: %s",
|
||||
+ error->message);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
MetaWaylandCompositor *
|
||||
meta_wayland_compositor_new (MetaBackend *backend)
|
||||
{
|
||||
@@ -507,7 +530,7 @@ meta_wayland_compositor_setup (MetaWaylandCompositor *compositor)
|
||||
meta_wayland_relative_pointer_init (compositor);
|
||||
meta_wayland_pointer_constraints_init (compositor);
|
||||
meta_wayland_xdg_foreign_init (compositor);
|
||||
- meta_wayland_dma_buf_init (compositor);
|
||||
+ init_dma_buf_support (compositor);
|
||||
meta_wayland_keyboard_shortcuts_inhibit_init (compositor);
|
||||
meta_wayland_surface_inhibit_shortcuts_dialog_init ();
|
||||
meta_wayland_text_input_init (compositor);
|
||||
@@ -595,6 +618,9 @@ meta_wayland_finalize (void)
|
||||
if (compositor->wayland_display)
|
||||
wl_display_destroy_clients (compositor->wayland_display);
|
||||
|
||||
+ g_clear_pointer (&compositor->dma_buf_manager,
|
||||
+ meta_wayland_dma_buf_manager_free);
|
||||
+
|
||||
g_clear_pointer (&compositor->seat, meta_wayland_seat_free);
|
||||
|
||||
g_clear_pointer (&compositor->display_name, g_free);
|
||||
--
|
||||
2.51.1
|
||||
|
||||
261
0003-wayland-dma-buf-Prepare-format-modifier-map-up-front.patch
Normal file
261
0003-wayland-dma-buf-Prepare-format-modifier-map-up-front.patch
Normal file
@ -0,0 +1,261 @@
|
||||
From cf495636abdee738c59aa854cd16c172048bbf72 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Wed, 4 Aug 2021 10:17:15 +0200
|
||||
Subject: [PATCH 03/18] wayland/dma-buf: Prepare format/modifier map up front
|
||||
|
||||
As the format table is setup up front, it doesn't change when this
|
||||
experimental feature setting change. Make the settings documentation
|
||||
reflect that.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 1978e93f285222e10ac6d5a25de5f90d061ec228)
|
||||
---
|
||||
data/org.gnome.mutter.gschema.xml.in | 5 +
|
||||
src/wayland/meta-wayland-dma-buf.c | 166 ++++++++++++++++-----------
|
||||
2 files changed, 106 insertions(+), 65 deletions(-)
|
||||
|
||||
diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in
|
||||
index 23fa9f3ad3..4955f8d383 100644
|
||||
--- a/data/org.gnome.mutter.gschema.xml.in
|
||||
+++ b/data/org.gnome.mutter.gschema.xml.in
|
||||
@@ -121,6 +121,11 @@
|
||||
to manage HiDPI monitors. Does not
|
||||
require a restart.
|
||||
|
||||
+ • “kms-modifiers” — makes mutter always advertise valid
|
||||
+ buffer modifiers on Wayland. This is
|
||||
+ currently not the case when using the
|
||||
+ i915 driver. Requires a restart.
|
||||
+
|
||||
• “rt-scheduler” — makes mutter request a low priority
|
||||
real-time scheduling. The executable
|
||||
or user must have CAP_SYS_NICE.
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index 0803a942db..d9338ae474 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -66,9 +66,17 @@
|
||||
|
||||
#define META_WAYLAND_DMA_BUF_MAX_FDS 4
|
||||
|
||||
+typedef struct _MetaWaylandDmaBufFormat
|
||||
+{
|
||||
+ uint32_t drm_format;
|
||||
+ uint64_t drm_modifier;
|
||||
+} MetaWaylandDmaBufFormat;
|
||||
+
|
||||
struct _MetaWaylandDmaBufManager
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
+
|
||||
+ GArray *formats;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDmaBufBuffer
|
||||
@@ -633,97 +641,122 @@ should_send_modifiers (MetaBackend *backend)
|
||||
}
|
||||
|
||||
static void
|
||||
-send_modifiers (struct wl_resource *resource,
|
||||
- uint32_t format)
|
||||
+send_modifiers (struct wl_resource *resource,
|
||||
+ MetaWaylandDmaBufFormat *format)
|
||||
+{
|
||||
+ zwp_linux_dmabuf_v1_send_format (resource, format->drm_format);
|
||||
+
|
||||
+ if (wl_resource_get_version (resource) <
|
||||
+ ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION)
|
||||
+ return;
|
||||
+
|
||||
+ zwp_linux_dmabuf_v1_send_modifier (resource,
|
||||
+ format->drm_format,
|
||||
+ format->drm_modifier >> 32,
|
||||
+ format->drm_modifier & 0xffffffff);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dma_buf_bind (struct wl_client *client,
|
||||
+ void *user_data,
|
||||
+ uint32_t version,
|
||||
+ uint32_t id)
|
||||
+{
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager = user_data;
|
||||
+ struct wl_resource *resource;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ resource = wl_resource_create (client, &zwp_linux_dmabuf_v1_interface,
|
||||
+ version, id);
|
||||
+ wl_resource_set_implementation (resource, &dma_buf_implementation,
|
||||
+ dma_buf_manager, NULL);
|
||||
+
|
||||
+
|
||||
+ for (i = 0; i < dma_buf_manager->formats->len; i++)
|
||||
+ {
|
||||
+ MetaWaylandDmaBufFormat *format =
|
||||
+ &g_array_index (dma_buf_manager->formats,
|
||||
+ MetaWaylandDmaBufFormat,
|
||||
+ i);
|
||||
+
|
||||
+ send_modifiers (resource, format);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+add_format (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
+ EGLDisplay egl_display,
|
||||
+ uint32_t drm_format)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaEgl *egl = meta_backend_get_egl (backend);
|
||||
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
- CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
- EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
||||
EGLint num_modifiers;
|
||||
- EGLuint64KHR *modifiers;
|
||||
- GError *error = NULL;
|
||||
- gboolean ret;
|
||||
+ g_autofree EGLuint64KHR *modifiers = NULL;
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
int i;
|
||||
-
|
||||
- zwp_linux_dmabuf_v1_send_format (resource, format);
|
||||
-
|
||||
- /* The modifier event was only added in v3; v1 and v2 only have the format
|
||||
- * event. */
|
||||
- if (wl_resource_get_version (resource) < ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION)
|
||||
- return;
|
||||
+ MetaWaylandDmaBufFormat format;
|
||||
|
||||
if (!should_send_modifiers (backend))
|
||||
- {
|
||||
- zwp_linux_dmabuf_v1_send_modifier (resource, format,
|
||||
- DRM_FORMAT_MOD_INVALID >> 32,
|
||||
- DRM_FORMAT_MOD_INVALID & 0xffffffff);
|
||||
- return;
|
||||
- }
|
||||
+ goto add_fallback;
|
||||
|
||||
/* First query the number of available modifiers, then allocate an array,
|
||||
* then fill the array. */
|
||||
- ret = meta_egl_query_dma_buf_modifiers (egl, egl_display, format, 0, NULL,
|
||||
- NULL, &num_modifiers, NULL);
|
||||
- if (!ret)
|
||||
- return;
|
||||
+ if (!meta_egl_query_dma_buf_modifiers (egl, egl_display, drm_format, 0, NULL,
|
||||
+ NULL, &num_modifiers, NULL))
|
||||
+ goto add_fallback;
|
||||
|
||||
if (num_modifiers == 0)
|
||||
- {
|
||||
- zwp_linux_dmabuf_v1_send_modifier (resource, format,
|
||||
- DRM_FORMAT_MOD_INVALID >> 32,
|
||||
- DRM_FORMAT_MOD_INVALID & 0xffffffff);
|
||||
- return;
|
||||
- }
|
||||
+ goto add_fallback;
|
||||
|
||||
modifiers = g_new0 (uint64_t, num_modifiers);
|
||||
- ret = meta_egl_query_dma_buf_modifiers (egl, egl_display, format,
|
||||
- num_modifiers, modifiers, NULL,
|
||||
- &num_modifiers, &error);
|
||||
- if (!ret)
|
||||
+ if (!meta_egl_query_dma_buf_modifiers (egl, egl_display, drm_format,
|
||||
+ num_modifiers, modifiers, NULL,
|
||||
+ &num_modifiers, &error))
|
||||
{
|
||||
g_warning ("Failed to query modifiers for format 0x%" PRIu32 ": %s",
|
||||
- format, error ? error->message : "unknown error");
|
||||
- g_free (modifiers);
|
||||
- return;
|
||||
+ drm_format, error ? error->message : "unknown error");
|
||||
+ goto add_fallback;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_modifiers; i++)
|
||||
{
|
||||
- zwp_linux_dmabuf_v1_send_modifier (resource, format,
|
||||
- modifiers[i] >> 32,
|
||||
- modifiers[i] & 0xffffffff);
|
||||
+ format = (MetaWaylandDmaBufFormat) {
|
||||
+ .drm_format = drm_format,
|
||||
+ .drm_modifier = modifiers[i],
|
||||
+ };
|
||||
+ g_array_append_val (dma_buf_manager->formats, format);
|
||||
}
|
||||
|
||||
- g_free (modifiers);
|
||||
+ return;
|
||||
+
|
||||
+add_fallback:
|
||||
+ format = (MetaWaylandDmaBufFormat) {
|
||||
+ .drm_format = drm_format,
|
||||
+ .drm_modifier = DRM_FORMAT_MOD_INVALID,
|
||||
+ };
|
||||
+ g_array_append_val (dma_buf_manager->formats, format);
|
||||
}
|
||||
|
||||
static void
|
||||
-dma_buf_bind (struct wl_client *client,
|
||||
- void *user_data,
|
||||
- uint32_t version,
|
||||
- uint32_t id)
|
||||
+init_formats (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
+ EGLDisplay egl_display)
|
||||
{
|
||||
- MetaWaylandDmaBufManager *dma_buf_manager = user_data;
|
||||
- struct wl_resource *resource;
|
||||
-
|
||||
- resource = wl_resource_create (client, &zwp_linux_dmabuf_v1_interface,
|
||||
- version, id);
|
||||
- wl_resource_set_implementation (resource, &dma_buf_implementation,
|
||||
- dma_buf_manager, NULL);
|
||||
- send_modifiers (resource, DRM_FORMAT_ARGB8888);
|
||||
- send_modifiers (resource, DRM_FORMAT_ABGR8888);
|
||||
- send_modifiers (resource, DRM_FORMAT_XRGB8888);
|
||||
- send_modifiers (resource, DRM_FORMAT_XBGR8888);
|
||||
- send_modifiers (resource, DRM_FORMAT_ARGB2101010);
|
||||
- send_modifiers (resource, DRM_FORMAT_ABGR2101010);
|
||||
- send_modifiers (resource, DRM_FORMAT_XRGB2101010);
|
||||
- send_modifiers (resource, DRM_FORMAT_RGB565);
|
||||
- send_modifiers (resource, DRM_FORMAT_ABGR16161616F);
|
||||
- send_modifiers (resource, DRM_FORMAT_XBGR16161616F);
|
||||
- send_modifiers (resource, DRM_FORMAT_XRGB16161616F);
|
||||
- send_modifiers (resource, DRM_FORMAT_ARGB16161616F);
|
||||
+ dma_buf_manager->formats = g_array_new (FALSE, FALSE,
|
||||
+ sizeof (MetaWaylandDmaBufFormat));
|
||||
+
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB8888);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR8888);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB8888);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR8888);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB2101010);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR2101010);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB2101010);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR2101010);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_RGB565);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR16161616F);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR16161616F);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB16161616F);
|
||||
+ add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB16161616F);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -772,12 +805,15 @@ meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
|
||||
dma_buf_manager->compositor = compositor;
|
||||
|
||||
+ init_formats (dma_buf_manager, egl_display);
|
||||
+
|
||||
return g_steal_pointer (&dma_buf_manager);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_dma_buf_manager_free (MetaWaylandDmaBufManager *dma_buf_manager)
|
||||
{
|
||||
+ g_clear_pointer (&dma_buf_manager->formats, g_array_unref);
|
||||
g_free (dma_buf_manager);
|
||||
}
|
||||
|
||||
--
|
||||
2.51.1
|
||||
|
||||
545
0004-wayland-dma-buf-Add-basic-support-for-DMA-buffer-fee.patch
Normal file
545
0004-wayland-dma-buf-Add-basic-support-for-DMA-buffer-fee.patch
Normal file
@ -0,0 +1,545 @@
|
||||
From ed3c27feeb3b745d04ec462e82d8ae58e041338e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Thu, 5 Aug 2021 15:10:47 +0200
|
||||
Subject: [PATCH 04/18] wayland/dma-buf: Add basic support for DMA buffer
|
||||
feedback
|
||||
|
||||
This includes sending the default tranche, but so far only sends the
|
||||
same for every surface feedback requested. Scanout tranche will be added
|
||||
later.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 7acecb1c7233dad0b9b314f59121882a518901d7)
|
||||
---
|
||||
meson.build | 2 +-
|
||||
src/wayland/meta-wayland-dma-buf.c | 368 +++++++++++++++++++++++++++-
|
||||
src/wayland/meta-wayland-versions.h | 1 -
|
||||
3 files changed, 360 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index f6f3872394..2dbee750c3 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -41,7 +41,7 @@ gudev_req = '>= 232'
|
||||
|
||||
# wayland version requirements
|
||||
wayland_server_req = '>= 1.18'
|
||||
-wayland_protocols_req = '>= 1.19'
|
||||
+wayland_protocols_req = '>= 1.24'
|
||||
|
||||
# native backend version requirements
|
||||
libinput_req = '>= 1.15.0'
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index d9338ae474..7155d07dcf 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -40,6 +40,9 @@
|
||||
#include "wayland/meta-wayland-dma-buf.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-egl-ext.h"
|
||||
@@ -66,17 +69,41 @@
|
||||
|
||||
#define META_WAYLAND_DMA_BUF_MAX_FDS 4
|
||||
|
||||
+/* Compatible with zwp_linux_dmabuf_feedback_v1.tranche_flags */
|
||||
+typedef enum _MetaWaylandDmaBufTrancheFlags
|
||||
+{
|
||||
+ META_WAYLAND_DMA_BUF_TRANCHE_FLAG_NONE = 0,
|
||||
+ META_WAYLAND_DMA_BUF_TRANCHE_FLAG_SCANOUT = 1,
|
||||
+} MetaWaylandDmaBufTrancheFlags;
|
||||
+
|
||||
typedef struct _MetaWaylandDmaBufFormat
|
||||
{
|
||||
uint32_t drm_format;
|
||||
uint64_t drm_modifier;
|
||||
+ uint16_t table_index;
|
||||
} MetaWaylandDmaBufFormat;
|
||||
|
||||
+typedef struct _MetaWaylandDmaBufTranche
|
||||
+{
|
||||
+ dev_t target_device_id;
|
||||
+ GArray *formats;
|
||||
+ MetaWaylandDmaBufTrancheFlags flags;
|
||||
+} MetaWaylandDmaBufTranche;
|
||||
+
|
||||
+typedef struct _MetaWaylandDmaBufFeedback
|
||||
+{
|
||||
+ dev_t main_device_id;
|
||||
+ GList *tranches;
|
||||
+} MetaWaylandDmaBufFeedback;
|
||||
+
|
||||
struct _MetaWaylandDmaBufManager
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
+ dev_t main_device_id;
|
||||
|
||||
GArray *formats;
|
||||
+ MetaAnonymousFile *format_table_file;
|
||||
+ MetaWaylandDmaBufFeedback *default_feedback;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDmaBufBuffer
|
||||
@@ -95,6 +122,118 @@ struct _MetaWaylandDmaBufBuffer
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJECT);
|
||||
|
||||
+static MetaWaylandDmaBufTranche *
|
||||
+meta_wayland_dma_buf_tranche_new (dev_t device_id,
|
||||
+ GArray *formats,
|
||||
+ MetaWaylandDmaBufTrancheFlags flags)
|
||||
+{
|
||||
+ MetaWaylandDmaBufTranche *tranche;
|
||||
+
|
||||
+ tranche = g_new0 (MetaWaylandDmaBufTranche, 1);
|
||||
+ tranche->target_device_id = device_id;
|
||||
+ tranche->formats = g_array_copy (formats);
|
||||
+ tranche->flags = flags;
|
||||
+
|
||||
+ return tranche;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_dma_buf_tranche_free (MetaWaylandDmaBufTranche *tranche)
|
||||
+{
|
||||
+ g_clear_pointer (&tranche->formats, g_array_unref);
|
||||
+ g_free (tranche);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_dma_buf_tranche_send (MetaWaylandDmaBufTranche *tranche,
|
||||
+ struct wl_resource *resource)
|
||||
+{
|
||||
+ struct wl_array target_device_buf;
|
||||
+ dev_t *device_id_ptr;
|
||||
+ struct wl_array formats_array;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ wl_array_init (&target_device_buf);
|
||||
+ device_id_ptr = wl_array_add (&target_device_buf, sizeof (*device_id_ptr));
|
||||
+ *device_id_ptr = tranche->target_device_id;
|
||||
+ zwp_linux_dmabuf_feedback_v1_send_tranche_target_device (resource,
|
||||
+ &target_device_buf);
|
||||
+ wl_array_release (&target_device_buf);
|
||||
+ zwp_linux_dmabuf_feedback_v1_send_tranche_flags (resource, tranche->flags);
|
||||
+
|
||||
+ wl_array_init (&formats_array);
|
||||
+ for (i = 0; i < tranche->formats->len; i++)
|
||||
+ {
|
||||
+ MetaWaylandDmaBufFormat *format =
|
||||
+ &g_array_index (tranche->formats,
|
||||
+ MetaWaylandDmaBufFormat,
|
||||
+ i);
|
||||
+ uint16_t *format_index_ptr;
|
||||
+
|
||||
+ format_index_ptr = wl_array_add (&formats_array,
|
||||
+ sizeof (*format_index_ptr));
|
||||
+ *format_index_ptr = format->table_index;
|
||||
+ }
|
||||
+ zwp_linux_dmabuf_feedback_v1_send_tranche_formats (resource, &formats_array);
|
||||
+ wl_array_release (&formats_array);
|
||||
+
|
||||
+ zwp_linux_dmabuf_feedback_v1_send_tranche_done (resource);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_dma_buf_feedback_send (MetaWaylandDmaBufFeedback *feedback,
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
+ struct wl_resource *resource)
|
||||
+{
|
||||
+ size_t size;
|
||||
+ int fd;
|
||||
+ struct wl_array main_device_buf;
|
||||
+ dev_t *device_id_ptr;
|
||||
+
|
||||
+ fd = meta_anonymous_file_open_fd (dma_buf_manager->format_table_file,
|
||||
+ META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
|
||||
+ size = meta_anonymous_file_size (dma_buf_manager->format_table_file);
|
||||
+ zwp_linux_dmabuf_feedback_v1_send_format_table (resource, fd, size);
|
||||
+ meta_anonymous_file_close_fd (fd);
|
||||
+
|
||||
+ wl_array_init (&main_device_buf);
|
||||
+ device_id_ptr = wl_array_add (&main_device_buf, sizeof (*device_id_ptr));
|
||||
+ *device_id_ptr = feedback->main_device_id;
|
||||
+ zwp_linux_dmabuf_feedback_v1_send_main_device (resource, &main_device_buf);
|
||||
+
|
||||
+ g_list_foreach (feedback->tranches,
|
||||
+ (GFunc) meta_wayland_dma_buf_tranche_send,
|
||||
+ resource);
|
||||
+
|
||||
+ zwp_linux_dmabuf_feedback_v1_send_done (resource);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_dma_buf_feedback_add_tranche (MetaWaylandDmaBufFeedback *feedback,
|
||||
+ MetaWaylandDmaBufTranche *tranche)
|
||||
+{
|
||||
+ feedback->tranches = g_list_append (feedback->tranches, tranche);
|
||||
+}
|
||||
+
|
||||
+static MetaWaylandDmaBufFeedback *
|
||||
+meta_wayland_dma_buf_feedback_new (dev_t device_id)
|
||||
+{
|
||||
+ MetaWaylandDmaBufFeedback *feedback;
|
||||
+
|
||||
+ feedback = g_new0 (MetaWaylandDmaBufFeedback, 1);
|
||||
+ feedback->main_device_id = device_id;
|
||||
+
|
||||
+ return feedback;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_dma_buf_feedback_free (MetaWaylandDmaBufFeedback *feedback)
|
||||
+{
|
||||
+ g_clear_list (&feedback->tranches,
|
||||
+ (GDestroyNotify) meta_wayland_dma_buf_tranche_free);
|
||||
+ g_free (feedback);
|
||||
+}
|
||||
+
|
||||
static gboolean
|
||||
meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
|
||||
GError **error)
|
||||
@@ -616,10 +755,80 @@ dma_buf_handle_create_buffer_params (struct wl_client *client,
|
||||
buffer_params_destructor);
|
||||
}
|
||||
|
||||
+static void
|
||||
+feedback_destroy (struct wl_client *client,
|
||||
+ struct wl_resource *resource)
|
||||
+{
|
||||
+ wl_resource_destroy (resource);
|
||||
+}
|
||||
+
|
||||
+static const struct zwp_linux_dmabuf_feedback_v1_interface feedback_implementation =
|
||||
+{
|
||||
+ feedback_destroy,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+feedback_destructor (struct wl_resource *resource)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dma_buf_handle_get_default_feedback (struct wl_client *client,
|
||||
+ struct wl_resource *dma_buf_resource,
|
||||
+ uint32_t feedback_id)
|
||||
+{
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager =
|
||||
+ wl_resource_get_user_data (dma_buf_resource);
|
||||
+ struct wl_resource *feedback_resource;
|
||||
+
|
||||
+ feedback_resource =
|
||||
+ wl_resource_create (client,
|
||||
+ &zwp_linux_dmabuf_feedback_v1_interface,
|
||||
+ wl_resource_get_version (dma_buf_resource),
|
||||
+ feedback_id);
|
||||
+
|
||||
+ wl_resource_set_implementation (feedback_resource,
|
||||
+ &feedback_implementation,
|
||||
+ NULL,
|
||||
+ feedback_destructor);
|
||||
+
|
||||
+ meta_wayland_dma_buf_feedback_send (dma_buf_manager->default_feedback,
|
||||
+ dma_buf_manager,
|
||||
+ feedback_resource);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dma_buf_handle_get_surface_feedback (struct wl_client *client,
|
||||
+ struct wl_resource *dma_buf_resource,
|
||||
+ uint32_t feedback_id,
|
||||
+ struct wl_resource *surface_resource)
|
||||
+{
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager =
|
||||
+ wl_resource_get_user_data (dma_buf_resource);
|
||||
+ struct wl_resource *feedback_resource;
|
||||
+
|
||||
+ feedback_resource =
|
||||
+ wl_resource_create (client,
|
||||
+ &zwp_linux_dmabuf_feedback_v1_interface,
|
||||
+ wl_resource_get_version (dma_buf_resource),
|
||||
+ feedback_id);
|
||||
+
|
||||
+ wl_resource_set_implementation (feedback_resource,
|
||||
+ &feedback_implementation,
|
||||
+ NULL,
|
||||
+ feedback_destructor);
|
||||
+
|
||||
+ meta_wayland_dma_buf_feedback_send (dma_buf_manager->default_feedback,
|
||||
+ dma_buf_manager,
|
||||
+ feedback_resource);
|
||||
+}
|
||||
+
|
||||
static const struct zwp_linux_dmabuf_v1_interface dma_buf_implementation =
|
||||
{
|
||||
dma_buf_handle_destroy,
|
||||
dma_buf_handle_create_buffer_params,
|
||||
+ dma_buf_handle_get_default_feedback,
|
||||
+ dma_buf_handle_get_surface_feedback,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
@@ -644,6 +853,9 @@ static void
|
||||
send_modifiers (struct wl_resource *resource,
|
||||
MetaWaylandDmaBufFormat *format)
|
||||
{
|
||||
+ g_assert (wl_resource_get_version (resource) <
|
||||
+ ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION);
|
||||
+
|
||||
zwp_linux_dmabuf_v1_send_format (resource, format->drm_format);
|
||||
|
||||
if (wl_resource_get_version (resource) <
|
||||
@@ -664,22 +876,25 @@ dma_buf_bind (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandDmaBufManager *dma_buf_manager = user_data;
|
||||
struct wl_resource *resource;
|
||||
- unsigned int i;
|
||||
|
||||
resource = wl_resource_create (client, &zwp_linux_dmabuf_v1_interface,
|
||||
version, id);
|
||||
wl_resource_set_implementation (resource, &dma_buf_implementation,
|
||||
dma_buf_manager, NULL);
|
||||
|
||||
-
|
||||
- for (i = 0; i < dma_buf_manager->formats->len; i++)
|
||||
+ if (version < ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION)
|
||||
{
|
||||
- MetaWaylandDmaBufFormat *format =
|
||||
- &g_array_index (dma_buf_manager->formats,
|
||||
- MetaWaylandDmaBufFormat,
|
||||
- i);
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < dma_buf_manager->formats->len; i++)
|
||||
+ {
|
||||
+ MetaWaylandDmaBufFormat *format =
|
||||
+ &g_array_index (dma_buf_manager->formats,
|
||||
+ MetaWaylandDmaBufFormat,
|
||||
+ i);
|
||||
|
||||
- send_modifiers (resource, format);
|
||||
+ send_modifiers (resource, format);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -723,6 +938,7 @@ add_format (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
format = (MetaWaylandDmaBufFormat) {
|
||||
.drm_format = drm_format,
|
||||
.drm_modifier = modifiers[i],
|
||||
+ .table_index = dma_buf_manager->formats->len,
|
||||
};
|
||||
g_array_append_val (dma_buf_manager->formats, format);
|
||||
}
|
||||
@@ -733,10 +949,53 @@ add_fallback:
|
||||
format = (MetaWaylandDmaBufFormat) {
|
||||
.drm_format = drm_format,
|
||||
.drm_modifier = DRM_FORMAT_MOD_INVALID,
|
||||
+ .table_index = dma_buf_manager->formats->len,
|
||||
};
|
||||
g_array_append_val (dma_buf_manager->formats, format);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * This is the structure the data is expected to have in the shared memory file
|
||||
+ * shared with clients, according to the Wayland Linux DMA buffer protocol.
|
||||
+ * It's structured as 16 bytes (128 bits) per entry, where each entry consists
|
||||
+ * of the following:
|
||||
+ *
|
||||
+ * [ 32 bit format ][ 32 bit padding ][ 64 bit modifier ]
|
||||
+ */
|
||||
+typedef struct _MetaMetaWaylanDmaBdufFormatEntry
|
||||
+{
|
||||
+ uint32_t drm_format;
|
||||
+ uint32_t unused_padding;
|
||||
+ uint64_t drm_modifier;
|
||||
+} MetaWaylandDmaBufFormatEntry;
|
||||
+
|
||||
+G_STATIC_ASSERT (sizeof (MetaWaylandDmaBufFormatEntry) == 16);
|
||||
+G_STATIC_ASSERT (offsetof (MetaWaylandDmaBufFormatEntry, drm_format) == 0);
|
||||
+G_STATIC_ASSERT (offsetof (MetaWaylandDmaBufFormatEntry, drm_modifier) == 8);
|
||||
+
|
||||
+static void
|
||||
+init_format_table (MetaWaylandDmaBufManager *dma_buf_manager)
|
||||
+{
|
||||
+ g_autofree MetaWaylandDmaBufFormatEntry *format_table = NULL;
|
||||
+ size_t size;
|
||||
+ int i;
|
||||
+
|
||||
+ size = sizeof (MetaWaylandDmaBufFormatEntry) * dma_buf_manager->formats->len;
|
||||
+ format_table = g_malloc0 (size);
|
||||
+
|
||||
+ for (i = 0; i < dma_buf_manager->formats->len; i++)
|
||||
+ {
|
||||
+ MetaWaylandDmaBufFormat *format =
|
||||
+ &g_array_index (dma_buf_manager->formats, MetaWaylandDmaBufFormat, i);
|
||||
+
|
||||
+ format_table[i].drm_format = format->drm_format;
|
||||
+ format_table[i].drm_modifier = format->drm_modifier;
|
||||
+ }
|
||||
+
|
||||
+ dma_buf_manager->format_table_file =
|
||||
+ meta_anonymous_file_new (size, (uint8_t *) format_table);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
init_formats (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
EGLDisplay egl_display)
|
||||
@@ -757,6 +1016,25 @@ init_formats (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR16161616F);
|
||||
add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB16161616F);
|
||||
add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB16161616F);
|
||||
+
|
||||
+ init_format_table (dma_buf_manager);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+init_default_feedback (MetaWaylandDmaBufManager *dma_buf_manager)
|
||||
+{
|
||||
+ MetaWaylandDmaBufTrancheFlags flags;
|
||||
+ MetaWaylandDmaBufTranche *tranche;
|
||||
+
|
||||
+ dma_buf_manager->default_feedback =
|
||||
+ meta_wayland_dma_buf_feedback_new (dma_buf_manager->main_device_id);
|
||||
+
|
||||
+ flags = META_WAYLAND_DMA_BUF_TRANCHE_FLAG_NONE;
|
||||
+ tranche = meta_wayland_dma_buf_tranche_new (dma_buf_manager->main_device_id,
|
||||
+ dma_buf_manager->formats,
|
||||
+ flags);
|
||||
+ meta_wayland_dma_buf_feedback_add_tranche (dma_buf_manager->default_feedback,
|
||||
+ tranche);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -776,8 +1054,14 @@ meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
||||
+ dev_t device_id = 0;
|
||||
+ int protocol_version;
|
||||
+ EGLDeviceEXT egl_device;
|
||||
+ EGLAttrib attrib;
|
||||
g_autoptr (GError) local_error = NULL;
|
||||
g_autofree MetaWaylandDmaBufManager *dma_buf_manager = NULL;
|
||||
+ const char *device_path = NULL;
|
||||
+ struct stat device_stat;
|
||||
|
||||
g_assert (backend && egl && clutter_backend && cogl_context && egl_display);
|
||||
|
||||
@@ -790,11 +1074,71 @@ meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ if (!meta_egl_query_display_attrib (egl, egl_display,
|
||||
+ EGL_DEVICE_EXT, &attrib,
|
||||
+ &local_error))
|
||||
+ {
|
||||
+ g_warning ("Failed to query EGL device from primary EGL display: %s",
|
||||
+ local_error->message);
|
||||
+ protocol_version = 3;
|
||||
+ goto initialize;
|
||||
+ }
|
||||
+ egl_device = (EGLDeviceEXT) attrib;
|
||||
+
|
||||
+ if (meta_egl_egl_device_has_extensions (egl, egl_device, NULL,
|
||||
+ "EGL_EXT_device_drm_render_node",
|
||||
+ NULL))
|
||||
+ {
|
||||
+ device_path = meta_egl_query_device_string (egl, egl_device,
|
||||
+ EGL_DRM_RENDER_NODE_FILE_EXT,
|
||||
+ &local_error);
|
||||
+ }
|
||||
+ else if (meta_egl_egl_device_has_extensions (egl, egl_device, NULL,
|
||||
+ "EGL_EXT_device_drm",
|
||||
+ NULL))
|
||||
+ {
|
||||
+ device_path = meta_egl_query_device_string (egl, egl_device,
|
||||
+ EGL_DRM_DEVICE_FILE_EXT,
|
||||
+ &local_error);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ meta_topic (META_DEBUG_WAYLAND,
|
||||
+ "Only advertising zwp_linux_dmabuf_v1 interface version 3 "
|
||||
+ "support, missing 'EGL_EXT_device_drm' and "
|
||||
+ "'EGL_EXT_device_drm_render_node'");
|
||||
+ protocol_version = 3;
|
||||
+ goto initialize;
|
||||
+ }
|
||||
+
|
||||
+ if (!device_path)
|
||||
+ {
|
||||
+ g_warning ("Failed to query EGL device path: %s",
|
||||
+ local_error->message);
|
||||
+ protocol_version = 3;
|
||||
+ goto initialize;
|
||||
+ }
|
||||
+
|
||||
+ if (stat (device_path, &device_stat) != 0)
|
||||
+ {
|
||||
+ g_warning ("Failed to fetch device file ID for '%s': %s",
|
||||
+ device_path,
|
||||
+ g_strerror (errno));
|
||||
+ protocol_version = 3;
|
||||
+ goto initialize;
|
||||
+ }
|
||||
+
|
||||
+ device_id = device_stat.st_rdev;
|
||||
+
|
||||
+ protocol_version = 4;
|
||||
+
|
||||
+initialize:
|
||||
+
|
||||
dma_buf_manager = g_new0 (MetaWaylandDmaBufManager, 1);
|
||||
|
||||
if (!wl_global_create (compositor->wayland_display,
|
||||
&zwp_linux_dmabuf_v1_interface,
|
||||
- META_ZWP_LINUX_DMABUF_V1_VERSION,
|
||||
+ protocol_version,
|
||||
dma_buf_manager,
|
||||
dma_buf_bind))
|
||||
{
|
||||
@@ -804,8 +1148,10 @@ meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
}
|
||||
|
||||
dma_buf_manager->compositor = compositor;
|
||||
+ dma_buf_manager->main_device_id = device_id;
|
||||
|
||||
init_formats (dma_buf_manager, egl_display);
|
||||
+ init_default_feedback (dma_buf_manager);
|
||||
|
||||
return g_steal_pointer (&dma_buf_manager);
|
||||
}
|
||||
@@ -813,7 +1159,11 @@ meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
void
|
||||
meta_wayland_dma_buf_manager_free (MetaWaylandDmaBufManager *dma_buf_manager)
|
||||
{
|
||||
+ g_clear_pointer (&dma_buf_manager->format_table_file,
|
||||
+ meta_anonymous_file_free);
|
||||
g_clear_pointer (&dma_buf_manager->formats, g_array_unref);
|
||||
+ g_clear_pointer (&dma_buf_manager->default_feedback,
|
||||
+ meta_wayland_dma_buf_feedback_free);
|
||||
g_free (dma_buf_manager);
|
||||
}
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h
|
||||
index 8f71c19dce..78e4e6127a 100644
|
||||
--- a/src/wayland/meta-wayland-versions.h
|
||||
+++ b/src/wayland/meta-wayland-versions.h
|
||||
@@ -48,7 +48,6 @@
|
||||
#define META_ZWP_POINTER_GESTURES_V1_VERSION 1
|
||||
#define META_ZXDG_EXPORTER_V1_VERSION 1
|
||||
#define META_ZXDG_IMPORTER_V1_VERSION 1
|
||||
-#define META_ZWP_LINUX_DMABUF_V1_VERSION 3
|
||||
#define META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION 1
|
||||
#define META_ZXDG_OUTPUT_V1_VERSION 3
|
||||
#define META_ZWP_XWAYLAND_KEYBOARD_GRAB_V1_VERSION 1
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
From e4d494916c1045dd24ae44a82c8e398feed2179d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Tue, 7 Dec 2021 22:12:57 +0100
|
||||
Subject: [PATCH 05/18] wayland/dma-buf: Always advertise non-modifier fallback
|
||||
|
||||
This is done to explicitly tell clients that the compositor supports
|
||||
implicit modifier paths (i.e. using modifier unaware API).
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 2a16a750c556a916a6792adf10adbe4499d5e092)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 17 ++++++++++++-----
|
||||
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index 7155d07dcf..ca9be5d601 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -851,12 +851,18 @@ should_send_modifiers (MetaBackend *backend)
|
||||
|
||||
static void
|
||||
send_modifiers (struct wl_resource *resource,
|
||||
- MetaWaylandDmaBufFormat *format)
|
||||
+ MetaWaylandDmaBufFormat *format,
|
||||
+ GHashTable *sent_formats)
|
||||
{
|
||||
g_assert (wl_resource_get_version (resource) <
|
||||
ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION);
|
||||
|
||||
- zwp_linux_dmabuf_v1_send_format (resource, format->drm_format);
|
||||
+ if (!g_hash_table_contains (sent_formats,
|
||||
+ GUINT_TO_POINTER (format->drm_format)))
|
||||
+ {
|
||||
+ g_hash_table_add (sent_formats, GUINT_TO_POINTER (format->drm_format));
|
||||
+ zwp_linux_dmabuf_v1_send_format (resource, format->drm_format);
|
||||
+ }
|
||||
|
||||
if (wl_resource_get_version (resource) <
|
||||
ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION)
|
||||
@@ -884,8 +890,11 @@ dma_buf_bind (struct wl_client *client,
|
||||
|
||||
if (version < ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION)
|
||||
{
|
||||
+ g_autoptr (GHashTable) sent_formats = NULL;
|
||||
unsigned int i;
|
||||
|
||||
+ sent_formats = g_hash_table_new (NULL, NULL);
|
||||
+
|
||||
for (i = 0; i < dma_buf_manager->formats->len; i++)
|
||||
{
|
||||
MetaWaylandDmaBufFormat *format =
|
||||
@@ -893,7 +902,7 @@ dma_buf_bind (struct wl_client *client,
|
||||
MetaWaylandDmaBufFormat,
|
||||
i);
|
||||
|
||||
- send_modifiers (resource, format);
|
||||
+ send_modifiers (resource, format, sent_formats);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -943,8 +952,6 @@ add_format (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
g_array_append_val (dma_buf_manager->formats, format);
|
||||
}
|
||||
|
||||
- return;
|
||||
-
|
||||
add_fallback:
|
||||
format = (MetaWaylandDmaBufFormat) {
|
||||
.drm_format = drm_format,
|
||||
--
|
||||
2.51.1
|
||||
|
||||
98
0006-wayland-surface-Remove-unnecessary-NULL-check.patch
Normal file
98
0006-wayland-surface-Remove-unnecessary-NULL-check.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From 15168d00affa1e05fd1307abef196b6e395a14bb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Thu, 5 Aug 2021 16:03:26 +0200
|
||||
Subject: [PATCH 06/18] wayland/surface: Remove unnecessary NULL check
|
||||
|
||||
This check has caused repeated confusion, as there are no current code
|
||||
paths where this can ever end up in the true-branch.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 90076cf268bde6c18e49908514d7dc7af4b3a92e)
|
||||
---
|
||||
src/wayland/meta-wayland-surface.c | 28 ----------------------------
|
||||
1 file changed, 28 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
|
||||
index 6e6457b249..e033b7b911 100644
|
||||
--- a/src/wayland/meta-wayland-surface.c
|
||||
+++ b/src/wayland/meta-wayland-surface.c
|
||||
@@ -1027,10 +1027,6 @@ wl_surface_attach (struct wl_client *client,
|
||||
MetaWaylandSurfaceState *pending = surface->pending_state;
|
||||
MetaWaylandBuffer *buffer;
|
||||
|
||||
- /* X11 unmanaged window */
|
||||
- if (!surface)
|
||||
- return;
|
||||
-
|
||||
if (buffer_resource)
|
||||
buffer = meta_wayland_buffer_from_resource (buffer_resource);
|
||||
else
|
||||
@@ -1068,10 +1064,6 @@ wl_surface_damage (struct wl_client *client,
|
||||
MetaWaylandSurfaceState *pending = surface->pending_state;
|
||||
cairo_rectangle_int_t rectangle;
|
||||
|
||||
- /* X11 unmanaged window */
|
||||
- if (!surface)
|
||||
- return;
|
||||
-
|
||||
rectangle = (cairo_rectangle_int_t) {
|
||||
.x = x,
|
||||
.y = y,
|
||||
@@ -1100,10 +1092,6 @@ wl_surface_frame (struct wl_client *client,
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaWaylandSurfaceState *pending = surface->pending_state;
|
||||
|
||||
- /* X11 unmanaged window */
|
||||
- if (!surface)
|
||||
- return;
|
||||
-
|
||||
callback = g_new0 (MetaWaylandFrameCallback, 1);
|
||||
callback->surface = surface;
|
||||
callback->resource = wl_resource_create (client,
|
||||
@@ -1124,10 +1112,6 @@ wl_surface_set_opaque_region (struct wl_client *client,
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaWaylandSurfaceState *pending = surface->pending_state;
|
||||
|
||||
- /* X11 unmanaged window */
|
||||
- if (!surface)
|
||||
- return;
|
||||
-
|
||||
g_clear_pointer (&pending->opaque_region, cairo_region_destroy);
|
||||
if (region_resource)
|
||||
{
|
||||
@@ -1146,10 +1130,6 @@ wl_surface_set_input_region (struct wl_client *client,
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaWaylandSurfaceState *pending = surface->pending_state;
|
||||
|
||||
- /* X11 unmanaged window */
|
||||
- if (!surface)
|
||||
- return;
|
||||
-
|
||||
g_clear_pointer (&pending->input_region, cairo_region_destroy);
|
||||
if (region_resource)
|
||||
{
|
||||
@@ -1166,10 +1146,6 @@ wl_surface_commit (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
- /* X11 unmanaged window */
|
||||
- if (!surface)
|
||||
- return;
|
||||
-
|
||||
meta_wayland_surface_commit (surface);
|
||||
}
|
||||
|
||||
@@ -1257,10 +1233,6 @@ wl_surface_damage_buffer (struct wl_client *client,
|
||||
MetaWaylandSurfaceState *pending = surface->pending_state;
|
||||
cairo_rectangle_int_t rectangle;
|
||||
|
||||
- /* X11 unmanaged window */
|
||||
- if (!surface)
|
||||
- return;
|
||||
-
|
||||
rectangle = (cairo_rectangle_int_t) {
|
||||
.x = x,
|
||||
.y = y,
|
||||
--
|
||||
2.51.1
|
||||
|
||||
145
0007-wayland-dma-buf-Make-manager-object-a-GObject.patch
Normal file
145
0007-wayland-dma-buf-Make-manager-object-a-GObject.patch
Normal file
@ -0,0 +1,145 @@
|
||||
From ba03e83acc2157fa96bb06784ca43d0da7e942ab Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Fri, 6 Aug 2021 15:23:15 +0200
|
||||
Subject: [PATCH 07/18] wayland/dma-buf: Make manager object a GObject
|
||||
|
||||
Will make certain operations easier, i.e. setting up a GQuark.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 9c942a43d6c49a728ab472d08640cef929cc94b0)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 48 ++++++++++++++++++++++--------
|
||||
src/wayland/meta-wayland-dma-buf.h | 6 ++--
|
||||
src/wayland/meta-wayland.c | 3 +-
|
||||
3 files changed, 40 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index ca9be5d601..6b798ec2dd 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -98,6 +98,8 @@ typedef struct _MetaWaylandDmaBufFeedback
|
||||
|
||||
struct _MetaWaylandDmaBufManager
|
||||
{
|
||||
+ GObject parent;
|
||||
+
|
||||
MetaWaylandCompositor *compositor;
|
||||
dev_t main_device_id;
|
||||
|
||||
@@ -122,6 +124,9 @@ struct _MetaWaylandDmaBufBuffer
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJECT);
|
||||
|
||||
+G_DEFINE_TYPE (MetaWaylandDmaBufManager, meta_wayland_dma_buf_manager,
|
||||
+ G_TYPE_OBJECT)
|
||||
+
|
||||
static MetaWaylandDmaBufTranche *
|
||||
meta_wayland_dma_buf_tranche_new (dev_t device_id,
|
||||
GArray *formats,
|
||||
@@ -1066,7 +1071,7 @@ meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
EGLDeviceEXT egl_device;
|
||||
EGLAttrib attrib;
|
||||
g_autoptr (GError) local_error = NULL;
|
||||
- g_autofree MetaWaylandDmaBufManager *dma_buf_manager = NULL;
|
||||
+ g_autoptr (MetaWaylandDmaBufManager) dma_buf_manager = NULL;
|
||||
const char *device_path = NULL;
|
||||
struct stat device_stat;
|
||||
|
||||
@@ -1141,7 +1146,7 @@ meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
|
||||
initialize:
|
||||
|
||||
- dma_buf_manager = g_new0 (MetaWaylandDmaBufManager, 1);
|
||||
+ dma_buf_manager = g_object_new (META_TYPE_WAYLAND_DMA_BUF_MANAGER, NULL);
|
||||
|
||||
if (!wl_global_create (compositor->wayland_display,
|
||||
&zwp_linux_dmabuf_v1_interface,
|
||||
@@ -1163,17 +1168,6 @@ initialize:
|
||||
return g_steal_pointer (&dma_buf_manager);
|
||||
}
|
||||
|
||||
-void
|
||||
-meta_wayland_dma_buf_manager_free (MetaWaylandDmaBufManager *dma_buf_manager)
|
||||
-{
|
||||
- g_clear_pointer (&dma_buf_manager->format_table_file,
|
||||
- meta_anonymous_file_free);
|
||||
- g_clear_pointer (&dma_buf_manager->formats, g_array_unref);
|
||||
- g_clear_pointer (&dma_buf_manager->default_feedback,
|
||||
- meta_wayland_dma_buf_feedback_free);
|
||||
- g_free (dma_buf_manager);
|
||||
-}
|
||||
-
|
||||
static void
|
||||
meta_wayland_dma_buf_buffer_finalize (GObject *object)
|
||||
{
|
||||
@@ -1207,3 +1201,31 @@ meta_wayland_dma_buf_buffer_class_init (MetaWaylandDmaBufBufferClass *klass)
|
||||
|
||||
object_class->finalize = meta_wayland_dma_buf_buffer_finalize;
|
||||
}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_dma_buf_manager_finalize (GObject *object)
|
||||
+{
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager =
|
||||
+ META_WAYLAND_DMA_BUF_MANAGER (object);
|
||||
+
|
||||
+ g_clear_pointer (&dma_buf_manager->format_table_file,
|
||||
+ meta_anonymous_file_free);
|
||||
+ g_clear_pointer (&dma_buf_manager->formats, g_array_unref);
|
||||
+ g_clear_pointer (&dma_buf_manager->default_feedback,
|
||||
+ meta_wayland_dma_buf_feedback_free);
|
||||
+
|
||||
+ G_OBJECT_CLASS (meta_wayland_dma_buf_manager_parent_class)->finalize (object);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_dma_buf_manager_class_init (MetaWaylandDmaBufManagerClass *klass)
|
||||
+{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
+
|
||||
+ object_class->finalize = meta_wayland_dma_buf_manager_finalize;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_dma_buf_manager_init (MetaWaylandDmaBufManager *dma_buf)
|
||||
+{
|
||||
+}
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.h b/src/wayland/meta-wayland-dma-buf.h
|
||||
index 72fd0b16a0..dc1231560b 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.h
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.h
|
||||
@@ -37,13 +37,15 @@
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer,
|
||||
META, WAYLAND_DMA_BUF_BUFFER, GObject);
|
||||
|
||||
+#define META_TYPE_WAYLAND_DMA_BUF_MANAGER (meta_wayland_dma_buf_manager_get_type ())
|
||||
+G_DECLARE_FINAL_TYPE (MetaWaylandDmaBufManager, meta_wayland_dma_buf_manager,
|
||||
+ META, WAYLAND_DMA_BUF_MANAGER, GObject)
|
||||
+
|
||||
typedef struct _MetaWaylandDmaBufBuffer MetaWaylandDmaBufBuffer;
|
||||
|
||||
MetaWaylandDmaBufManager * meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
GError **error);
|
||||
|
||||
-void meta_wayland_dma_buf_manager_free (MetaWaylandDmaBufManager *dma_buf_manager);
|
||||
-
|
||||
gboolean
|
||||
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
|
||||
CoglTexture **texture,
|
||||
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
|
||||
index a566a35449..28af6ae196 100644
|
||||
--- a/src/wayland/meta-wayland.c
|
||||
+++ b/src/wayland/meta-wayland.c
|
||||
@@ -618,8 +618,7 @@ meta_wayland_finalize (void)
|
||||
if (compositor->wayland_display)
|
||||
wl_display_destroy_clients (compositor->wayland_display);
|
||||
|
||||
- g_clear_pointer (&compositor->dma_buf_manager,
|
||||
- meta_wayland_dma_buf_manager_free);
|
||||
+ g_clear_object (&compositor->dma_buf_manager);
|
||||
|
||||
g_clear_pointer (&compositor->seat, meta_wayland_seat_free);
|
||||
|
||||
--
|
||||
2.51.1
|
||||
|
||||
108
0008-wayland-dma-buf-Add-tranche-priorities.patch
Normal file
108
0008-wayland-dma-buf-Add-tranche-priorities.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From c5f6a8435d526438c722f6b13869d177bcc31855 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Fri, 6 Aug 2021 16:20:14 +0200
|
||||
Subject: [PATCH 08/18] wayland/dma-buf: Add tranche priorities
|
||||
|
||||
Unused for now, but will be added to prioritize scanout tranches higher
|
||||
than render only ones.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 9a47766a9627e75fffb7c5a20c0e3d63aae38539)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 36 ++++++++++++++++++++++++++----
|
||||
1 file changed, 32 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index 6b798ec2dd..a255158993 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -76,6 +76,12 @@ typedef enum _MetaWaylandDmaBufTrancheFlags
|
||||
META_WAYLAND_DMA_BUF_TRANCHE_FLAG_SCANOUT = 1,
|
||||
} MetaWaylandDmaBufTrancheFlags;
|
||||
|
||||
+typedef enum _MetaWaylandDmaBufTranchePriority
|
||||
+{
|
||||
+ META_WAYLAND_DMA_BUF_TRANCHE_PRIORITY_HIGH = 0,
|
||||
+ META_WAYLAND_DMA_BUF_TRANCHE_PRIORITY_DEFAULT = 10,
|
||||
+} MetaWaylandDmaBufTranchePriority;
|
||||
+
|
||||
typedef struct _MetaWaylandDmaBufFormat
|
||||
{
|
||||
uint32_t drm_format;
|
||||
@@ -85,6 +91,7 @@ typedef struct _MetaWaylandDmaBufFormat
|
||||
|
||||
typedef struct _MetaWaylandDmaBufTranche
|
||||
{
|
||||
+ MetaWaylandDmaBufTranchePriority priority;
|
||||
dev_t target_device_id;
|
||||
GArray *formats;
|
||||
MetaWaylandDmaBufTrancheFlags flags;
|
||||
@@ -127,16 +134,33 @@ G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJE
|
||||
G_DEFINE_TYPE (MetaWaylandDmaBufManager, meta_wayland_dma_buf_manager,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
+static gint
|
||||
+compare_tranches (gconstpointer a,
|
||||
+ gconstpointer b)
|
||||
+{
|
||||
+ const MetaWaylandDmaBufTranche *tranche_a = a;
|
||||
+ const MetaWaylandDmaBufTranche *tranche_b = b;
|
||||
+
|
||||
+ if (tranche_a->priority > tranche_b->priority)
|
||||
+ return 1;
|
||||
+ if (tranche_a->priority < tranche_b->priority)
|
||||
+ return -1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static MetaWaylandDmaBufTranche *
|
||||
-meta_wayland_dma_buf_tranche_new (dev_t device_id,
|
||||
- GArray *formats,
|
||||
- MetaWaylandDmaBufTrancheFlags flags)
|
||||
+meta_wayland_dma_buf_tranche_new (dev_t device_id,
|
||||
+ GArray *formats,
|
||||
+ MetaWaylandDmaBufTranchePriority priority,
|
||||
+ MetaWaylandDmaBufTrancheFlags flags)
|
||||
{
|
||||
MetaWaylandDmaBufTranche *tranche;
|
||||
|
||||
tranche = g_new0 (MetaWaylandDmaBufTranche, 1);
|
||||
tranche->target_device_id = device_id;
|
||||
tranche->formats = g_array_copy (formats);
|
||||
+ tranche->priority = priority;
|
||||
tranche->flags = flags;
|
||||
|
||||
return tranche;
|
||||
@@ -217,7 +241,8 @@ static void
|
||||
meta_wayland_dma_buf_feedback_add_tranche (MetaWaylandDmaBufFeedback *feedback,
|
||||
MetaWaylandDmaBufTranche *tranche)
|
||||
{
|
||||
- feedback->tranches = g_list_append (feedback->tranches, tranche);
|
||||
+ feedback->tranches = g_list_insert_sorted (feedback->tranches, tranche,
|
||||
+ compare_tranches);
|
||||
}
|
||||
|
||||
static MetaWaylandDmaBufFeedback *
|
||||
@@ -1035,15 +1060,18 @@ init_formats (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
static void
|
||||
init_default_feedback (MetaWaylandDmaBufManager *dma_buf_manager)
|
||||
{
|
||||
+ MetaWaylandDmaBufTranchePriority priority;
|
||||
MetaWaylandDmaBufTrancheFlags flags;
|
||||
MetaWaylandDmaBufTranche *tranche;
|
||||
|
||||
dma_buf_manager->default_feedback =
|
||||
meta_wayland_dma_buf_feedback_new (dma_buf_manager->main_device_id);
|
||||
|
||||
+ priority = META_WAYLAND_DMA_BUF_TRANCHE_PRIORITY_DEFAULT;
|
||||
flags = META_WAYLAND_DMA_BUF_TRANCHE_FLAG_NONE;
|
||||
tranche = meta_wayland_dma_buf_tranche_new (dma_buf_manager->main_device_id,
|
||||
dma_buf_manager->formats,
|
||||
+ priority,
|
||||
flags);
|
||||
meta_wayland_dma_buf_feedback_add_tranche (dma_buf_manager->default_feedback,
|
||||
tranche);
|
||||
--
|
||||
2.51.1
|
||||
|
||||
302
0009-compositor-native-Track-what-Wayland-surface-is-a-sc.patch
Normal file
302
0009-compositor-native-Track-what-Wayland-surface-is-a-sc.patch
Normal file
@ -0,0 +1,302 @@
|
||||
From f928306ebbec7bcbdb80a456b07e7db0219da36c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Fri, 6 Aug 2021 17:00:19 +0200
|
||||
Subject: [PATCH 09/18] compositor/native: Track what Wayland surface is a
|
||||
scanout candidate
|
||||
|
||||
For the current candidate, set the candidate CRTC on that surface. This
|
||||
will later be used to send DMA buffer feedback for direct scanout purposes.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 43161c66602febd5bf635f8dea927da1b282c757)
|
||||
---
|
||||
src/compositor/meta-compositor-native.c | 69 +++++++++++++++++----
|
||||
src/compositor/meta-surface-actor-wayland.c | 3 +-
|
||||
src/wayland/meta-wayland-surface.c | 60 ++++++++++++++++++
|
||||
src/wayland/meta-wayland-surface.h | 8 +++
|
||||
4 files changed, 127 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/compositor/meta-compositor-native.c b/src/compositor/meta-compositor-native.c
|
||||
index 00f66b70d4..7822789a3e 100644
|
||||
--- a/src/compositor/meta-compositor-native.c
|
||||
+++ b/src/compositor/meta-compositor-native.c
|
||||
@@ -23,11 +23,14 @@
|
||||
#include "compositor/meta-compositor-native.h"
|
||||
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
+#include "backends/native/meta-crtc-kms.h"
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
|
||||
struct _MetaCompositorNative
|
||||
{
|
||||
MetaCompositorServer parent;
|
||||
+
|
||||
+ MetaWaylandSurface *current_scanout_candidate;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaCompositorNative, meta_compositor_native,
|
||||
@@ -62,57 +65,88 @@ get_window_view (MetaRenderer *renderer,
|
||||
static void
|
||||
maybe_assign_primary_plane (MetaCompositor *compositor)
|
||||
{
|
||||
+ MetaCompositorNative *compositor_native = META_COMPOSITOR_NATIVE (compositor);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaWindowActor *window_actor;
|
||||
MetaWindow *window;
|
||||
MetaRendererView *view;
|
||||
+ MetaCrtc *crtc;
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglOnscreen *onscreen;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaSurfaceActorWayland *surface_actor_wayland;
|
||||
+ MetaWaylandSurface *surface;
|
||||
+ MetaWaylandSurface *old_candidate =
|
||||
+ compositor_native->current_scanout_candidate;
|
||||
+ MetaWaylandSurface *new_candidate = NULL;
|
||||
g_autoptr (CoglScanout) scanout = NULL;
|
||||
|
||||
if (meta_compositor_is_unredirect_inhibited (compositor))
|
||||
- return;
|
||||
+ goto done;
|
||||
|
||||
window_actor = meta_compositor_get_top_window_actor (compositor);
|
||||
if (!window_actor)
|
||||
- return;
|
||||
+ goto done;
|
||||
|
||||
if (meta_window_actor_effect_in_progress (window_actor))
|
||||
- return;
|
||||
+ goto done;
|
||||
|
||||
if (clutter_actor_has_transitions (CLUTTER_ACTOR (window_actor)))
|
||||
- return;
|
||||
+ goto done;
|
||||
|
||||
if (clutter_actor_get_n_children (CLUTTER_ACTOR (window_actor)) != 1)
|
||||
- return;
|
||||
+ goto done;
|
||||
|
||||
window = meta_window_actor_get_meta_window (window_actor);
|
||||
if (!window)
|
||||
- return;
|
||||
+ goto done;
|
||||
|
||||
view = get_window_view (renderer, window);
|
||||
if (!view)
|
||||
- return;
|
||||
+ goto done;
|
||||
+
|
||||
+ crtc = meta_renderer_view_get_crtc (META_RENDERER_VIEW (view));
|
||||
+ if (!META_IS_CRTC_KMS (crtc))
|
||||
+ goto done;
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (CLUTTER_STAGE_VIEW (view));
|
||||
if (!COGL_IS_ONSCREEN (framebuffer))
|
||||
- return;
|
||||
+ goto done;
|
||||
|
||||
surface_actor = meta_window_actor_get_surface (window_actor);
|
||||
if (!META_IS_SURFACE_ACTOR_WAYLAND (surface_actor))
|
||||
- return;
|
||||
-
|
||||
+ goto done;
|
||||
surface_actor_wayland = META_SURFACE_ACTOR_WAYLAND (surface_actor);
|
||||
+
|
||||
+ surface = meta_surface_actor_wayland_get_surface (surface_actor_wayland);
|
||||
+ if (!surface)
|
||||
+ goto done;
|
||||
+
|
||||
+ new_candidate = surface;
|
||||
+
|
||||
onscreen = COGL_ONSCREEN (framebuffer);
|
||||
scanout = meta_surface_actor_wayland_try_acquire_scanout (surface_actor_wayland,
|
||||
onscreen);
|
||||
if (!scanout)
|
||||
- return;
|
||||
+ goto done;
|
||||
|
||||
clutter_stage_view_assign_next_scanout (CLUTTER_STAGE_VIEW (view), scanout);
|
||||
+
|
||||
+done:
|
||||
+
|
||||
+ if (old_candidate && old_candidate != new_candidate)
|
||||
+ {
|
||||
+ meta_wayland_surface_set_scanout_candidate (old_candidate, NULL);
|
||||
+ g_clear_weak_pointer (&compositor_native->current_scanout_candidate);
|
||||
+ }
|
||||
+
|
||||
+ if (new_candidate)
|
||||
+ {
|
||||
+ meta_wayland_surface_set_scanout_candidate (surface, crtc);
|
||||
+ g_set_weak_pointer (&compositor_native->current_scanout_candidate,
|
||||
+ surface);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -137,6 +171,16 @@ meta_compositor_native_new (MetaDisplay *display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
+static void
|
||||
+meta_compositor_native_finalize (GObject *object)
|
||||
+{
|
||||
+ MetaCompositorNative *compositor_native = META_COMPOSITOR_NATIVE (object);
|
||||
+
|
||||
+ g_clear_weak_pointer (&compositor_native->current_scanout_candidate);
|
||||
+
|
||||
+ G_OBJECT_CLASS (meta_compositor_native_parent_class)->finalize (object);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_compositor_native_init (MetaCompositorNative *compositor_native)
|
||||
{
|
||||
@@ -145,7 +189,10 @@ meta_compositor_native_init (MetaCompositorNative *compositor_native)
|
||||
static void
|
||||
meta_compositor_native_class_init (MetaCompositorNativeClass *klass)
|
||||
{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
|
||||
|
||||
+ object_class->finalize = meta_compositor_native_finalize;
|
||||
+
|
||||
compositor_class->before_paint = meta_compositor_native_before_paint;
|
||||
}
|
||||
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
|
||||
index 8c2a93da1e..4e131b0ba6 100644
|
||||
--- a/src/compositor/meta-surface-actor-wayland.c
|
||||
+++ b/src/compositor/meta-surface-actor-wayland.c
|
||||
@@ -80,8 +80,7 @@ meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
||||
return NULL;
|
||||
|
||||
surface = meta_surface_actor_wayland_get_surface (self);
|
||||
- if (!surface)
|
||||
- return NULL;
|
||||
+ g_return_val_if_fail (surface, NULL);
|
||||
|
||||
scanout = meta_wayland_surface_try_acquire_scanout (surface, onscreen);
|
||||
if (!scanout)
|
||||
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
|
||||
index e033b7b911..c69433352e 100644
|
||||
--- a/src/wayland/meta-wayland-surface.c
|
||||
+++ b/src/wayland/meta-wayland-surface.c
|
||||
@@ -79,6 +79,17 @@ typedef struct _MetaWaylandSurfaceRolePrivate
|
||||
MetaWaylandSurface *surface;
|
||||
} MetaWaylandSurfaceRolePrivate;
|
||||
|
||||
+enum
|
||||
+{
|
||||
+ PROP_0,
|
||||
+
|
||||
+ PROP_SCANOUT_CANDIDATE,
|
||||
+
|
||||
+ N_PROPS
|
||||
+};
|
||||
+
|
||||
+static GParamSpec *obj_props[N_PROPS];
|
||||
+
|
||||
G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT);
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole,
|
||||
@@ -1413,6 +1424,7 @@ wl_surface_destructor (struct wl_resource *resource)
|
||||
|
||||
g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0);
|
||||
|
||||
+ g_clear_object (&surface->scanout_candidate);
|
||||
g_clear_object (&surface->role);
|
||||
|
||||
if (surface->unassigned.buffer)
|
||||
@@ -1697,11 +1709,41 @@ meta_wayland_surface_init (MetaWaylandSurface *surface)
|
||||
g_node_prepend_data (surface->subsurface_branch_node, surface);
|
||||
}
|
||||
|
||||
+static void
|
||||
+meta_wayland_surface_get_property (GObject *object,
|
||||
+ guint prop_id,
|
||||
+ GValue *value,
|
||||
+ GParamSpec *pspec)
|
||||
+{
|
||||
+ MetaWaylandSurface *surface = META_WAYLAND_SURFACE (object);
|
||||
+
|
||||
+ switch (prop_id)
|
||||
+ {
|
||||
+ case PROP_SCANOUT_CANDIDATE:
|
||||
+ g_value_set_object (value, surface->scanout_candidate);
|
||||
+ break;
|
||||
+ default:
|
||||
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
+ object_class->get_property = meta_wayland_surface_get_property;
|
||||
+
|
||||
+ obj_props[PROP_SCANOUT_CANDIDATE] =
|
||||
+ g_param_spec_object ("scanout-candidate",
|
||||
+ "scanout-candidate",
|
||||
+ "Scanout candidate for given CRTC",
|
||||
+ META_TYPE_CRTC,
|
||||
+ G_PARAM_READABLE |
|
||||
+ G_PARAM_STATIC_STRINGS);
|
||||
+ g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
+
|
||||
surface_signals[SURFACE_DESTROY] =
|
||||
g_signal_new ("destroy",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
@@ -2104,3 +2146,21 @@ meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
|
||||
|
||||
return scanout;
|
||||
}
|
||||
+
|
||||
+MetaCrtc *
|
||||
+meta_wayland_surface_get_scanout_candidate (MetaWaylandSurface *surface)
|
||||
+{
|
||||
+ return surface->scanout_candidate;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
|
||||
+ MetaCrtc *crtc)
|
||||
+{
|
||||
+ if (surface->scanout_candidate == crtc)
|
||||
+ return;
|
||||
+
|
||||
+ g_set_object (&surface->scanout_candidate, crtc);
|
||||
+ g_object_notify_by_pspec (G_OBJECT (surface),
|
||||
+ obj_props[PROP_SCANOUT_CANDIDATE]);
|
||||
+}
|
||||
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
|
||||
index f0153b23b9..7e90cf095c 100644
|
||||
--- a/src/wayland/meta-wayland-surface.h
|
||||
+++ b/src/wayland/meta-wayland-surface.h
|
||||
@@ -247,6 +247,9 @@ struct _MetaWaylandSurface
|
||||
*/
|
||||
uint64_t sequence;
|
||||
} presentation_time;
|
||||
+
|
||||
+ /* dma-buf feedback */
|
||||
+ MetaCrtc *scanout_candidate;
|
||||
};
|
||||
|
||||
void meta_wayland_shell_init (MetaWaylandCompositor *compositor);
|
||||
@@ -362,6 +365,11 @@ int meta_wayland_surface_get_height (MetaWaylandSurface *surface
|
||||
CoglScanout * meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
|
||||
CoglOnscreen *onscreen);
|
||||
|
||||
+MetaCrtc * meta_wayland_surface_get_scanout_candidate (MetaWaylandSurface *surface);
|
||||
+
|
||||
+void meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
|
||||
+ MetaCrtc *crtc);
|
||||
+
|
||||
static inline GNode *
|
||||
meta_get_next_subsurface_sibling (GNode *n)
|
||||
{
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
From 2890b4a152f1efbc1492626a4ee055083cc40159 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Fri, 6 Aug 2021 17:07:21 +0200
|
||||
Subject: [PATCH 10/18] wayland/dma-buf: Move should_send_modifiers() to the
|
||||
top
|
||||
|
||||
It's very much an auxiliary method; lets move it to where it belongs,
|
||||
according to HACKING.md.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 4c54b36126a610c43b05f36f4aab33f302fdc021)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 39 ++++++++++++++++--------------
|
||||
1 file changed, 21 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index a255158993..c9e4671074 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -134,6 +134,27 @@ G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJE
|
||||
G_DEFINE_TYPE (MetaWaylandDmaBufManager, meta_wayland_dma_buf_manager,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
+static gboolean
|
||||
+should_send_modifiers (MetaBackend *backend)
|
||||
+{
|
||||
+ MetaSettings *settings = meta_backend_get_settings (backend);
|
||||
+
|
||||
+ if (meta_settings_is_experimental_feature_enabled (
|
||||
+ settings, META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS))
|
||||
+ return TRUE;
|
||||
+
|
||||
+#ifdef HAVE_NATIVE_BACKEND
|
||||
+ if (META_IS_BACKEND_NATIVE (backend))
|
||||
+ {
|
||||
+ MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
+ MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||
+ return meta_renderer_native_use_modifiers (renderer_native);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
static gint
|
||||
compare_tranches (gconstpointer a,
|
||||
gconstpointer b)
|
||||
@@ -861,24 +882,6 @@ static const struct zwp_linux_dmabuf_v1_interface dma_buf_implementation =
|
||||
dma_buf_handle_get_surface_feedback,
|
||||
};
|
||||
|
||||
-static gboolean
|
||||
-should_send_modifiers (MetaBackend *backend)
|
||||
-{
|
||||
- MetaSettings *settings = meta_backend_get_settings (backend);
|
||||
-
|
||||
-#ifdef HAVE_NATIVE_BACKEND
|
||||
- if (META_IS_BACKEND_NATIVE (backend))
|
||||
- {
|
||||
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
- MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||
- return meta_renderer_native_use_modifiers (renderer_native);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- return meta_settings_is_experimental_feature_enabled (
|
||||
- settings, META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS);
|
||||
-}
|
||||
-
|
||||
static void
|
||||
send_modifiers (struct wl_resource *resource,
|
||||
MetaWaylandDmaBufFormat *format,
|
||||
--
|
||||
2.51.1
|
||||
|
||||
378
0011-wayland-dma-buf-Add-support-for-scanout-surface-feed.patch
Normal file
378
0011-wayland-dma-buf-Add-support-for-scanout-surface-feed.patch
Normal file
@ -0,0 +1,378 @@
|
||||
From 6bb16eb5ac7f70b42533b189a4928f29d0fbc768 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Fri, 6 Aug 2021 17:04:18 +0200
|
||||
Subject: [PATCH 11/18] wayland/dma-buf: Add support for scanout surface
|
||||
feedback
|
||||
|
||||
Whenever a surface is promoted as a scanout candidate by
|
||||
MetaCompositorNative, it'll get a CRTC set as the candidate CRTC.
|
||||
|
||||
When a client asks for DMA buffer surface feedback, use this property to
|
||||
determine whether we should send a scanout feedback tranche.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
|
||||
(cherry picked from commit 64e6bedb6bcd6cedc8439c6848003991906c9c80)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 287 ++++++++++++++++++++++++++++-
|
||||
1 file changed, 284 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index c9e4671074..385012f1ab 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -95,6 +95,7 @@ typedef struct _MetaWaylandDmaBufTranche
|
||||
dev_t target_device_id;
|
||||
GArray *formats;
|
||||
MetaWaylandDmaBufTrancheFlags flags;
|
||||
+ uint64_t scanout_crtc_id;
|
||||
} MetaWaylandDmaBufTranche;
|
||||
|
||||
typedef struct _MetaWaylandDmaBufFeedback
|
||||
@@ -103,6 +104,15 @@ typedef struct _MetaWaylandDmaBufFeedback
|
||||
GList *tranches;
|
||||
} MetaWaylandDmaBufFeedback;
|
||||
|
||||
+typedef struct _MetaWaylandDmaBufSurfaceFeedback
|
||||
+{
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager;
|
||||
+ MetaWaylandSurface *surface;
|
||||
+ MetaWaylandDmaBufFeedback *feedback;
|
||||
+ GList *resources;
|
||||
+ gulong scanout_candidate_changed_id;
|
||||
+} MetaWaylandDmaBufSurfaceFeedback;
|
||||
+
|
||||
struct _MetaWaylandDmaBufManager
|
||||
{
|
||||
GObject parent;
|
||||
@@ -134,6 +144,8 @@ G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJE
|
||||
G_DEFINE_TYPE (MetaWaylandDmaBufManager, meta_wayland_dma_buf_manager,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
+static GQuark quark_dma_buf_surface_feedback;
|
||||
+
|
||||
static gboolean
|
||||
should_send_modifiers (MetaBackend *backend)
|
||||
{
|
||||
@@ -194,6 +206,15 @@ meta_wayland_dma_buf_tranche_free (MetaWaylandDmaBufTranche *tranche)
|
||||
g_free (tranche);
|
||||
}
|
||||
|
||||
+static MetaWaylandDmaBufTranche *
|
||||
+meta_wayland_dma_buf_tranche_copy (MetaWaylandDmaBufTranche *tranche)
|
||||
+{
|
||||
+ return meta_wayland_dma_buf_tranche_new (tranche->target_device_id,
|
||||
+ tranche->formats,
|
||||
+ tranche->priority,
|
||||
+ tranche->flags);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_wayland_dma_buf_tranche_send (MetaWaylandDmaBufTranche *tranche,
|
||||
struct wl_resource *resource)
|
||||
@@ -285,6 +306,20 @@ meta_wayland_dma_buf_feedback_free (MetaWaylandDmaBufFeedback *feedback)
|
||||
g_free (feedback);
|
||||
}
|
||||
|
||||
+static MetaWaylandDmaBufFeedback *
|
||||
+meta_wayland_dma_buf_feedback_copy (MetaWaylandDmaBufFeedback *feedback)
|
||||
+{
|
||||
+ MetaWaylandDmaBufFeedback *new_feedback;
|
||||
+
|
||||
+ new_feedback = meta_wayland_dma_buf_feedback_new (feedback->main_device_id);
|
||||
+ new_feedback->tranches =
|
||||
+ g_list_copy_deep (feedback->tranches,
|
||||
+ (GCopyFunc) meta_wayland_dma_buf_tranche_copy,
|
||||
+ NULL);
|
||||
+
|
||||
+ return new_feedback;
|
||||
+}
|
||||
+
|
||||
static gboolean
|
||||
meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
|
||||
GError **error)
|
||||
@@ -848,6 +883,242 @@ dma_buf_handle_get_default_feedback (struct wl_client *client,
|
||||
feedback_resource);
|
||||
}
|
||||
|
||||
+#ifdef HAVE_NATIVE_BACKEND
|
||||
+static int
|
||||
+find_scanout_tranche_func (gconstpointer a,
|
||||
+ gconstpointer b)
|
||||
+{
|
||||
+ const MetaWaylandDmaBufTranche *tranche = a;
|
||||
+
|
||||
+ if (tranche->scanout_crtc_id)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+has_modifier (GArray *modifiers,
|
||||
+ uint64_t drm_modifier)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < modifiers->len; i++)
|
||||
+ {
|
||||
+ if (drm_modifier == g_array_index (modifiers, uint64_t, i))
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+crtc_supports_modifier (MetaCrtcKms *crtc_kms,
|
||||
+ uint32_t drm_format,
|
||||
+ uint64_t drm_modifier)
|
||||
+{
|
||||
+ GArray *crtc_modifiers;
|
||||
+
|
||||
+ crtc_modifiers = meta_crtc_kms_get_modifiers (crtc_kms, drm_format);
|
||||
+ if (!crtc_modifiers)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return has_modifier (crtc_modifiers, drm_modifier);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ensure_scanout_tranche (MetaWaylandDmaBufSurfaceFeedback *surface_feedback,
|
||||
+ MetaCrtc *crtc)
|
||||
+{
|
||||
+ MetaWaylandDmaBufManager *dma_buf_manager = surface_feedback->dma_buf_manager;
|
||||
+ MetaWaylandDmaBufFeedback *feedback = surface_feedback->feedback;
|
||||
+ MetaCrtcKms *crtc_kms;
|
||||
+ MetaWaylandDmaBufTranche *tranche;
|
||||
+ GList *el;
|
||||
+ int i;
|
||||
+ g_autoptr (GArray) formats = NULL;
|
||||
+ MetaWaylandDmaBufTranchePriority priority;
|
||||
+ MetaWaylandDmaBufTrancheFlags flags;
|
||||
+
|
||||
+ g_return_if_fail (META_IS_CRTC_KMS (crtc));
|
||||
+ crtc_kms = META_CRTC_KMS (crtc);
|
||||
+
|
||||
+ el = g_list_find_custom (feedback->tranches, NULL, find_scanout_tranche_func);
|
||||
+ if (el)
|
||||
+ {
|
||||
+ tranche = el->data;
|
||||
+
|
||||
+ if (tranche->scanout_crtc_id == meta_crtc_get_id (crtc))
|
||||
+ return;
|
||||
+
|
||||
+ meta_wayland_dma_buf_tranche_free (tranche);
|
||||
+ feedback->tranches = g_list_delete_link (feedback->tranches, el);
|
||||
+ }
|
||||
+
|
||||
+ formats = g_array_new (FALSE, FALSE, sizeof (MetaWaylandDmaBufFormat));
|
||||
+ if (should_send_modifiers (meta_get_backend ()))
|
||||
+ {
|
||||
+ for (i = 0; i < dma_buf_manager->formats->len; i++)
|
||||
+ {
|
||||
+ MetaWaylandDmaBufFormat format =
|
||||
+ g_array_index (dma_buf_manager->formats,
|
||||
+ MetaWaylandDmaBufFormat,
|
||||
+ i);
|
||||
+
|
||||
+ if (!crtc_supports_modifier (crtc_kms,
|
||||
+ format.drm_format,
|
||||
+ format.drm_modifier))
|
||||
+ continue;
|
||||
+
|
||||
+ g_array_append_val (formats, format);
|
||||
+ }
|
||||
+
|
||||
+ if (formats->len == 0)
|
||||
+ return;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ for (i = 0; i < dma_buf_manager->formats->len; i++)
|
||||
+ {
|
||||
+ MetaWaylandDmaBufFormat format =
|
||||
+ g_array_index (dma_buf_manager->formats,
|
||||
+ MetaWaylandDmaBufFormat,
|
||||
+ i);
|
||||
+
|
||||
+ if (format.drm_modifier != DRM_FORMAT_MOD_INVALID)
|
||||
+ continue;
|
||||
+
|
||||
+ if (!meta_crtc_kms_get_modifiers (crtc_kms, format.drm_format))
|
||||
+ continue;
|
||||
+
|
||||
+ g_array_append_val (formats, format);
|
||||
+ }
|
||||
+
|
||||
+ if (formats->len == 0)
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ priority = META_WAYLAND_DMA_BUF_TRANCHE_PRIORITY_HIGH;
|
||||
+ flags = META_WAYLAND_DMA_BUF_TRANCHE_FLAG_SCANOUT;
|
||||
+ tranche = meta_wayland_dma_buf_tranche_new (feedback->main_device_id,
|
||||
+ formats,
|
||||
+ priority,
|
||||
+ flags);
|
||||
+ tranche->scanout_crtc_id = meta_crtc_get_id (crtc);
|
||||
+ meta_wayland_dma_buf_feedback_add_tranche (feedback, tranche);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+clear_scanout_tranche (MetaWaylandDmaBufSurfaceFeedback *surface_feedback)
|
||||
+{
|
||||
+ MetaWaylandDmaBufFeedback *feedback = surface_feedback->feedback;
|
||||
+ MetaWaylandDmaBufTranche *tranche;
|
||||
+ GList *el;
|
||||
+
|
||||
+ el = g_list_find_custom (feedback->tranches, NULL, find_scanout_tranche_func);
|
||||
+ if (!el)
|
||||
+ return;
|
||||
+
|
||||
+ tranche = el->data;
|
||||
+ meta_wayland_dma_buf_tranche_free (tranche);
|
||||
+ feedback->tranches = g_list_delete_link (feedback->tranches, el);
|
||||
+}
|
||||
+#endif /* HAVE_NATIVE_BACKEND */
|
||||
+
|
||||
+static void
|
||||
+update_surface_feedback_tranches (MetaWaylandDmaBufSurfaceFeedback *surface_feedback)
|
||||
+{
|
||||
+#ifdef HAVE_NATIVE_BACKEND
|
||||
+ MetaCrtc *crtc;
|
||||
+
|
||||
+ crtc = meta_wayland_surface_get_scanout_candidate (surface_feedback->surface);
|
||||
+ if (crtc)
|
||||
+ ensure_scanout_tranche (surface_feedback, crtc);
|
||||
+ else
|
||||
+ clear_scanout_tranche (surface_feedback);
|
||||
+#endif /* HAVE_NATIVE_BACKEND */
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+on_scanout_candidate_changed (MetaWaylandSurface *surface,
|
||||
+ GParamSpec *pspec,
|
||||
+ MetaWaylandDmaBufSurfaceFeedback *surface_feedback)
|
||||
+{
|
||||
+ GList *l;
|
||||
+
|
||||
+ update_surface_feedback_tranches (surface_feedback);
|
||||
+
|
||||
+ for (l = surface_feedback->resources; l; l = l->next)
|
||||
+ {
|
||||
+ struct wl_resource *resource = l->data;
|
||||
+
|
||||
+ meta_wayland_dma_buf_feedback_send (surface_feedback->feedback,
|
||||
+ surface_feedback->dma_buf_manager,
|
||||
+ resource);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+surface_feedback_surface_destroyed_cb (gpointer user_data)
|
||||
+{
|
||||
+ MetaWaylandDmaBufSurfaceFeedback *surface_feedback = user_data;
|
||||
+
|
||||
+ g_list_foreach (surface_feedback->resources,
|
||||
+ (GFunc) wl_resource_set_user_data,
|
||||
+ NULL);
|
||||
+ g_list_free (surface_feedback->resources);
|
||||
+
|
||||
+ g_free (surface_feedback);
|
||||
+}
|
||||
+
|
||||
+static MetaWaylandDmaBufSurfaceFeedback *
|
||||
+ensure_surface_feedback (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
+ MetaWaylandSurface *surface)
|
||||
+{
|
||||
+ MetaWaylandDmaBufSurfaceFeedback *surface_feedback;
|
||||
+
|
||||
+ surface_feedback = g_object_get_qdata (G_OBJECT (surface),
|
||||
+ quark_dma_buf_surface_feedback);
|
||||
+ if (surface_feedback)
|
||||
+ return surface_feedback;
|
||||
+
|
||||
+ surface_feedback = g_new0 (MetaWaylandDmaBufSurfaceFeedback, 1);
|
||||
+ surface_feedback->dma_buf_manager = dma_buf_manager;
|
||||
+ surface_feedback->surface = surface;
|
||||
+ surface_feedback->feedback =
|
||||
+ meta_wayland_dma_buf_feedback_copy (dma_buf_manager->default_feedback);
|
||||
+
|
||||
+ surface_feedback->scanout_candidate_changed_id =
|
||||
+ g_signal_connect (surface, "notify::scanout-candidate",
|
||||
+ G_CALLBACK (on_scanout_candidate_changed),
|
||||
+ surface_feedback);
|
||||
+
|
||||
+ g_object_set_qdata_full (G_OBJECT (surface),
|
||||
+ quark_dma_buf_surface_feedback,
|
||||
+ surface_feedback,
|
||||
+ surface_feedback_surface_destroyed_cb);
|
||||
+
|
||||
+ return surface_feedback;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+surface_feedback_destructor (struct wl_resource *resource)
|
||||
+{
|
||||
+ MetaWaylandDmaBufSurfaceFeedback *surface_feedback =
|
||||
+
|
||||
+ surface_feedback = wl_resource_get_user_data (resource);
|
||||
+ if (!surface_feedback)
|
||||
+ return;
|
||||
+
|
||||
+ surface_feedback->resources = g_list_remove (surface_feedback->resources,
|
||||
+ resource);
|
||||
+ if (!surface_feedback->resources)
|
||||
+ {
|
||||
+ g_clear_signal_handler (&surface_feedback->scanout_candidate_changed_id,
|
||||
+ surface_feedback->surface);
|
||||
+ g_object_set_qdata (G_OBJECT (surface_feedback->surface),
|
||||
+ quark_dma_buf_surface_feedback, NULL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
dma_buf_handle_get_surface_feedback (struct wl_client *client,
|
||||
struct wl_resource *dma_buf_resource,
|
||||
@@ -856,8 +1127,13 @@ dma_buf_handle_get_surface_feedback (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandDmaBufManager *dma_buf_manager =
|
||||
wl_resource_get_user_data (dma_buf_resource);
|
||||
+ MetaWaylandSurface *surface =
|
||||
+ wl_resource_get_user_data (surface_resource);
|
||||
+ MetaWaylandDmaBufSurfaceFeedback *surface_feedback;
|
||||
struct wl_resource *feedback_resource;
|
||||
|
||||
+ surface_feedback = ensure_surface_feedback (dma_buf_manager, surface);
|
||||
+
|
||||
feedback_resource =
|
||||
wl_resource_create (client,
|
||||
&zwp_linux_dmabuf_feedback_v1_interface,
|
||||
@@ -866,10 +1142,12 @@ dma_buf_handle_get_surface_feedback (struct wl_client *client,
|
||||
|
||||
wl_resource_set_implementation (feedback_resource,
|
||||
&feedback_implementation,
|
||||
- NULL,
|
||||
- feedback_destructor);
|
||||
+ surface_feedback,
|
||||
+ surface_feedback_destructor);
|
||||
+ surface_feedback->resources = g_list_prepend (surface_feedback->resources,
|
||||
+ feedback_resource);
|
||||
|
||||
- meta_wayland_dma_buf_feedback_send (dma_buf_manager->default_feedback,
|
||||
+ meta_wayland_dma_buf_feedback_send (surface_feedback->feedback,
|
||||
dma_buf_manager,
|
||||
feedback_resource);
|
||||
}
|
||||
@@ -1254,6 +1532,9 @@ meta_wayland_dma_buf_manager_class_init (MetaWaylandDmaBufManagerClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_wayland_dma_buf_manager_finalize;
|
||||
+
|
||||
+ quark_dma_buf_surface_feedback =
|
||||
+ g_quark_from_static_string ("-meta-wayland-dma-buf-surface-feedback");
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
2.51.1
|
||||
|
||||
30
0012-wayland-dma-buf-Add-missing-wl_array_release.patch
Normal file
30
0012-wayland-dma-buf-Add-missing-wl_array_release.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 405673317976d578d7b228f4ab5ceea0e1366d99 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Mader <robert.mader@collabora.com>
|
||||
Date: Tue, 15 Feb 2022 20:56:27 +0100
|
||||
Subject: [PATCH 12/18] wayland/dma-buf: Add missing wl_array_release()
|
||||
|
||||
So we don't leak the array.
|
||||
|
||||
Fixes 7acecb1c7233dad0b9b314f59121882a518901d7
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2297>
|
||||
(cherry picked from commit 5b9abecc1bbe6acf8f65f976c660d5eefead16d8)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index 385012f1ab..4e21632159 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -271,6 +271,7 @@ meta_wayland_dma_buf_feedback_send (MetaWaylandDmaBufFeedback *feedback,
|
||||
device_id_ptr = wl_array_add (&main_device_buf, sizeof (*device_id_ptr));
|
||||
*device_id_ptr = feedback->main_device_id;
|
||||
zwp_linux_dmabuf_feedback_v1_send_main_device (resource, &main_device_buf);
|
||||
+ wl_array_release (&main_device_buf);
|
||||
|
||||
g_list_foreach (feedback->tranches,
|
||||
(GFunc) meta_wayland_dma_buf_tranche_send,
|
||||
--
|
||||
2.51.1
|
||||
|
||||
29
0013-wayland-dma-buf-Fix-typos-in-struct-name.patch
Normal file
29
0013-wayland-dma-buf-Fix-typos-in-struct-name.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From 70ff9d15f67dc88b6d81f794e8bb35820c23dfc2 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Mader <robert.mader@collabora.com>
|
||||
Date: Tue, 15 Feb 2022 21:31:06 +0100
|
||||
Subject: [PATCH 13/18] wayland/dma-buf: Fix typos in struct name
|
||||
|
||||
Fixes 7acecb1c7233dad0b9b314f59121882a518901d7
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2297>
|
||||
(cherry picked from commit 8f91d831ee20b9c73036561ee1b57bf9f5efef65)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index 4e21632159..f28070da80 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -1281,7 +1281,7 @@ add_fallback:
|
||||
*
|
||||
* [ 32 bit format ][ 32 bit padding ][ 64 bit modifier ]
|
||||
*/
|
||||
-typedef struct _MetaMetaWaylanDmaBdufFormatEntry
|
||||
+typedef struct _MetaWaylandDmaBufFormatEntry
|
||||
{
|
||||
uint32_t drm_format;
|
||||
uint32_t unused_padding;
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From ba94be928ecf77bd202bd57bbcc5dc5dffb4aee5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <mdaenzer@redhat.com>
|
||||
Date: Thu, 16 Jun 2022 12:17:36 +0200
|
||||
Subject: [PATCH 14/18] wayland/dma-buf: Free feedback in
|
||||
surface_feedback_surface_destroyed_cb
|
||||
|
||||
Fixes leak:
|
||||
|
||||
==14889== 2,168 (16 direct, 2,152 indirect) bytes in 1 blocks are definitely lost in loss record 15,308 of 15,584
|
||||
==14889== at 0x48445EF: calloc (vg_replace_malloc.c:1328)
|
||||
==14889== by 0x4BAC1D0: g_malloc0 (gmem.c:155)
|
||||
==14889== by 0x4AAFF60: meta_wayland_dma_buf_feedback_new (meta-wayland-dma-buf.c:298)
|
||||
==14889== by 0x4AAFFE0: meta_wayland_dma_buf_feedback_copy (meta-wayland-dma-buf.c:317)
|
||||
==14889== by 0x4AB16B6: ensure_surface_feedback (meta-wayland-dma-buf.c:1121)
|
||||
==14889== by 0x4AB1848: dma_buf_handle_get_surface_feedback (meta-wayland-dma-buf.c:1169)
|
||||
==14889== by 0x66F77E9: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0)
|
||||
==14889== by 0x66F6922: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0)
|
||||
==14889== by 0x5318750: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-server.so.0.20.0)
|
||||
==14889== by 0x5313B99: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-server.so.0.20.0)
|
||||
==14889== by 0x5316649: wl_event_loop_dispatch (in /usr/lib/x86_64-linux-gnu/libwayland-server.so.0.20.0)
|
||||
==14889== by 0x4AA7C19: wayland_event_source_dispatch (meta-wayland.c:110)
|
||||
|
||||
Fixes: 64e6bedb6bcd ("wayland/dma-buf: Add support for scanout surface feedback")
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2469>
|
||||
(cherry picked from commit 4af54225de3a653e7b44ab1905b64ebddf57da4a)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index f28070da80..3a1d92ecf6 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -1067,6 +1067,8 @@ surface_feedback_surface_destroyed_cb (gpointer user_data)
|
||||
NULL);
|
||||
g_list_free (surface_feedback->resources);
|
||||
|
||||
+ meta_wayland_dma_buf_feedback_free (surface_feedback->feedback);
|
||||
+
|
||||
g_free (surface_feedback);
|
||||
}
|
||||
|
||||
--
|
||||
2.51.1
|
||||
|
||||
144
0015-wayland-dma-buf-Only-advertise-supported-formats.patch
Normal file
144
0015-wayland-dma-buf-Only-advertise-supported-formats.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From 43feafa1c2c061acb226a8df0a6b6a1f5a9b1ba0 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Mader <robert.mader@posteo.de>
|
||||
Date: Mon, 25 Apr 2022 18:00:50 +0200
|
||||
Subject: [PATCH 15/18] wayland/dma-buf: Only advertise supported formats
|
||||
|
||||
Analogous to how we use `eglQueryDmaBufModifiersEXT()` to query
|
||||
supported modifiers, use `eglQueryDmaBufFormatsEXT()` to ensure
|
||||
we only advertise formats supported by both the compositor and the
|
||||
driver.
|
||||
|
||||
If there is no overlap, don't advertise `zwp_linux_dmabuf_v1` at
|
||||
all.
|
||||
|
||||
Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/2238
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2386>
|
||||
(cherry picked from commit c8095b430689365c5cdd4646c54de4b07a0da7ee)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 89 +++++++++++++++++++++++-------
|
||||
1 file changed, 69 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index 3a1d92ecf6..145fd0cdab 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -1317,28 +1317,71 @@ init_format_table (MetaWaylandDmaBufManager *dma_buf_manager)
|
||||
meta_anonymous_file_new (size, (uint8_t *) format_table);
|
||||
}
|
||||
|
||||
-static void
|
||||
-init_formats (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
- EGLDisplay egl_display)
|
||||
+static EGLint supported_formats[] = {
|
||||
+ DRM_FORMAT_ARGB8888,
|
||||
+ DRM_FORMAT_ABGR8888,
|
||||
+ DRM_FORMAT_XRGB8888,
|
||||
+ DRM_FORMAT_XBGR8888,
|
||||
+ DRM_FORMAT_ARGB2101010,
|
||||
+ DRM_FORMAT_ABGR2101010,
|
||||
+ DRM_FORMAT_XRGB2101010,
|
||||
+ DRM_FORMAT_XBGR2101010,
|
||||
+ DRM_FORMAT_RGB565,
|
||||
+ DRM_FORMAT_ABGR16161616F,
|
||||
+ DRM_FORMAT_XBGR16161616F,
|
||||
+ DRM_FORMAT_XRGB16161616F,
|
||||
+ DRM_FORMAT_ARGB16161616F
|
||||
+};
|
||||
+
|
||||
+static gboolean
|
||||
+init_formats (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
+ EGLDisplay egl_display,
|
||||
+ GError **error)
|
||||
{
|
||||
+ MetaBackend *backend = meta_get_backend ();
|
||||
+ MetaEgl *egl = meta_backend_get_egl (backend);
|
||||
+ EGLint num_formats;
|
||||
+ g_autofree EGLint *driver_formats = NULL;
|
||||
+ int i, j;
|
||||
+
|
||||
dma_buf_manager->formats = g_array_new (FALSE, FALSE,
|
||||
sizeof (MetaWaylandDmaBufFormat));
|
||||
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB8888);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR8888);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB8888);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR8888);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB2101010);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR2101010);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB2101010);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR2101010);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_RGB565);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR16161616F);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR16161616F);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB16161616F);
|
||||
- add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB16161616F);
|
||||
+ if (!meta_egl_query_dma_buf_formats (egl, egl_display, 0, NULL, &num_formats,
|
||||
+ error))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (num_formats == 0)
|
||||
+ {
|
||||
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
+ "EGL doesn't support any DRM formats");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ driver_formats = g_new0 (EGLint, num_formats);
|
||||
+ if (!meta_egl_query_dma_buf_formats (egl, egl_display, num_formats,
|
||||
+ driver_formats, &num_formats, error))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ for (i = 0; i < G_N_ELEMENTS (supported_formats); i++)
|
||||
+ {
|
||||
+ for (j = 0; j < num_formats; j++)
|
||||
+ {
|
||||
+ if (supported_formats[i] == driver_formats[j])
|
||||
+ add_format (dma_buf_manager, egl_display, supported_formats[i]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (dma_buf_manager->formats->len == 0)
|
||||
+ {
|
||||
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
+ "EGL doesn't support any DRM formats supported by the "
|
||||
+ "compositor");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
init_format_table (dma_buf_manager);
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1460,6 +1503,16 @@ initialize:
|
||||
|
||||
dma_buf_manager = g_object_new (META_TYPE_WAYLAND_DMA_BUF_MANAGER, NULL);
|
||||
|
||||
+ dma_buf_manager->compositor = compositor;
|
||||
+ dma_buf_manager->main_device_id = device_id;
|
||||
+
|
||||
+ if (!init_formats (dma_buf_manager, egl_display, &local_error))
|
||||
+ {
|
||||
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
+ "No supported formats detected: %s", local_error->message);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
if (!wl_global_create (compositor->wayland_display,
|
||||
&zwp_linux_dmabuf_v1_interface,
|
||||
protocol_version,
|
||||
@@ -1471,10 +1524,6 @@ initialize:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- dma_buf_manager->compositor = compositor;
|
||||
- dma_buf_manager->main_device_id = device_id;
|
||||
-
|
||||
- init_formats (dma_buf_manager, egl_display);
|
||||
init_default_feedback (dma_buf_manager);
|
||||
|
||||
return g_steal_pointer (&dma_buf_manager);
|
||||
--
|
||||
2.51.1
|
||||
|
||||
29
0016-wayland-dma-buf-Remove-redundant-error-check.patch
Normal file
29
0016-wayland-dma-buf-Remove-redundant-error-check.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From d7bf34fc6d9b9dd876c665c9e8b84270de86e34e Mon Sep 17 00:00:00 2001
|
||||
From: Robert Mader <robert.mader@posteo.de>
|
||||
Date: Tue, 26 Apr 2022 20:27:57 +0200
|
||||
Subject: [PATCH 16/18] wayland/dma-buf: Remove redundant error check
|
||||
|
||||
`meta_egl_*` functions are assumed to set an error on failure.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2386>
|
||||
(cherry picked from commit aa8d2d6fffbcb4ccf16ff527311e101fa75d4d3c)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index 145fd0cdab..c59b767b4c 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -1252,7 +1252,7 @@ add_format (MetaWaylandDmaBufManager *dma_buf_manager,
|
||||
&num_modifiers, &error))
|
||||
{
|
||||
g_warning ("Failed to query modifiers for format 0x%" PRIu32 ": %s",
|
||||
- drm_format, error ? error->message : "unknown error");
|
||||
+ drm_format, error->message);
|
||||
goto add_fallback;
|
||||
}
|
||||
|
||||
--
|
||||
2.51.1
|
||||
|
||||
34
0017-egl-Don-t-set-an-error-when-there-is-none.patch
Normal file
34
0017-egl-Don-t-set-an-error-when-there-is-none.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 6e6a88f95e6fae313601fc83e3f3b7e61628e4e0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Wed, 12 Jan 2022 14:02:25 +0100
|
||||
Subject: [PATCH 17/18] egl: Don't set an error when there is none
|
||||
|
||||
Some API will return NULL or the equivalent; sometimes it's an error,
|
||||
and sometimes it's not, and the way to check that is by looking at the
|
||||
return value of eglGetError(). When we check this, don't set the GError
|
||||
if it returned EGL_SUCCESS, as that indicates that the return value is
|
||||
expected behavior, and not an error.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2151>
|
||||
(cherry picked from commit 719a6c0006ed5e982b283c9a616973600db8c7f7)
|
||||
---
|
||||
src/backends/meta-egl.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c
|
||||
index c2777271ff..3b6e4b399e 100644
|
||||
--- a/src/backends/meta-egl.c
|
||||
+++ b/src/backends/meta-egl.c
|
||||
@@ -158,6 +158,9 @@ set_egl_error (GError **error)
|
||||
return;
|
||||
|
||||
error_number = eglGetError ();
|
||||
+ if (error_number == EGL_SUCCESS)
|
||||
+ return;
|
||||
+
|
||||
error_str = get_egl_error_str (error_number);
|
||||
g_set_error_literal (error, META_EGL_ERROR,
|
||||
error_number,
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
From b61fc8eb57186dd4fb2f83383f69673a06b0104c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Wed, 12 Jan 2022 12:11:01 +0100
|
||||
Subject: [PATCH 18/18] wayland/dma-buf: Don't warn if there was no render node
|
||||
|
||||
When running in KVM, the EGL driver supports querying the render node
|
||||
path, but it returns NULL. Handle that better by falling back to
|
||||
querying the device main device file, instead of falling back on v3 of
|
||||
the protocol and logging a warning.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2151>
|
||||
(cherry picked from commit a2382f325117dbfc4dede55f72fc5b9942c3ffb9)
|
||||
---
|
||||
src/wayland/meta-wayland-dma-buf.c | 33 +++++++++++++++++-------------
|
||||
1 file changed, 19 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
|
||||
index c59b767b4c..75b0bbe858 100644
|
||||
--- a/src/wayland/meta-wayland-dma-buf.c
|
||||
+++ b/src/wayland/meta-wayland-dma-buf.c
|
||||
@@ -1459,29 +1459,34 @@ meta_wayland_dma_buf_manager_new (MetaWaylandCompositor *compositor,
|
||||
device_path = meta_egl_query_device_string (egl, egl_device,
|
||||
EGL_DRM_RENDER_NODE_FILE_EXT,
|
||||
&local_error);
|
||||
+ if (local_error)
|
||||
+ {
|
||||
+ g_warning ("Failed to query EGL render node path: %s",
|
||||
+ local_error->message);
|
||||
+ g_clear_error (&local_error);
|
||||
+ }
|
||||
}
|
||||
- else if (meta_egl_egl_device_has_extensions (egl, egl_device, NULL,
|
||||
- "EGL_EXT_device_drm",
|
||||
- NULL))
|
||||
+
|
||||
+ if (!device_path &&
|
||||
+ meta_egl_egl_device_has_extensions (egl, egl_device, NULL,
|
||||
+ "EGL_EXT_device_drm",
|
||||
+ NULL))
|
||||
{
|
||||
device_path = meta_egl_query_device_string (egl, egl_device,
|
||||
EGL_DRM_DEVICE_FILE_EXT,
|
||||
&local_error);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- meta_topic (META_DEBUG_WAYLAND,
|
||||
- "Only advertising zwp_linux_dmabuf_v1 interface version 3 "
|
||||
- "support, missing 'EGL_EXT_device_drm' and "
|
||||
- "'EGL_EXT_device_drm_render_node'");
|
||||
- protocol_version = 3;
|
||||
- goto initialize;
|
||||
+ if (local_error)
|
||||
+ {
|
||||
+ g_warning ("Failed to query EGL render node path: %s",
|
||||
+ local_error->message);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!device_path)
|
||||
{
|
||||
- g_warning ("Failed to query EGL device path: %s",
|
||||
- local_error->message);
|
||||
+ meta_topic (META_DEBUG_WAYLAND,
|
||||
+ "Only advertising zwp_linux_dmabuf_v1 interface version 3 "
|
||||
+ "support, no suitable device path could be found");
|
||||
protocol_version = 3;
|
||||
goto initialize;
|
||||
}
|
||||
--
|
||||
2.51.1
|
||||
|
||||
29
mutter.spec
29
mutter.spec
@ -10,7 +10,7 @@
|
||||
|
||||
Name: mutter
|
||||
Version: 40.9
|
||||
Release: 30%{?dist}
|
||||
Release: 31%{?dist}
|
||||
Summary: Window and compositing manager based on Clutter
|
||||
|
||||
License: GPLv2+
|
||||
@ -170,6 +170,26 @@ Patch73: 0001-compositor-x11-sync-again-at-the-end-of-before_paint.patch
|
||||
# RHEL-113246
|
||||
Patch74: 0001-compositor-sync-ring-Allow-the-gpu_fence-to-be-moved.patch
|
||||
|
||||
# RHEL-129832 - linux_dmabuf v4 support.
|
||||
Patch75: 0001-egl-Add-eglQueryDisplayAttribEXT-helper.patch
|
||||
Patch76: 0002-wayland-dma-buf-Add-manager-struct.patch
|
||||
Patch77: 0003-wayland-dma-buf-Prepare-format-modifier-map-up-front.patch
|
||||
Patch78: 0004-wayland-dma-buf-Add-basic-support-for-DMA-buffer-fee.patch
|
||||
Patch79: 0005-wayland-dma-buf-Always-advertise-non-modifier-fallba.patch
|
||||
Patch80: 0006-wayland-surface-Remove-unnecessary-NULL-check.patch
|
||||
Patch81: 0007-wayland-dma-buf-Make-manager-object-a-GObject.patch
|
||||
Patch82: 0008-wayland-dma-buf-Add-tranche-priorities.patch
|
||||
Patch83: 0009-compositor-native-Track-what-Wayland-surface-is-a-sc.patch
|
||||
Patch84: 0010-wayland-dma-buf-Move-should_send_modifiers-to-the-to.patch
|
||||
Patch85: 0011-wayland-dma-buf-Add-support-for-scanout-surface-feed.patch
|
||||
Patch86: 0012-wayland-dma-buf-Add-missing-wl_array_release.patch
|
||||
Patch87: 0013-wayland-dma-buf-Fix-typos-in-struct-name.patch
|
||||
Patch88: 0014-wayland-dma-buf-Free-feedback-in-surface_feedback_su.patch
|
||||
Patch89: 0015-wayland-dma-buf-Only-advertise-supported-formats.patch
|
||||
Patch90: 0016-wayland-dma-buf-Remove-redundant-error-check.patch
|
||||
Patch91: 0017-egl-Don-t-set-an-error-when-there-is-none.patch
|
||||
Patch92: 0018-wayland-dma-buf-Don-t-warn-if-there-was-no-render-no.patch
|
||||
|
||||
# RHEL-70872
|
||||
Patch533: 0001-x11-iconcache-Turn-icons-from-WM_HINTS-pixmaps-to-ca.patch
|
||||
|
||||
@ -224,7 +244,7 @@ BuildRequires: pkgconfig(libdrm)
|
||||
BuildRequires: pkgconfig(gbm)
|
||||
BuildRequires: pkgconfig(wayland-server)
|
||||
BuildRequires: pkgconfig(wayland-eglstream)
|
||||
BuildRequires: pkgconfig(wayland-protocols)
|
||||
BuildRequires: pkgconfig(wayland-protocols) >= 1.24
|
||||
|
||||
BuildRequires: json-glib-devel >= %{json_glib_version}
|
||||
BuildRequires: libgudev1-devel
|
||||
@ -320,6 +340,11 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop
|
||||
%{_datadir}/mutter-%{mutter_api_version}/tests
|
||||
|
||||
%changelog
|
||||
* Thu Nov 20 2025 Olivier Fourdan <ofourdan@redhat.com> - 40.9-31
|
||||
- Backport linux-dmabuf v4 support to restore hardware acceleration
|
||||
in Xwayland 24.1 with Mesa 25.2
|
||||
Resolves: RHEL-129832
|
||||
|
||||
* Mon Nov 10 2025 Jonas Ådahl <jadahl@redhat.com> - 40.9-30
|
||||
- Fix handling of more WM_HINTS window icon types
|
||||
Resolves: RHEL-70872
|
||||
|
||||
Loading…
Reference in New Issue
Block a user