vlc | branch: master | Rémi Denis-Courmont <[email protected]> | 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; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
