[RFC v2 06/13] glamor: Use gbm_bo_create_with_modifiers for internal pixmap allocation

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Fri Jul 14 04:47:53 UTC 2017


Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
 configure.ac                  |  4 +++
 glamor/glamor_egl.c           | 73 +++++++++++++++++++++++++++++++++++++------
 hw/xwayland/xwayland-glamor.c | 22 +++++++++++--
 include/dix-config.h.in       |  3 ++
 4 files changed, 90 insertions(+), 12 deletions(-)

diff --git a/configure.ac b/configure.ac
index fbee76211..7587f311e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2095,6 +2095,10 @@ if test "x$GLAMOR" = xyes; then
 			[AC_DEFINE(GLAMOR_HAS_GBM_LINEAR, 1, [Have GBM_BO_USE_LINEAR])], [],
 			[#include <stdlib.h>
 			 #include <gbm.h>])
+		dnl 17.1.0 is required for gbm_bo_create_with_modifiers
+		PKG_CHECK_EXISTS(gbm >= 17.1.0,
+				 [AC_DEFINE(GBM_BO_WITH_MODIFIERS, 1, [Have gbm_bo_create_with_modifiers])],
+				 [])
 	else
 		if test "x$XORG" = xyes; then
 			AC_MSG_ERROR([Glamor for Xorg requires $LIBGBM])
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 8bd050308..af956a05d 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -294,9 +294,11 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap)
         glamor_get_pixmap_private(pixmap);
     unsigned width = pixmap->drawable.width;
     unsigned height = pixmap->drawable.height;
+    uint64_t modifier = 0;
     struct gbm_bo *bo;
     PixmapPtr exported;
     GCPtr scratch_gc;
+    Bool ret = FALSE;
 
     if (pixmap_priv->image)
         return TRUE;
@@ -308,13 +310,31 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap)
         return FALSE;
     }
 
-    bo = gbm_bo_create(glamor_egl->gbm, width, height,
-                       GBM_FORMAT_ARGB8888,
+#ifdef GBM_BO_WITH_MODIFIERS
+    if (glamor_egl->modifiers_capable) {
+        uint32_t num_modifiers;
+        uint64_t *modifiers = NULL;
+
+        glamor_get_modifiers(screen, DRM_FORMAT_ARGB8888,
+                             &num_modifiers, &modifiers);
+        bo = gbm_bo_create_with_modifiers(glamor_egl->gbm, width, height,
+                                          GBM_FORMAT_ARGB8888,
+                                          modifiers, num_modifiers);
+        modifier = gbm_bo_get_modifier(bo);
+        free(modifiers);
+    }
+    else
+#endif
+    {
+        bo = gbm_bo_create(glamor_egl->gbm, width, height,
+                GBM_FORMAT_ARGB8888,
 #ifdef GLAMOR_HAS_GBM_LINEAR
-                       (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
-                        GBM_BO_USE_LINEAR : 0) |
+                (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
+                 GBM_BO_USE_LINEAR : 0) |
 #endif
-                       GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+                GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+    }
+
     if (!bo) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR,
                    "Failed to make %dx%dx%dbpp GBM bo\n",
@@ -325,15 +345,45 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap)
     exported = screen->CreatePixmap(screen, 0, 0, pixmap->drawable.depth, 0);
     screen->ModifyPixmapHeader(exported, width, height, 0, 0,
                                gbm_bo_get_stride(bo), NULL);
-    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo)) {
+
+    if (modifier) {
+#ifdef GBM_BO_WITH_MODIFIERS
+        // XXX Check if multi planes is supported
+        int i, num_fds, fds[4];
+        uint32_t strides[4], offsets[4];
+        uint32_t format;
+
+        format = drm_format_for_depth(pixmap->drawable.bitsPerPixel,
+                                      pixmap->drawable.depth);
+        num_fds = gbm_bo_get_plane_count(bo);
+        for (i = 0; i < num_fds; i++) {
+            fds[i] = gbm_bo_get_fd(bo); // All planes use same fd
+            strides[i] = gbm_bo_get_stride_for_plane(bo, i);
+            offsets[i] = gbm_bo_get_offset(bo, i);
+        }
+        ret = glamor_egl_create_textured_pixmap_from_dmabuf(exported,
+                                                            num_fds, fds,
+                                                            width, height,
+                                                            strides, offsets,
+                                                            format, modifier);
+        if (!ret) {
+            for (i = 0; i < num_fds; i++)
+                close(fds[i]);
+        }
+#endif
+    } else {
+        ret = glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo);
+    }
+
+    gbm_bo_destroy(bo);
+
+    if (!ret) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR,
                    "Failed to make %dx%dx%dbpp pixmap from GBM bo\n",
                    width, height, pixmap->drawable.bitsPerPixel);
         screen->DestroyPixmap(exported);
-        gbm_bo_destroy(bo);
         return FALSE;
     }
-    gbm_bo_destroy(bo);
 
     scratch_gc = GetScratchGC(pixmap->drawable.depth, screen);
     ValidateGC(&pixmap->drawable, scratch_gc);
@@ -484,7 +534,7 @@ glamor_pixmap_from_fds(ScreenPtr screen,
     pixmap = screen->CreatePixmap(screen, 0, 0, info->depth, 0);
 
     if (glamor_egl->dmabuf_capable) {
-        screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL); // XXX what is the stride used for?
+        screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL);
         ret = glamor_egl_create_textured_pixmap_from_dmabuf(pixmap, num_fds, fds,
                                                             width, height,
                                                             strides, offsets,
@@ -608,6 +658,7 @@ _X_EXPORT void
 glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 {
     EGLImageKHR temp;
+    struct glamor_pixmap_dmabuf *tmp_dmabuf;
     struct glamor_pixmap_private *front_priv =
         glamor_get_pixmap_private(front);
     struct glamor_pixmap_private *back_priv =
@@ -619,6 +670,10 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
     back_priv->image = front_priv->image;
     front_priv->image = temp;
 
+    tmp_dmabuf = back_priv->dmabuf;
+    back_priv->dmabuf = front_priv->dmabuf;
+    front_priv->dmabuf = tmp_dmabuf;
+
     glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
 }
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 78fe11103..e1d96a42e 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -277,14 +277,30 @@ xwl_glamor_create_pixmap(ScreenPtr screen,
 {
     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
     struct gbm_bo *bo;
+    uint32_t format;
 
     if (width > 0 && height > 0 && depth >= 15 &&
         (hint == 0 ||
          hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP ||
          hint == CREATE_PIXMAP_USAGE_SHARED)) {
-        bo = gbm_bo_create(xwl_screen->gbm, width, height,
-                           gbm_format_for_depth(depth),
-                           GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+        format = gbm_format_for_depth(depth);
+
+#ifdef GBM_BO_WITH_MODIFIERS
+        if (xwl_screen->modifiers_capable) {
+            uint32_t num_modifiers;
+            uint64_t *modifiers = NULL;
+
+            glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
+            bo = gbm_bo_create_with_modifiers(xwl_screen->gbm, width, height,
+                                              format, modifiers, num_modifiers);
+            free(modifiers);
+        }
+        else
+#endif
+        {
+            bo = gbm_bo_create(xwl_screen->gbm, width, height, format,
+                               GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+        }
 
         if (bo)
             return xwl_glamor_create_pixmap_for_bo(screen, bo, depth, format);
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index ad1ab20a6..57aee61fd 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -497,6 +497,9 @@
 /* Build glamor/gbm has linear support */
 #undef GLAMOR_HAS_GBM_LINEAR
 
+/* GBM has modifiers support */
+#undef GBM_BO_WITH_MODIFIERS
+
 /* Build glamor use new drmGetDeviceNameFromFD2 */
 #undef GLAMOR_HAS_DRM_NAME_FROM_FD_2
 
-- 
2.13.0



More information about the xorg-devel mailing list