[RFC xserver v2 04/10] glamor: Implement GetSupportedModifiers

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Wed Aug 30 04:45:36 UTC 2017


Implement function added in DRI3 v1.1.

A newest version of libepoxy (>= 1.4.4) is required as earlier
versions use a problematic version of Khronos
EXT_image_dma_buf_import_modifiers spec.

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
 configure.ac                  |   4 ++
 glamor/glamor.h               |  10 ++++
 glamor/glamor_egl.c           |  91 +++++++++++++++++++++++++++++
 hw/xwayland/xwayland-glamor.c | 129 +++++++++++++++++++++++++++++++++++++-----
 hw/xwayland/xwayland.h        |   9 ++-
 include/dix-config.h.in       |   3 +
 6 files changed, 232 insertions(+), 14 deletions(-)

diff --git a/configure.ac b/configure.ac
index 4604189ee..b1818477b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2087,6 +2087,10 @@ if test "x$GLAMOR" = xyes; then
 	AC_DEFINE(GLAMOR, 1, [Build glamor])
 	PKG_CHECK_MODULES([GLAMOR], [epoxy])
 
+	PKG_CHECK_EXISTS(epoxy >= 1.4.4,
+			 [AC_DEFINE(GLAMOR_HAS_EGL_QUERY_DMABUF, 1, [Have GLAMOR_HAS_EGL_QUERY_DMABUF])],
+			 [])
+
 	PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no])
 	if test "x$GBM" = xyes; then
 		AC_DEFINE(GLAMOR_HAS_GBM, 1,
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 8f8c31b45..ddf67fe20 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -272,6 +272,16 @@ extern _X_EXPORT Bool glamor_back_pixmap_from_fd(PixmapPtr pixmap,
                                                  CARD16 stride,
                                                  CARD8 depth,
                                                  CARD8 bpp);
+
+extern _X_EXPORT Bool glamor_get_formats(ScreenPtr screen,
+                                         CARD32 *num_formats,
+                                         CARD32 **formats);
+
+extern _X_EXPORT Bool glamor_get_modifiers(ScreenPtr screen,
+                                           CARD32 format,
+                                           CARD32 *num_modifiers,
+                                           uint64_t **modifiers);
+
 #ifdef GLAMOR_FOR_XORG
 
 #define GLAMOR_EGL_MODULE_NAME  "glamoregl"
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 5708170a9..dc51337ad 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -486,6 +486,95 @@ glamor_pixmap_from_fds(ScreenPtr screen,
     return pixmap;
 }
 
+_X_EXPORT Bool
+glamor_get_formats(ScreenPtr screen,
+                   CARD32 *num_formats, CARD32 **formats)
+{
+#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
+    struct glamor_egl_screen_private *glamor_egl;
+    EGLint num;
+
+    glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+
+    if (!glamor_egl->dmabuf_capable)
+        return FALSE;
+
+    if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, 0, NULL, &num)) {
+        *num_formats = 0;
+        return FALSE;
+    }
+
+    if (num == 0) {
+        *num_formats = 0;
+        return TRUE;
+    }
+
+    *formats = calloc(num, sizeof(CARD32));
+    if (*formats == NULL) {
+        *num_formats = 0;
+        return FALSE;
+    }
+
+    if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, num,
+                                  (EGLint *) *formats, &num)) {
+        *num_formats = 0;
+        free(*formats);
+        return FALSE;
+    }
+
+    *num_formats = num;
+    return TRUE;
+#else
+    *num_formats = 0;
+    return TRUE;
+#endif
+}
+
+_X_EXPORT Bool
+glamor_get_modifiers(ScreenPtr screen, CARD32 format,
+                     CARD32 *num_modifiers, uint64_t **modifiers)
+{
+#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
+    struct glamor_egl_screen_private *glamor_egl;
+    EGLint num;
+
+    glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+
+    if (!glamor_egl->dmabuf_capable)
+        return FALSE;
+
+    if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, 0, NULL,
+                                    NULL, &num)) {
+        *num_modifiers = 0;
+        return FALSE;
+    }
+
+    if (num == 0) {
+        *num_modifiers = 0;
+        return TRUE;
+    }
+
+    *modifiers = calloc(num, sizeof(uint64_t));
+    if (*modifiers == NULL) {
+        *num_modifiers = 0;
+        return FALSE;
+    }
+
+    if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, num,
+                                    (EGLuint64KHR *) *modifiers, NULL, &num)) {
+        *num_modifiers = 0;
+        free(*modifiers);
+        return FALSE;
+    }
+
+    *num_modifiers = num;
+    return TRUE;
+#else
+    *num_modifiers = 0;
+    return TRUE;
+#endif
+}
+
 static Bool
 glamor_egl_destroy_pixmap(PixmapPtr pixmap)
 {
@@ -607,6 +696,8 @@ static dri3_screen_info_rec glamor_dri3_info = {
     .open_client = glamor_dri3_open_client,
     .pixmap_from_fds = glamor_pixmap_from_fds,
     .fds_from_pixmap = glamor_egl_fds_from_pixmap,
+    .get_formats = glamor_get_formats,
+    .get_modifiers = glamor_get_modifiers,
 };
 #endif /* DRI3 */
 
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 5c0c408ab..ca3785ff5 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -409,19 +409,6 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
 static void
 xwl_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
 {
-   struct xwl_screen *xwl_screen = data;
-
-   switch (format) {
-   case WL_DRM_FORMAT_ARGB8888:
-      xwl_screen->formats |= XWL_FORMAT_ARGB8888;
-      break;
-   case WL_DRM_FORMAT_XRGB8888:
-      xwl_screen->formats |= XWL_FORMAT_XRGB8888;
-      break;
-   case WL_DRM_FORMAT_RGB565:
-      xwl_screen->formats |= XWL_FORMAT_RGB565;
-      break;
-   }
 }
 
 static void
@@ -448,6 +435,54 @@ static const struct wl_drm_listener xwl_drm_listener = {
     xwl_drm_handle_capabilities
 };
 
+static void
+xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+                         uint32_t format)
+{
+}
+
+static void
+xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+                           uint32_t format, uint32_t modifier_hi,
+                           uint32_t modifier_lo)
+{
+   struct xwl_screen *xwl_screen = data;
+    struct xwl_format *xwl_format = NULL;
+    int i;
+
+    for (i = 0; i < xwl_screen->num_formats; i++) {
+        if (xwl_screen->formats[i].format == format) {
+            xwl_format = &xwl_screen->formats[i];
+            break;
+        }
+    }
+
+    if (xwl_format == NULL) {
+       xwl_screen->num_formats++;
+       xwl_screen->formats = realloc(xwl_screen->formats,
+                                     xwl_screen->num_formats * sizeof(*xwl_format));
+       if (!xwl_screen->formats)
+          return;
+       xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1];
+       xwl_format->format = format;
+       xwl_format->num_modifiers = 0;
+       xwl_format->modifiers = NULL;
+    }
+
+    xwl_format->num_modifiers++;
+    xwl_format->modifiers = realloc(xwl_format->modifiers,
+                                    xwl_format->num_modifiers * sizeof(uint64_t));
+    if (!xwl_format->modifiers)
+       return;
+    xwl_format->modifiers[xwl_format->num_modifiers - 1]  = (uint64_t) modifier_lo;
+    xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32;
+}
+
+static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
+    .format   = xwl_dmabuf_handle_format,
+    .modifier = xwl_dmabuf_handle_modifier
+};
+
 Bool
 xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
                              uint32_t id, uint32_t version)
@@ -472,6 +507,7 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
 
     xwl_screen->dmabuf =
         wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 2);
+    zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
 
     return TRUE;
 }
@@ -673,12 +709,79 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
     return xwl_pixmap->num_fds;
 }
 
+_X_EXPORT Bool
+glamor_get_formats(ScreenPtr screen,
+                   CARD32 *num_formats, CARD32 **formats)
+{
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    int i;
+
+    if (!xwl_screen->dmabuf_capable || !xwl_screen->dmabuf)
+        return FALSE;
+
+    if (xwl_screen->num_formats == 0) {
+       *num_formats = 0;
+       return TRUE;
+    }
+
+    *formats = calloc(xwl_screen->num_formats, sizeof(CARD32));
+    if (*formats == NULL) {
+        *num_formats = 0;
+        return FALSE;
+    }
+
+    for (i = 0; i < xwl_screen->num_formats; i++)
+       (*formats)[i] = xwl_screen->formats[i].format;
+    *num_formats = xwl_screen->num_formats;
+
+    return TRUE;
+}
+
+_X_EXPORT Bool
+glamor_get_modifiers(ScreenPtr screen, CARD32 format,
+                     CARD32 *num_modifiers, uint64_t **modifiers)
+{
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    struct xwl_format *xwl_format = NULL;
+    int i;
+
+    if (!xwl_screen->dmabuf_capable || !xwl_screen->dmabuf)
+        return FALSE;
+
+    if (xwl_screen->num_modifiers == 0) {
+       *num_modifiers = 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];
+          break;
+       }
+    }
+
+    *modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
+    if (*modifiers == NULL) {
+        *num_modifiers = 0;
+        return FALSE;
+    }
+
+    for (i = 0; i < xwl_format->num_modifiers; i++)
+       (*modifiers)[i] = xwl_format->modifiers[i];
+    *num_modifiers = xwl_format->num_modifiers;
+
+    return TRUE;
+}
+
+
 static dri3_screen_info_rec xwl_dri3_info = {
     .version = 2,
     .open = NULL,
     .pixmap_from_fds = glamor_pixmap_from_fds,
     .fds_from_pixmap = glamor_fds_from_pixmap,
     .open_client = xwl_dri3_open_client,
+    .get_formats = glamor_get_formats,
+    .get_modifiers = glamor_get_modifiers,
 };
 
 Bool
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index ec77d10f9..fc24e1e74 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -48,6 +48,12 @@
 #include "xwayland-keyboard-grab-unstable-v1-client-protocol.h"
 #include "linux-dmabuf-unstable-v1-client-protocol.h"
 
+struct xwl_format {
+    uint32_t format;
+    int num_modifiers;
+    uint64_t *modifiers;
+};
+
 struct xwl_screen {
     int width;
     int height;
@@ -97,7 +103,8 @@ struct xwl_screen {
     int fd_render_node;
     struct wl_drm *drm;
     struct zwp_linux_dmabuf_v1 *dmabuf;
-    uint32_t formats;
+    uint32_t num_formats;
+    struct xwl_format *formats;
     uint32_t capabilities;
     void *egl_display, *egl_context;
     struct gbm_device *gbm;
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 57aee61fd..8e9dcdfcc 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -503,6 +503,9 @@
 /* Build glamor use new drmGetDeviceNameFromFD2 */
 #undef GLAMOR_HAS_DRM_NAME_FROM_FD_2
 
+/* Glamor can use eglQueryDmaBuf* functions */
+#undef GLAMOR_HAS_EGL_QUERY_DMABUF
+
 /* byte order */
 #undef X_BYTE_ORDER
 
-- 
2.13.0



More information about the xorg-devel mailing list