[PATCH xserver 3/7] glamor: Track if BO allocation used modifiers

Daniel Stone daniels at collabora.com
Wed Apr 4 15:16:34 UTC 2018


Keep track of whether or not we fed modifiers into GBM when we allocated
a BO. We'll use this later inside Glamor, to reallocate buffer storage
if we allocate buffer storage using modifiers, and a non-modifier-aware
client requests an export of that pixmap.

This makes it possible to run a compositing manager on an old GLX/EGL
stack on top of an X server which allocates internal buffer storage
using exotic modifiers from modifier-aware GBM/EGL/KMS.

Signed-off-by: Daniel Stone <daniels at collabora.com>
Reported-by: Adam Jackson <ajax at redhat.com>
---
 glamor/glamor.h                               |  3 +-
 glamor/glamor_egl.c                           | 29 +++++++++++++------
 glamor/glamor_priv.h                          |  1 +
 .../drivers/modesetting/drmmode_display.c     |  3 +-
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 7b5676226..b0b23d3a3 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -391,7 +391,8 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
  */
 extern _X_EXPORT Bool
  glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
-                                               struct gbm_bo *bo);
+                                               struct gbm_bo *bo,
+                                               Bool used_modifiers);
 
 #endif
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index f82fa519b..0e771b6d2 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -150,7 +150,8 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 }
 
 static void
-glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
+glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image,
+                            Bool used_modifiers)
 {
     struct glamor_pixmap_private *pixmap_priv =
         glamor_get_pixmap_private(pixmap);
@@ -165,6 +166,7 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
         eglDestroyImageKHR(glamor_egl->display, old);
     }
     pixmap_priv->image = image;
+    pixmap_priv->used_modifiers = used_modifiers;
 }
 
 Bool
@@ -204,7 +206,8 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 
 Bool
 glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
-                                              struct gbm_bo *bo)
+                                              struct gbm_bo *bo,
+                                              Bool used_modifiers)
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@@ -229,7 +232,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(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_egl_set_pixmap_image(pixmap, image);
+    glamor_egl_set_pixmap_image(pixmap, image, used_modifiers);
     ret = TRUE;
 
  done:
@@ -259,6 +262,7 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap)
     unsigned height = pixmap->drawable.height;
     uint32_t format;
     struct gbm_bo *bo;
+    Bool used_modifiers = FALSE;
     PixmapPtr exported;
     GCPtr scratch_gc;
 
@@ -286,6 +290,8 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap)
 
         bo = gbm_bo_create_with_modifiers(glamor_egl->gbm, width, height,
                                           format, modifiers, num_modifiers);
+        if (bo)
+            used_modifiers = TRUE;
         free(modifiers);
     }
     else
@@ -309,7 +315,8 @@ 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 (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo,
+                                                       used_modifiers)) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR,
                    "Failed to make %dx%dx%dbpp pixmap from GBM bo\n",
                    width, height, pixmap->drawable.bitsPerPixel);
@@ -452,7 +459,7 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
 
     screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL);
 
-    ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
+    ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo, FALSE);
     gbm_bo_destroy(bo);
     return ret;
 }
@@ -509,7 +516,7 @@ glamor_pixmap_from_fds(ScreenPtr screen,
         bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER, &import_data, 0);
         if (bo) {
             screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL);
-            ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
+            ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo, TRUE);
             gbm_bo_destroy(bo);
         }
     } else
@@ -667,7 +674,8 @@ glamor_egl_destroy_pixmap(PixmapPtr pixmap)
 _X_EXPORT void
 glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 {
-    EGLImageKHR temp;
+    EGLImageKHR temp_img;
+    Bool temp_mod;
     struct glamor_pixmap_private *front_priv =
         glamor_get_pixmap_private(front);
     struct glamor_pixmap_private *back_priv =
@@ -675,9 +683,12 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 
     glamor_pixmap_exchange_fbos(front, back);
 
-    temp = back_priv->image;
+    temp_img = back_priv->image;
+    temp_mod = back_priv->used_modifiers;
     back_priv->image = front_priv->image;
-    front_priv->image = temp;
+    back_priv->used_modifiers = front_priv->used_modifiers;
+    front_priv->image = temp_img;
+    front_priv->used_modifiers = temp_mod;
 
     glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 3fff6396c..7d9a7d4fb 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -341,6 +341,7 @@ typedef struct glamor_pixmap_private {
     Bool prepared;
 #ifdef GLAMOR_HAS_GBM
     EGLImageKHR image;
+    Bool used_modifiers;
 #endif
     /** block width of this large pixmap. */
     int block_w;
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index aeb44263b..0eacefba2 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -3146,7 +3146,8 @@ drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
     if (!drmmode->glamor)
         return TRUE;
 
-    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
+    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm,
+                                                       bo->used_modifiers)) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create pixmap\n");
         return FALSE;
     }
-- 
2.17.0



More information about the xorg-devel mailing list