[PATCH xserver 3/3] modesetting/drmmode: Use drmModeGetFB2

Daniel Stone daniels at collabora.com
Fri Mar 23 13:50:25 UTC 2018


Much like AddFB -> AddFB2, GetFB2 lets us get multiple buffers back as
well as modifier information. This lets us use -background none with
multiplanar formats, or modifiers which can't be inferred via a magic
side channel.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 hw/xfree86/drivers/modesetting/drmmode_display.c | 65 ++++++++++++++++++------
 1 file changed, 50 insertions(+), 15 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 39ed16f98..82ea49386 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1080,9 +1080,13 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int fbcon_id)
 {
     PixmapPtr pixmap = drmmode->fbcon_pixmap;
     drmModeFBPtr fbcon;
+    drmModeFB2Ptr fbcon2;
     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
     uint32_t handles[4] = { 0, };
     CARD32 strides[4] = { 0, }, offsets[4] = { 0, };
+    uint64_t modifier;
+    int width, height;
+    int depth = 0, bpp = 0;
     int fds[4] = { -1, -1, -1, -1 };
     int num_fds;
     int i;
@@ -1090,31 +1094,63 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int fbcon_id)
     if (pixmap)
         return pixmap;
 
-    fbcon = drmModeGetFB(drmmode->fd, fbcon_id);
-    if (fbcon == NULL)
-        return NULL;
+    fbcon2 = drmModeGetFB2(drmmode->fd, fbcon_id);
+    if (fbcon2) {
+        width = fbcon2->width;
+        height = fbcon2->height;
+        memcpy(handles, fbcon2->handles, sizeof(handles));
+        memcpy(strides, fbcon2->pitches, sizeof(strides));
+        memcpy(offsets, fbcon2->offsets, sizeof(offsets));
+        modifier = fbcon2->modifier;
+        switch (fbcon2->pixel_format) {
+        case DRM_FORMAT_RGB565:
+            depth = 16;
+            break;
+        case DRM_FORMAT_XRGB8888:
+            depth = 24;
+            bpp = 32;
+            break;
+        case DRM_FORMAT_XRGB2101010:
+            depth = 30;
+            bpp = 32;
+        default:
+            break;
+        }
+        drmModeFreeFB2(fbcon2);
+    }
+    else {
+        fbcon = drmModeGetFB(drmmode->fd, fbcon_id);
+        if (fbcon == NULL)
+            return NULL;
+
+        width = fbcon->width;
+        height = fbcon->height;
+        handles[0] = fbcon->handle;
+        strides[0] = fbcon->pitch;
+        modifier = DRM_FORMAT_MOD_INVALID;
+        depth = fbcon->depth;
+        bpp = fbcon->bpp;
 
-    if (fbcon->depth != pScrn->depth ||
-        fbcon->width != pScrn->virtualX ||
-        fbcon->height != pScrn->virtualY)
-        goto out_free_fb;
+        drmModeFreeFB(fbcon);
+    }
+
+    if (depth != pScrn->depth ||
+        width != pScrn->virtualX || height != pScrn->virtualY)
+        goto out;
 
     /* GBM doesn't have an import path from handles, so we make a
      * dma-buf fd from it and then go through that.
      */
-    handles[0] = fbcon->handle;
     num_fds = handles_to_fds(drmmode, handles, fds);
     if (num_fds == 0) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                    "Failed to make prime FD for handle: %d\n", errno);
-        goto out_free_fb;
+        goto out;
     }
-    strides[0] = fbcon->pitch;
 
     pixmap = glamor_pixmap_from_fds(pScreen, num_fds, fds,
-                                    fbcon->width, fbcon->height,
-                                    strides, offsets, fbcon->depth,
-                                    fbcon->bpp, DRM_FORMAT_MOD_INVALID);
+                                    width, height, strides, offsets,
+                                    depth, bpp, modifier);
     if (!pixmap)
         goto out_close_fds;
 
@@ -1124,8 +1160,7 @@ out_close_fds:
         if (fds[i] != -1)
             close(fds[i]);
     }
-out_free_fb:
-    drmModeFreeFB(fbcon);
+out:
     return pixmap;
 }
 #endif
-- 
2.16.2



More information about the xorg-devel mailing list