[vlc-commits] xcb/x11: use normal picture buffers

Rémi Denis-Courmont git at videolan.org
Sun Dec 9 20:46:08 CET 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Dec  9 19:33:42 2018 +0200| [f1649ea3f31d06cdd87a07f88196aa0e83c46423] | committer: Rémi Denis-Courmont

xcb/x11: use normal picture buffers

Get rid of the custom allocator.

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

 modules/video_output/xcb/x11.c | 98 ++++++++++++++++++------------------------
 1 file changed, 43 insertions(+), 55 deletions(-)

diff --git a/modules/video_output/xcb/x11.c b/modules/video_output/xcb/x11.c
index c65e062aae..d8443fcfa4 100644
--- a/modules/video_output/xcb/x11.c
+++ b/modules/video_output/xcb/x11.c
@@ -31,6 +31,7 @@
 #include <xcb/shm.h>
 
 #include <vlc_common.h>
+#include <vlc_fs.h>
 #include <vlc_plugin.h>
 #include <vlc_vout_display.h>
 #include <vlc_picture_pool.h>
@@ -44,7 +45,8 @@ struct vout_display_sys_t
 
     xcb_window_t window; /* drawable X window */
     xcb_gcontext_t gc; /* context to put images */
-    xcb_shm_seg_t seg_base; /**< shared memory segment XID base */
+    xcb_shm_seg_t segment; /**< shared memory segment XID */
+    bool attached;
     bool visible; /* whether to draw */
     uint8_t depth; /* useful bits per pixel */
 
@@ -63,51 +65,40 @@ struct vout_display_sys_t
 static picture_pool_t *Pool(vout_display_t *vd, unsigned requested_count)
 {
     vout_display_sys_t *sys = vd->sys;
-    (void)requested_count;
 
-    if (sys->pool)
-        return sys->pool;
+    if (sys->pool == NULL)
+        sys->pool = picture_pool_NewFromFormat(&vd->fmt, requested_count);
+    return sys->pool;
+}
 
-    picture_t *pic = picture_NewFromFormat(&vd->fmt);
-    if (!pic)
-        return NULL;
+static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
+                    vlc_tick_t date)
+{
+    vout_display_sys_t *sys = vd->sys;
+    const picture_buffer_t *buf = pic->p_sys;
+    xcb_connection_t *conn = sys->conn;
 
-    assert (pic->i_planes == 1);
+    sys->attached = false;
 
-    picture_resource_t res = {
-        .p = {
-            [0] = {
-                .i_lines = pic->p->i_lines,
-                .i_pitch = pic->p->i_pitch,
-            },
-        },
-    };
-    picture_Release (pic);
+    if (sys->segment == 0)
+        return; /* SHM extension not supported */
+    if (buf->fd == -1)
+        return; /* not a shareable picture buffer */
 
-    unsigned count;
-    picture_t *pic_array[MAX_PICTURES];
-    const size_t size = res.p->i_pitch * res.p->i_lines;
-    for (count = 0; count < MAX_PICTURES; count++)
-    {
-        xcb_shm_seg_t seg = (sys->seg_base != 0) ? (sys->seg_base + count) : 0;
+    int fd = vlc_dup(buf->fd);
+    if (fd == -1)
+        return;
 
-        if (XCB_picture_Alloc(vd, &res, size, sys->conn, seg))
-            break;
-        pic_array[count] = XCB_picture_NewFromResource(&vd->fmt, &res,
-                                                       sys->conn);
-        if (unlikely(pic_array[count] == NULL))
-            break;
+    xcb_void_cookie_t c = xcb_shm_attach_fd_checked(conn, sys->segment, fd, 1);
+    xcb_generic_error_t *e = xcb_request_check(conn, c);
+    if (e != NULL) /* attach failure (likely remote access) */
+    {
+        free(e);
+        return;
     }
-    xcb_flush(sys->conn);
 
-    if (count == 0)
-        return NULL;
-
-    sys->pool = picture_pool_New(count, pic_array);
-    if (unlikely(sys->pool == NULL))
-        while (count > 0)
-            picture_Release(pic_array[--count]);
-    return sys->pool;
+    sys->attached = true;
+    (void) subpic; (void) date;
 }
 
 /**
@@ -116,15 +107,17 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned requested_count)
 static void Display (vout_display_t *vd, picture_t *pic)
 {
     vout_display_sys_t *sys = vd->sys;
-    xcb_shm_seg_t segment = XCB_picture_GetSegment(pic);
+    xcb_connection_t *conn = sys->conn;
+    const picture_buffer_t *buf = pic->p_sys;
+    xcb_shm_seg_t segment = sys->segment;
     xcb_void_cookie_t ck;
 
     vlc_xcb_Manage(vd, sys->conn, &sys->visible);
 
     if (sys->visible)
     {
-        if (segment != 0)
-            ck = xcb_shm_put_image_checked(sys->conn, sys->window, sys->gc,
+        if (sys->attached)
+            ck = xcb_shm_put_image_checked(conn, sys->window, sys->gc,
               /* real width */ pic->p->i_pitch / pic->p->i_pixel_pitch,
              /* real height */ pic->p->i_lines,
                        /* x */ sys->fmt.i_x_offset,
@@ -132,13 +125,13 @@ static void Display (vout_display_t *vd, picture_t *pic)
                    /* width */ sys->fmt.i_visible_width,
                   /* height */ sys->fmt.i_visible_height,
                                0, 0, sys->depth, XCB_IMAGE_FORMAT_Z_PIXMAP,
-                               0, segment, 0);
+                               0, segment, buf->offset);
         else
         {
             const size_t offset = sys->fmt.i_y_offset * pic->p->i_pitch;
             const unsigned lines = pic->p->i_lines - sys->fmt.i_y_offset;
 
-            ck = xcb_put_image_checked(sys->conn, XCB_IMAGE_FORMAT_Z_PIXMAP,
+            ck = xcb_put_image_checked(conn, XCB_IMAGE_FORMAT_Z_PIXMAP,
                                sys->window, sys->gc,
                                pic->p->i_pitch / pic->p->i_pixel_pitch,
                                lines, -sys->fmt.i_x_offset, 0, 0, sys->depth,
@@ -151,7 +144,7 @@ static void Display (vout_display_t *vd, picture_t *pic)
          * with shared memory the PUT requests are so short that many of them
          * can fit in X11 socket output buffer before the kernel preempts VLC.
          */
-        xcb_generic_error_t *e = xcb_request_check(sys->conn, ck);
+        xcb_generic_error_t *e = xcb_request_check(conn, ck);
         if (e != NULL)
         {
             msg_Dbg(vd, "%s: X11 error %d", "cannot put image", e->error_code);
@@ -162,6 +155,9 @@ static void Display (vout_display_t *vd, picture_t *pic)
     /* FIXME might be WAY better to wait in some case (be carefull with
      * VOUT_DISPLAY_RESET_PICTURES if done) + does not work with
      * vout_display wrapper. */
+
+    if (sys->attached)
+        xcb_shm_detach(conn, segment);
 }
 
 static void ResetPictures(vout_display_t *vd)
@@ -171,10 +167,6 @@ static void ResetPictures(vout_display_t *vd)
     if (!sys->pool)
         return;
 
-    if (sys->seg_base != 0)
-        for (unsigned i = 0; i < MAX_PICTURES; i++)
-            xcb_shm_detach(sys->conn, sys->seg_base + i);
-
     picture_pool_Release(sys->pool);
     sys->pool = NULL;
 }
@@ -451,20 +443,16 @@ found_format:;
 
     sys->visible = false;
     if (XCB_shm_Check (VLC_OBJECT(vd), conn))
-    {
-        sys->seg_base = xcb_generate_id (conn);
-        for (unsigned i = 1; i < MAX_PICTURES; i++)
-             xcb_generate_id (conn);
-    }
+        sys->segment = xcb_generate_id(conn);
     else
-        sys->seg_base = 0;
+        sys->segment = 0;
 
     sys->fmt = *fmtp = fmt_pic;
     /* Setup vout_display_t once everything is fine */
     vd->info.has_pictures_invalid = true;
 
     vd->pool = Pool;
-    vd->prepare = NULL;
+    vd->prepare = Prepare;
     vd->display = Display;
     vd->control = Control;
 



More information about the vlc-commits mailing list