[RFC xserver 06/16] DRI3: Implement BuffersFromPixmap request

Daniel Stone daniels at collabora.com
Thu Jun 8 18:43:32 UTC 2017


From: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 dri3/dri3.h                   | 13 ++++---
 dri3/dri3_priv.h              |  4 ++-
 dri3/dri3_request.c           | 46 ++++++++++++++----------
 dri3/dri3_screen.c            | 16 ++++-----
 glamor/glamor.c               | 81 +++++++++++++++++++++++++++++++++++++------
 glamor/glamor.h               | 41 +++++++++++++++-------
 glamor/glamor_egl.c           | 60 ++++++++++++++++++++++++++------
 glamor/glamor_egl_stubs.c     |  7 ++--
 glamor/glamor_priv.h          | 10 ++++++
 hw/xwayland/xwayland-glamor.c | 51 ++++++++++++++++++++-------
 10 files changed, 245 insertions(+), 84 deletions(-)

diff --git a/dri3/dri3.h b/dri3/dri3.h
index 4d6699f5e..864e1ae00 100644
--- a/dri3/dri3.h
+++ b/dri3/dri3.h
@@ -49,10 +49,13 @@ typedef PixmapPtr (*dri3_pixmap_from_fds_proc) (ScreenPtr screen,
                                                 CARD32 format,
                                                 uint64_t modifiers);
 
-typedef int (*dri3_fd_from_pixmap_proc) (ScreenPtr screen,
-                                         PixmapPtr pixmap,
-                                         CARD16 *stride,
-                                         CARD32 *size);
+typedef int (*dri3_fds_from_pixmap_proc) (ScreenPtr screen,
+                                          PixmapPtr pixmap,
+                                          int *fds,
+                                          uint32_t *strides,
+                                          uint32_t *offsets,
+                                          uint32_t *format,
+                                          uint64_t *modifier);
 
 typedef int (*dri3_get_formats_proc) (ScreenPtr screen,
                                       CARD32 *num_formats,
@@ -69,7 +72,7 @@ typedef struct dri3_screen_info {
 
     dri3_open_proc              open;
     dri3_pixmap_from_fds_proc   pixmap_from_fds;
-    dri3_fd_from_pixmap_proc    fd_from_pixmap;
+    dri3_fds_from_pixmap_proc   fds_from_pixmap;
     dri3_get_formats_proc       get_formats;
     dri3_get_modifiers_proc     get_modifiers;
 
diff --git a/dri3/dri3_priv.h b/dri3/dri3_priv.h
index 5359a8a92..730fcfb43 100644
--- a/dri3/dri3_priv.h
+++ b/dri3/dri3_priv.h
@@ -85,7 +85,9 @@ dri3_pixmap_from_fds(PixmapPtr *ppixmap, ScreenPtr screen, CARD8 num_fds, int *f
                      CARD32 format, uint64_t modifier);
 
 int
-dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size);
+dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds,
+                     uint32_t *strides, uint32_t *offsets,
+                     uint32_t *format, uint64_t *modifier);
 
 int
 dri3_get_supported_formats(ScreenPtr screen, CARD32 *num_formats, CARD32 **formats);
diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c
index 182388232..d60e6bd0e 100644
--- a/dri3/dri3_request.c
+++ b/dri3/dri3_request.c
@@ -234,7 +234,11 @@ proc_dri3_buffer_from_pixmap(ClientPtr client)
         .length = 0,
     };
     int rc;
-    int fd;
+    int num_fds;
+    int fds[4];
+    uint32_t strides[4], offsets[4];
+    uint32_t format;
+    uint64_t modifier;
     PixmapPtr pixmap;
 
     REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
@@ -250,9 +254,15 @@ proc_dri3_buffer_from_pixmap(ClientPtr client)
     rep.depth = pixmap->drawable.depth;
     rep.bpp = pixmap->drawable.bitsPerPixel;
 
-    rc = dri3_fd_from_pixmap(&fd, pixmap, &rep.stride, &rep.size);
-    if (rc != Success)
-        return rc;
+    num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets,
+                                   &format, &modifier);
+    if (num_fds == 0)
+        return BadPixmap;
+
+    // XXX Should we fail if num_fds > 1
+
+    rep.stride = (CARD16) strides[0];
+    rep.size = rep.stride * rep.height;
 
     if (client->swapped) {
         swaps(&rep.sequenceNumber);
@@ -262,8 +272,8 @@ proc_dri3_buffer_from_pixmap(ClientPtr client)
         swaps(&rep.height);
         swaps(&rep.stride);
     }
-    if (WriteFdToClient(client, fd, TRUE) < 0) {
-        close(fd);
+    if (WriteFdToClient(client, fds[0], TRUE) < 0) {
+        close(fds[0]);
         return BadAlloc;
     }
 
@@ -531,7 +541,9 @@ proc_dri3_buffers_from_pixmap(ClientPtr client)
     int rc;
     int fds[4];
     int num_fds;
-    CARD32 strides[4], offsets[4];
+    uint32_t strides[4], offsets[4];
+    uint32_t format;
+    uint64_t modifier;
     int i;
     PixmapPtr pixmap;
 
@@ -543,20 +555,18 @@ proc_dri3_buffers_from_pixmap(ClientPtr client)
         return rc;
     }
 
-    rep.width = pixmap->drawable.width;
-    rep.height = pixmap->drawable.height;
-    rep.format = 0; /* XXX: DTRT */
-    rep.modifier_hi = 0; /* XXX: DTRT */
-    rep.modifier_lo = 0; /* XXX: DTRT */
-
-    /* XXX: DTRT */
-    num_fds = 1;
-    rc = dri3_fd_from_pixmap(fds, pixmap, (CARD16 *) strides, NULL);
-    if (rc != Success)
-        return rc;
+    num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets,
+                                   &format, &modifier);
+    if (num_fds == 0)
+        return BadPixmap;
 
     rep.nfd = num_fds;
     rep.length = bytes_to_int32(num_fds * 2 * sizeof(CARD32));
+    rep.width = pixmap->drawable.width;
+    rep.height = pixmap->drawable.height;
+    rep.format = format;
+    rep.modifier_hi = modifier >> 32;
+    rep.modifier_lo = modifier & 0xffffffff;
 
     if (client->swapped) {
         swaps(&rep.sequenceNumber);
diff --git a/dri3/dri3_screen.c b/dri3/dri3_screen.c
index 65c262ba0..f666c920b 100644
--- a/dri3/dri3_screen.c
+++ b/dri3/dri3_screen.c
@@ -83,21 +83,19 @@ dri3_pixmap_from_fds(PixmapPtr *ppixmap, ScreenPtr screen,
 }
 
 int
-dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
+dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds,
+                     uint32_t *strides, uint32_t *offsets,
+                     uint32_t *format, uint64_t *modifier)
 {
     ScreenPtr                   screen = pixmap->drawable.pScreen;
     dri3_screen_priv_ptr        ds = dri3_screen_priv(screen);
     dri3_screen_info_ptr        info = ds->info;
-    int                         fd;
 
-    if (!info || !info->fd_from_pixmap)
-        return BadImplementation;
+    if (!info || !info->fds_from_pixmap)
+        return 0;
 
-    fd = (*info->fd_from_pixmap)(screen, pixmap, stride, size);
-    if (fd < 0)
-        return BadAlloc;
-    *pfd = fd;
-    return Success;
+    return (*info->fds_from_pixmap)(screen, pixmap, fds, strides, offsets,
+                                    format, modifier);
 }
 
 static int
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 66b081272..b6611bef0 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -170,6 +170,65 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
     glamor_pixmap_attach_fbo(pixmap, fbo);
 }
 
+_X_EXPORT void
+glamor_set_pixmap_dmabuf(PixmapPtr pixmap,
+                         int num_fds, int *fds,
+                         uint32_t *strides, uint32_t *offsets,
+                         uint32_t format, uint64_t modifier)
+{
+    glamor_pixmap_private *pixmap_priv;
+    glamor_pixmap_dmabuf *dmabuf;
+    int i;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (pixmap_priv->dmabuf) {
+        free(pixmap_priv->dmabuf);
+        pixmap_priv->dmabuf = NULL;
+    }
+
+    dmabuf = calloc(1, sizeof(glamor_pixmap_dmabuf));
+    if (dmabuf == NULL) {
+        ErrorF("XXX fail to create dmabuf struct.\n");
+        return;
+    }
+    dmabuf->num_fds = num_fds;
+    dmabuf->format = format;
+    dmabuf->modifier = modifier;
+    for (i = 0; i < num_fds; i++) {
+        dmabuf->fds[i] = fds[i];
+        dmabuf->strides[i] = strides[i];
+        dmabuf->offsets[i] = offsets[i];
+    }
+
+    pixmap_priv->dmabuf = dmabuf;
+}
+
+_X_EXPORT int
+glamor_dmabuf_from_pixmap(PixmapPtr pixmap, int *fds,
+                          uint32_t *strides, uint32_t *offsets,
+                          uint32_t *format, uint64_t *modifier)
+{
+    glamor_pixmap_private *pixmap_priv;
+    glamor_pixmap_dmabuf *dmabuf;
+    int i;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (!pixmap_priv->dmabuf)
+        return 0;
+
+    dmabuf = pixmap_priv->dmabuf;
+    *format = dmabuf->format;
+    *modifier = dmabuf->modifier;
+    for (i = 0; i < dmabuf->num_fds; i++) {
+        fds[i] = dmabuf->fds[i];
+        strides[i] = dmabuf->strides[i];
+        offsets[i] = dmabuf->offsets[i];
+    }
+    return dmabuf->num_fds;
+}
+
 uint32_t
 glamor_get_pixmap_texture(PixmapPtr pixmap)
 {
@@ -860,8 +919,10 @@ glamor_supports_pixmap_import_export(ScreenPtr screen)
 }
 
 _X_EXPORT int
-glamor_fd_from_pixmap(ScreenPtr screen,
-                      PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
+glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
+                       int *num_fds, int *fds,
+                       uint32_t *strides, uint32_t *offsets,
+                       uint32_t *format, uint64_t *modifier)
 {
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_screen_private *glamor_priv =
@@ -874,10 +935,9 @@ glamor_fd_from_pixmap(ScreenPtr screen,
     case GLAMOR_TEXTURE_ONLY:
         if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
             return -1;
-        return glamor_egl_dri3_fd_name_from_tex(screen,
-                                                pixmap,
-                                                pixmap_priv->fbo->tex,
-                                                FALSE, stride, size);
+        return glamor_egl_fds_from_pixmap(screen, pixmap, fds,
+                                          strides, offsets,
+                                          format, modifier);
     default:
         break;
     }
@@ -898,7 +958,8 @@ glamor_shareable_fd_from_pixmap(ScreenPtr screen,
      * 2 of those calls are also exported API, so we cannot just add a flag.
      */
     pixmap->usage_hint = CREATE_PIXMAP_USAGE_SHARED;
-    ret = glamor_fd_from_pixmap(screen, pixmap, stride, size);
+    // XXX Check uses of glamor_shareable_fd_from_pixmap
+    //ret = glamor_fds_from_pixmap(screen, pixmap, stride, size);
     pixmap->usage_hint = orig_usage_hint;
 
     return ret;
@@ -914,10 +975,8 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
     case GLAMOR_TEXTURE_ONLY:
         if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
             return -1;
-        return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
-                                                pixmap,
-                                                pixmap_priv->fbo->tex,
-                                                TRUE, stride, size);
+        return glamor_egl_fd_name_from_pixmap(pixmap->drawable.pScreen,
+                                              pixmap, stride, size);
     default:
         break;
     }
diff --git a/glamor/glamor.h b/glamor/glamor.h
index fdf265075..d57d25046 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -116,6 +116,18 @@ extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap);
 extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
                                                 unsigned int tex);
 
+extern _X_EXPORT void glamor_set_pixmap_dmabuf(PixmapPtr pixmap,
+                                               int num_fds, int *fds,
+                                               uint32_t *strides,
+                                               uint32_t *offsets,
+                                               uint32_t format,
+                                               uint64_t modifier);
+extern _X_EXPORT int glamor_dmabuf_from_pixmap(PixmapPtr pixmap, int *fds,
+                                               uint32_t *strides,
+                                               uint32_t *offsets,
+                                               uint32_t *format,
+                                               uint64_t *modifier);
+
 extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap,
                                              glamor_pixmap_type_t type);
 extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
@@ -146,14 +158,16 @@ extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front,
 
 /* The DDX is not supposed to call these three functions */
 extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
-extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
-                                                      unsigned int, Bool,
-                                                      CARD16 *, CARD32 *);
+extern _X_EXPORT int glamor_egl_fds_from_pixmap(ScreenPtr, PixmapPtr, int *,
+                                                uint32_t *, uint32_t *,
+                                                uint32_t *, uint64_t *);
+extern _X_EXPORT int glamor_egl_fd_name_from_pixmap(ScreenPtr, PixmapPtr,
+                                                    CARD16 *, CARD32 *);
 
 extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen);
 
 /* @glamor_supports_pixmap_import_export: Returns whether
- * glamor_fd_from_pixmap(), glamor_name_from_pixmap(), and
+ * glamor_fds_from_pixmap(), glamor_name_from_pixmap(), and
  * glamor_pixmap_from_fd() are supported.
  *
  * @screen: Current screen pointer.
@@ -168,20 +182,23 @@ extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen);
  * */
 extern _X_EXPORT Bool glamor_supports_pixmap_import_export(ScreenPtr screen);
 
-/* @glamor_fd_from_pixmap: Get a dma-buf fd from a pixmap.
+/* @glamor_fds_from_pixmap: Get a dma-buf fd from a pixmap.
  *
  * @screen: Current screen pointer.
  * @pixmap: The pixmap from which we want the fd.
- * @stride, @size: Pointers to fill the stride and size of the
- * 		   buffer associated to the fd.
+ * @num_fds: Pointer to fill the number of planes.
+ * @fds, @strides, @offsets: Pointers to fill info of each plane.
+ * @format, @modifier: Pointers to fill the format and modifier of the buffer.
  *
- * the pixmap and the buffer associated by the fd will share the same
+ * the pixmap and the buffer associated by the fds will share the same
  * content.
- * Returns the fd on success, -1 on error.
+ * Returns 0 on success, -1 on error.
  * */
-extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen,
-                                           PixmapPtr pixmap,
-                                           CARD16 *stride, CARD32 *size);
+extern _X_EXPORT int glamor_fds_from_pixmap(ScreenPtr screen,
+                                            PixmapPtr pixmap,
+                                            int *num_fds, int *fds,
+                                            uint32_t *strides, uint32_t *offsets,
+                                            uint32_t *format, uint64_t *modifier);
 
 /* @glamor_shareable_fd_from_pixmap: Get a dma-buf fd suitable for sharing
  *				     with other GPUs from a pixmap.
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 762908203..392c9a39c 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -345,6 +345,8 @@ glamor_egl_create_textured_pixmap_from_dmabuf(PixmapPtr pixmap,
     glamor_create_texture_from_image(screen, image, &texture);
     glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_texture(pixmap, texture);
+    glamor_set_pixmap_dmabuf(pixmap, num_fds, fds, strides, offsets,
+                             format, modifier);
     glamor_egl_set_pixmap_image(pixmap, image);
 
     return TRUE;
@@ -446,10 +448,45 @@ glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
 }
 
 int
-glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
-                                 PixmapPtr pixmap,
-                                 unsigned int tex,
-                                 Bool want_name, CARD16 *stride, CARD32 *size)
+glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
+                           uint32_t *strides, uint32_t *offsets,
+                           uint32_t *format, uint64_t *modifier)
+{
+#ifdef GLAMOR_HAS_GBM
+    struct gbm_bo *bo;
+    int ret;
+
+    if (!glamor_make_pixmap_exportable(pixmap))
+        return 0;
+
+    ret = glamor_dmabuf_from_pixmap(pixmap, fds, strides, offsets,
+                                    format, modifier);
+    if (ret)
+        return ret;
+
+    bo = glamor_gbm_bo_from_pixmap(screen, pixmap);
+    if (!bo)
+        return 0;
+
+    pixmap->devKind = gbm_bo_get_stride(bo);
+
+    fds[0] = gbm_bo_get_fd(bo);
+    strides[0] = pixmap->devKind;
+    offsets[0] = 0;
+    *modifier = gbm_bo_get_modifier(bo);
+    *format = gbm_bo_get_format(bo);
+
+    gbm_bo_destroy(bo);
+    return 1;
+#else
+    return 0;
+#endif
+}
+
+int
+glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
+                               PixmapPtr pixmap,
+                               CARD16 *stride, CARD32 *size)
 {
     struct glamor_egl_screen_private *glamor_egl;
     struct gbm_bo *bo;
@@ -463,12 +500,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 
     pixmap->devKind = gbm_bo_get_stride(bo);
 
-    if (want_name) {
-        glamor_get_name_from_bo(glamor_egl->fd, bo, &fd);
-    }
-    else {
-        fd = gbm_bo_get_fd(bo);
-    }
+    glamor_get_name_from_bo(glamor_egl->fd, bo, &fd);
     *stride = pixmap->devKind;
     *size = pixmap->devKind * gbm_bo_get_height(bo);
 
@@ -644,6 +676,12 @@ glamor_egl_destroy_pixmap(PixmapPtr pixmap)
 
         if (pixmap_priv->image)
             eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
+
+        if (pixmap_priv->dmabuf) {
+            for (i = 0; i < pixmap_priv->dmabuf->num_fds; i++)
+                close(pixmap_priv->dmabuf->fds[i]);
+            free(pixmap_priv->dmabuf);
+        }
     }
 
     screen->DestroyPixmap = glamor_egl->saved_destroy_pixmap;
@@ -749,7 +787,7 @@ static dri3_screen_info_rec glamor_dri3_info = {
     .version = 1,
     .open_client = glamor_dri3_open_client,
     .pixmap_from_fds = glamor_pixmap_from_fds,
-    .fd_from_pixmap = glamor_fd_from_pixmap,
+    .fds_from_pixmap = glamor_egl_fds_from_pixmap,
     .get_formats = glamor_get_formats,
     .get_modifiers = glamor_get_modifiers,
 };
diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c
index 40f7fcc01..c6e13842b 100644
--- a/glamor/glamor_egl_stubs.c
+++ b/glamor/glamor_egl_stubs.c
@@ -36,10 +36,9 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 }
 
 int
-glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
-                                 PixmapPtr pixmap,
-                                 unsigned int tex,
-                                 Bool want_name, CARD16 *stride, CARD32 *size)
+glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
+                           uint32_t *offsets, uint32_t *strides,
+                           uint32_t *format, uint64_t *modifier)
 {
     return 0;
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 07a98efeb..3856ddd77 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -319,6 +319,15 @@ typedef struct glamor_pixmap_fbo {
     GLenum type; /**< GL type used to create the texture. */
 } glamor_pixmap_fbo;
 
+typedef struct glamor_pixmap_dmabuf {
+    int num_fds;
+    int fds[4];
+    uint32_t strides[4];
+    uint32_t offsets[4];
+    uint32_t format;
+    uint64_t modifier;
+} glamor_pixmap_dmabuf;
+
 typedef struct glamor_pixmap_clipped_regions {
     int block_idx;
     RegionPtr region;
@@ -341,6 +350,7 @@ typedef struct glamor_pixmap_private {
     Bool prepared;
 #ifdef GLAMOR_HAS_GBM
     EGLImageKHR image;
+    glamor_pixmap_dmabuf *dmabuf;
 #endif
     /** block width of this large pixmap. */
     int block_w;
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index ddf93bce6..139e38052 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -111,7 +111,8 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 }
 
 static PixmapPtr
-xwl_glamor_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth)
+xwl_glamor_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth,
+                                uint32_t format)
 {
     PixmapPtr pixmap;
     struct xwl_pixmap *xwl_pixmap;
@@ -137,6 +138,7 @@ xwl_glamor_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth)
     }
 
     xwl_pixmap->bo = bo;
+    xwl_pixmap->format = format;
     xwl_pixmap->buffer = NULL;
     xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
                                           xwl_screen->egl_context,
@@ -348,7 +350,7 @@ xwl_glamor_create_pixmap(ScreenPtr screen,
                            GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
 
         if (bo)
-            return xwl_glamor_create_pixmap_for_bo(screen, bo, depth);
+            return xwl_glamor_create_pixmap_for_bo(screen, bo, depth, format);
     }
 
     return glamor_create_pixmap(screen, width, height, depth, hint);
@@ -578,10 +580,17 @@ xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
 }
 
 int
-glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
-                                 PixmapPtr pixmap,
-                                 unsigned int tex,
-                                 Bool want_name, CARD16 *stride, CARD32 *size)
+glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
+                               PixmapPtr pixmap,
+                               CARD16 *stride, CARD32 *size)
+{
+    return 0;
+}
+
+int
+glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
+                           uint32_t *strides, uint32_t *offsets,
+                           uint32_t *format, uint64_t *modifier)
 {
     return 0;
 }
@@ -718,7 +727,7 @@ xwl_dri3_pixmap_from_fds(ScreenPtr screen,
        if (bo == NULL)
           return NULL;
 
-       pixmap = xwl_glamor_create_pixmap_for_bo(screen, bo, info->depth);
+       pixmap = xwl_glamor_create_pixmap_for_bo(screen, bo, info->depth, format);
        if (pixmap == NULL) {
           gbm_bo_destroy(bo);
           return NULL;
@@ -731,17 +740,33 @@ xwl_dri3_pixmap_from_fds(ScreenPtr screen,
 }
 
 static int
-xwl_dri3_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
-                        CARD16 *stride, CARD32 *size)
+xwl_dri3_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
+                         uint32_t *strides, uint32_t *offsets,
+                         uint32_t *format, uint64_t *modifier)
 {
     struct xwl_pixmap *xwl_pixmap;
+    int i;
 
     xwl_pixmap = xwl_pixmap_get(pixmap);
 
-    *stride = gbm_bo_get_stride(xwl_pixmap->bo);
-    *size = pixmap->drawable.width * *stride;
+    if (xwl_pixmap->bo) {
+        fds[0] = gbm_bo_get_fd(xwl_pixmap->bo);
+        strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
+        offsets[0] = 0;
+        *format = gbm_format_for_depth(pixmap->drawable.depth),
+        *modifier = 0;
+        return 1;
+    }
+
+    for (i = 0; i < xwl_pixmap->num_fds; i++) {
+       fds[i] = xwl_pixmap->fds[i];
+       strides[i] = xwl_pixmap->strides[i];
+       offsets[i] = xwl_pixmap->offsets[i];
+    }
+    *format = xwl_pixmap->format;
+    *modifier = xwl_pixmap->modifier;
 
-    return gbm_bo_get_fd(xwl_pixmap->bo);
+    return xwl_pixmap->num_fds;
 }
 
 static int
@@ -821,7 +846,7 @@ static dri3_screen_info_rec xwl_dri3_info = {
     .version = 1,
     .open = NULL,
     .pixmap_from_fds = xwl_dri3_pixmap_from_fds,
-    .fd_from_pixmap = xwl_dri3_fd_from_pixmap,
+    .fds_from_pixmap = xwl_dri3_fds_from_pixmap,
     .open_client = xwl_dri3_open_client,
     .get_formats = xwl_dri3_get_formats,
     .get_modifiers = xwl_dri3_get_modifiers,
-- 
2.13.0



More information about the xorg-devel mailing list