summaryrefslogtreecommitdiff
path: root/hw/xwayland/xwayland-glamor.c
diff options
context:
space:
mode:
authorAustin Shafer <ashafer@nvidia.com>2021-12-02 12:54:23 -0500
committerMichel Dänzer <michel@daenzer.net>2023-01-20 17:56:54 +0000
commitd61eb4dd98e3192b35c61ecf46ef1c1053c528db (patch)
tree98fb286c0d0fbdac4775993926b22cb1e27401f5 /hw/xwayland/xwayland-glamor.c
parent43b35b4efeddac3df180d38b3c4967a15de9e639 (diff)
downloadxserver-d61eb4dd98e3192b35c61ecf46ef1c1053c528db.tar.gz
xwayland: Return default feedback in xwl_screen
If protocol version 4 of linux_dmabuf is in use, then the compositor may not return anything with the modifiers event. We instead will return the formats/mods reported for the main device. Reviewed-by: Michel Dänzer <mdaenzer@redhat.com> [ Michel Dänzer: * Move main_dev declaration to where it's used in xwl_glamor_get_formats * Add empty line between variable declaration and comment ]
Diffstat (limited to 'hw/xwayland/xwayland-glamor.c')
-rw-r--r--hw/xwayland/xwayland-glamor.c74
1 files changed, 65 insertions, 9 deletions
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 988ab33ff..ad52afd20 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -175,6 +175,45 @@ xwl_get_formats(struct xwl_format *format_array, int format_array_len,
return TRUE;
}
+static Bool
+xwl_get_formats_for_device(struct xwl_dmabuf_feedback *xwl_feedback, dev_t device,
+ uint32_t *num_formats, uint32_t **formats)
+{
+ uint32_t *ret = NULL;
+ uint32_t count = 0;
+
+ /* go through all matching sets of tranches for the window's device */
+ for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
+ if (xwl_feedback->dev_formats[i].drm_dev == device) {
+ struct xwl_device_formats *dev_formats = &xwl_feedback->dev_formats[i];
+
+ /* Append the formats from this tranche to the list */
+ ret = xnfreallocarray(ret, count + dev_formats->num_formats, sizeof(CARD32));
+
+ for (int j = 0; j < dev_formats->num_formats; j++) {
+ bool found = false;
+
+ /* Check if this format is already present in the list */
+ for (int k = 0; k < count; k++) {
+ if (ret[k] == dev_formats->formats[j].format) {
+ found = true;
+ break;
+ }
+ }
+
+ /* If this format has not yet been added, do so now */
+ if (!found)
+ ret[count++] = dev_formats->formats[j].format;
+ }
+ }
+ }
+
+ *num_formats = count;
+ *formats = ret;
+
+ return TRUE;
+}
+
Bool
xwl_glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats)
@@ -187,6 +226,13 @@ xwl_glamor_get_formats(ScreenPtr screen,
if (!xwl_screen->dmabuf)
return FALSE;
+ if (xwl_screen->dmabuf_protocol_version >= 4) {
+ dev_t main_dev = xwl_screen_get_main_dev(xwl_screen);
+
+ return xwl_get_formats_for_device(&xwl_screen->default_feedback, main_dev,
+ num_formats, formats);
+ }
+
return xwl_get_formats(xwl_screen->formats, xwl_screen->num_formats,
num_formats, formats);
}
@@ -232,19 +278,17 @@ 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];
- }
+ struct xwl_device_formats *dev_formats = &feedback->dev_formats[i];
- if (!dev_formats)
- return FALSE;
+ if (dev_formats->drm_dev == device &&
+ xwl_get_modifiers_for_format(dev_formats->formats, dev_formats->num_formats,
+ format, num_modifiers, modifiers))
+ return TRUE;
+ }
- return xwl_get_modifiers_for_format(dev_formats->formats, dev_formats->num_formats,
- format, num_modifiers, modifiers);
+ return FALSE;
}
Bool
@@ -587,6 +631,18 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
xwl_screen->dmabuf_protocol_version = supported_version;
zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
+ /* If the compositor supports it, request the default feedback hints */
+ if (version >= 4) {
+ xwl_screen->default_feedback.dmabuf_feedback =
+ zwp_linux_dmabuf_v1_get_default_feedback(xwl_screen->dmabuf);
+ if (!xwl_screen->default_feedback.dmabuf_feedback)
+ return FALSE;
+
+ zwp_linux_dmabuf_feedback_v1_add_listener(xwl_screen->default_feedback.dmabuf_feedback,
+ &xwl_dmabuf_feedback_listener,
+ &xwl_screen->default_feedback);
+ }
+
return TRUE;
}