summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Shafer <ashafer@nvidia.com>2022-12-20 12:15:34 +0100
committerMichel Dänzer <michel@daenzer.net>2023-01-20 17:56:54 +0000
commitd2e107b260a87e577827ef02c4970a33cb95cc92 (patch)
treea0b72e760686c6e265e72305b8ee9d6f7386d06b
parent9f348077521a28272d79117eb06476f666419f32 (diff)
xwayland: Add get_drawable_modifiers implementation
This reads from the format list, which is not yet filled in. Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
-rw-r--r--hw/xwayland/xwayland-glamor-eglstream.c2
-rw-r--r--hw/xwayland/xwayland-glamor-gbm.c2
-rw-r--r--hw/xwayland/xwayland-glamor.c109
-rw-r--r--hw/xwayland/xwayland-glamor.h2
-rw-r--r--hw/xwayland/xwayland-window.h1
5 files changed, 102 insertions, 14 deletions
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 04541bfc9..c911ed987 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -932,7 +932,7 @@ static const dri3_screen_info_rec xwl_dri3_info = {
.open_client = xwl_dri3_open_client,
.get_formats = xwl_glamor_get_formats,
.get_modifiers = xwl_glamor_get_modifiers,
- .get_drawable_modifiers = glamor_get_drawable_modifiers,
+ .get_drawable_modifiers = xwl_glamor_get_drawable_modifiers,
};
static Bool
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index a29105f4d..205d2feb3 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -716,7 +716,7 @@ static const dri3_screen_info_rec xwl_dri3_info = {
.open_client = xwl_dri3_open_client,
.get_formats = xwl_glamor_get_formats,
.get_modifiers = xwl_glamor_get_modifiers,
- .get_drawable_modifiers = glamor_get_drawable_modifiers,
+ .get_drawable_modifiers = xwl_glamor_get_drawable_modifiers,
};
static const char *
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 2f0bc5275..1c7845ee6 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -141,6 +141,19 @@ wl_drm_format_for_depth(int depth)
}
}
+static dev_t
+xwl_screen_get_main_dev(struct xwl_screen *xwl_screen)
+{
+ /*
+ * If we have gbm then get our main device from it. Otherwise use what
+ * the compositor told us.
+ */
+ if (xwl_screen->gbm_backend.is_available)
+ return xwl_screen->gbm_backend.get_main_device(xwl_screen);
+ else
+ return xwl_screen->default_feedback.main_dev;
+}
+
Bool
xwl_glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats)
@@ -168,26 +181,22 @@ xwl_glamor_get_formats(ScreenPtr screen,
return TRUE;
}
-Bool
-xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
- uint32_t *num_modifiers, uint64_t **modifiers)
+static Bool
+xwl_get_modifiers_for_format(struct xwl_format *format_array, int num_formats,
+ uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers)
{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_format *xwl_format = NULL;
int i;
- /* Explicitly zero the count as the caller may ignore the return value */
*num_modifiers = 0;
+ *modifiers = NULL;
- if (!xwl_screen->dmabuf)
- return FALSE;
-
- if (xwl_screen->num_formats == 0)
+ if (num_formats == 0)
return TRUE;
- for (i = 0; i < xwl_screen->num_formats; i++) {
- if (xwl_screen->formats[i].format == format) {
- xwl_format = &xwl_screen->formats[i];
+ for (i = 0; i < num_formats; i++) {
+ if (format_array[i].format == format) {
+ xwl_format = &format_array[i];
break;
}
}
@@ -208,6 +217,82 @@ xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
return TRUE;
}
+static Bool
+xwl_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback, dev_t device,
+ uint32_t format, uint32_t *num_modifiers,
+ uint64_t **modifiers)
+{
+ struct xwl_device_formats *dev_formats = NULL;
+
+ /* Now try to find a matching set of tranches for the window's device */
+ for (int i = 0; i < feedback->dev_formats_len; i++) {
+ if (feedback->dev_formats[i].drm_dev == device)
+ dev_formats = &feedback->dev_formats[i];
+ }
+
+ if (!dev_formats)
+ return FALSE;
+
+ return xwl_get_modifiers_for_format(dev_formats->formats, dev_formats->num_formats,
+ format, num_modifiers, modifiers);
+}
+
+Bool
+xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
+ uint32_t *num_modifiers, uint64_t **modifiers)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ dev_t main_dev;
+
+ /* Explicitly zero the count as the caller may ignore the return value */
+ *num_modifiers = 0;
+ *modifiers = NULL;
+
+ if (!xwl_screen->dmabuf)
+ return FALSE;
+
+ if (xwl_screen->dmabuf_protocol_version >= 4) {
+ main_dev = xwl_screen_get_main_dev(xwl_screen);
+
+ return xwl_get_modifiers_for_device(&xwl_screen->default_feedback, main_dev,
+ format, num_modifiers, modifiers);
+ } else {
+ return xwl_get_modifiers_for_format(xwl_screen->formats, xwl_screen->num_formats,
+ format, num_modifiers, modifiers);
+ }
+}
+
+Bool
+xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
+ uint32_t *num_modifiers, uint64_t **modifiers)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(drawable->pScreen);
+ struct xwl_window *xwl_window;
+ dev_t main_dev;
+
+ *num_modifiers = 0;
+ *modifiers = NULL;
+
+ /* We can only return per-drawable modifiers if the compositor supports feedback */
+ if (xwl_screen->dmabuf_protocol_version < 4)
+ return TRUE;
+
+ if (drawable->type != DRAWABLE_WINDOW || !xwl_screen->dmabuf)
+ return FALSE;
+
+ xwl_window = xwl_window_from_window((WindowPtr)drawable);
+
+ /* couldn't find drawable for window */
+ if (!xwl_window)
+ return FALSE;
+
+ main_dev = xwl_screen_get_main_dev(xwl_screen);
+
+ return xwl_get_modifiers_for_device(&xwl_window->feedback, main_dev,
+ format, num_modifiers, modifiers);
+
+}
+
static void
xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
uint32_t format)
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index 216b4bf17..ed9ec40de 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -136,6 +136,8 @@ Bool xwl_glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats);
Bool xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers);
+Bool xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
+ uint32_t *num_modifiers, uint64_t **modifiers);
Bool xwl_glamor_check_flip(PixmapPtr pixmap);
#ifdef XV
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
index 740e62455..88ea6011c 100644
--- a/hw/xwayland/xwayland-window.h
+++ b/hw/xwayland/xwayland-window.h
@@ -34,6 +34,7 @@
#include <dix.h>
#include <propertyst.h>
#include <validate.h>
+#include <wayland-util.h>
#include "xwayland-types.h"