[vlc-commits] xcb/x11: clean up search for X11 visual

Rémi Denis-Courmont git at videolan.org
Wed Dec 19 20:11:39 CET 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Dec 19 18:51:32 2018 +0200| [3d5c12104cc482493b55159b00ca175a2919ba98] | committer: Rémi Denis-Courmont

xcb/x11: clean up search for X11 visual

Pixmap formats are not indicative of what the screen can actually show.
For instance, 1 bit formats are typically used for pixel masks, but can
not be painted.

Instead look for a supported depth, then a supported visual for that
depth. Also check (in the previous commit helper) the RGB masks actually
corresponds to a VLC pixel format. We would not want to treat
R10G10B10A2 as R8B8G8A8.

This changeset effectively drops RGBA support for the time being.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3d5c12104cc482493b55159b00ca175a2919ba98
---

 modules/video_output/xcb/x11.c | 162 ++++++++++++-----------------------------
 1 file changed, 48 insertions(+), 114 deletions(-)

diff --git a/modules/video_output/xcb/x11.c b/modules/video_output/xcb/x11.c
index de6d77e245..c885d3b030 100644
--- a/modules/video_output/xcb/x11.c
+++ b/modules/video_output/xcb/x11.c
@@ -214,19 +214,50 @@ static void Close(vout_display_t *vd)
     free(sys);
 }
 
-static const xcb_depth_t *FindDepth (const xcb_screen_t *scr,
-                                     uint_fast8_t depth)
+static xcb_visualid_t DepthToFormat(const xcb_setup_t *setup,
+                                    const xcb_depth_t *depth,
+                                    video_format_t *restrict f)
 {
-    xcb_depth_t *d = NULL;
-    for (xcb_depth_iterator_t it = xcb_screen_allowed_depths_iterator (scr);
-         it.rem > 0 && d == NULL;
-         xcb_depth_next (&it))
+    /* Check visual types for the selected depth */
+    const xcb_visualtype_t *vt = xcb_depth_visuals(depth);
+
+    for (int i = xcb_depth_visuals_length(depth); i > 0; i--, vt++)
+        if (vlc_xcb_VisualToFormat(setup, depth->depth, vt, f))
+            return vt->visual_id;
+
+    return 0;
+}
+
+static xcb_visualid_t ScreenToFormat(const xcb_setup_t *setup,
+                                     const xcb_screen_t *screen,
+                                     uint8_t *restrict bits,
+                                     video_format_t *restrict fmtp)
+{
+    xcb_visualid_t visual = 0;
+
+    *bits = 0;
+
+    for (xcb_depth_iterator_t it = xcb_screen_allowed_depths_iterator(screen);
+         it.rem > 0;
+         xcb_depth_next(&it))
     {
-        if (it.data->depth == depth)
-            d = it.data;
-    }
+        const xcb_depth_t *depth = it.data;
+        video_format_t fmt;
+        xcb_visualid_t vid;
+
+        if (depth->depth <= *bits)
+            continue; /* no better than earlier depth */
 
-    return d;
+        video_format_ApplyRotation(&fmt, fmtp);
+        vid = DepthToFormat(setup, depth, &fmt);
+        if (vid != 0)
+        {
+            *bits = depth->depth;
+            *fmtp = fmt;
+            visual = vid;
+        }
+    }
+    return visual;
 }
 
 /**
@@ -254,112 +285,15 @@ static int Open (vout_display_t *vd, const vout_display_cfg_t *cfg,
     const xcb_setup_t *setup = xcb_get_setup (conn);
 
     /* Determine our pixel format */
-    video_format_t fmt_pic;
-    xcb_visualid_t vid = 0;
-    sys->depth = 0;
-
-    for (const xcb_format_t *fmt = xcb_setup_pixmap_formats (setup),
-             *end = fmt + xcb_setup_pixmap_formats_length (setup);
-         fmt < end;
-         fmt++)
-    {
-        if (fmt->depth <= sys->depth)
-            continue; /* no better than earlier format */
-
-        video_format_ApplyRotation(&fmt_pic, fmtp);
-
-        /* Check that the pixmap format is supported by VLC. */
-        switch (fmt->depth)
-        {
-          case 32:
-            if (fmt->bits_per_pixel != 32)
-                continue;
-            fmt_pic.i_chroma = VLC_CODEC_ARGB;
-            break;
-          case 24:
-            if (fmt->bits_per_pixel == 32)
-                fmt_pic.i_chroma = VLC_CODEC_RGB32;
-            else if (fmt->bits_per_pixel == 24)
-                fmt_pic.i_chroma = VLC_CODEC_RGB24;
-            else
-                continue;
-            break;
-          case 16:
-            if (fmt->bits_per_pixel != 16)
-                continue;
-            fmt_pic.i_chroma = VLC_CODEC_RGB16;
-            break;
-          case 15:
-            if (fmt->bits_per_pixel != 16)
-                continue;
-            fmt_pic.i_chroma = VLC_CODEC_RGB15;
-            break;
-          case 8:
-            if (fmt->bits_per_pixel != 8)
-                continue;
-            fmt_pic.i_chroma = VLC_CODEC_RGB8;
-            break;
-          default:
-            continue;
-        }
-
-        /* Byte sex is a non-issue for 8-bits. It can be worked around with
-         * RGB masks for 24-bits. Too bad for 15-bits and 16-bits. */
-        if (fmt->bits_per_pixel == 16 && setup->image_byte_order != ORDER)
-            continue;
-
-        /* Make sure the X server is sane */
-        assert (fmt->bits_per_pixel > 0);
-        if (unlikely(fmt->scanline_pad % fmt->bits_per_pixel))
-            continue;
-
-        /* Check that the selected screen supports this depth */
-        const xcb_depth_t *d = FindDepth (scr, fmt->depth);
-        if (d == NULL)
-            continue;
-
-        /* Find a visual type for the selected depth */
-        const xcb_visualtype_t *vt = xcb_depth_visuals (d);
-
-        /* First try True Color class */
-        for (int i = xcb_depth_visuals_length (d); i > 0; i--)
-        {
-            if (vt->_class == XCB_VISUAL_CLASS_TRUE_COLOR)
-            {
-                fmt_pic.i_rmask = vt->red_mask;
-                fmt_pic.i_gmask = vt->green_mask;
-                fmt_pic.i_bmask = vt->blue_mask;
-            found_visual:
-                vid = vt->visual_id;
-                msg_Dbg (vd, "using X11 visual ID 0x%"PRIx32, vid);
-                sys->depth = fmt->depth;
-                msg_Dbg (vd, " %"PRIu8" bits depth", sys->depth);
-                msg_Dbg (vd, " %"PRIu8" bits per pixel", fmt->bits_per_pixel);
-                msg_Dbg (vd, " %"PRIu8" bits line pad", fmt->scanline_pad);
-                goto found_format;
-            }
-            vt++;
-        }
-
-        /* Then try Static Gray class */
-        if (fmt->depth != 8)
-            continue;
-        vt = xcb_depth_visuals (d);
-        for (int i = xcb_depth_visuals_length (d); i > 0 && !vid; i--)
-        {
-            if (vt->_class == XCB_VISUAL_CLASS_STATIC_GRAY)
-            {
-                fmt_pic.i_chroma = VLC_CODEC_GREY;
-                goto found_visual;
-            }
-            vt++;
-        }
+    xcb_visualid_t vid = ScreenToFormat(setup, scr, &sys->depth, fmtp);
+    if (vid == 0) {
+        msg_Err(vd, "no supported visual & pixel format");
+        goto error;
     }
 
-    msg_Err (vd, "no supported pixel format & visual");
-    goto error;
+    msg_Dbg(vd, "using X11 visual ID 0x%"PRIx32, vid);
+    msg_Dbg(vd, " %"PRIu8" bits depth", sys->depth);
 
-found_format:;
     /* Create colormap (needed to select non-default visual) */
     xcb_colormap_t cmap;
     if (vid != scr->root_visual)
@@ -417,7 +351,7 @@ found_format:;
     else
         sys->segment = 0;
 
-    sys->fmt = *fmtp = fmt_pic;
+    sys->fmt = *fmtp;
     /* Setup vout_display_t once everything is fine */
     vd->info.has_pictures_invalid = true;
 



More information about the vlc-commits mailing list