[vlc-commits] xcb/render: add MIT-SHM support

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


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Dec 19 00:12:30 2018 +0200| [9b8f1c2983b1e6c01d7052bfd60ac11b56c20aa2] | committer: Rémi Denis-Courmont

xcb/render: add MIT-SHM support

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

 modules/video_output/xcb/render.c | 66 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 61 insertions(+), 5 deletions(-)

diff --git a/modules/video_output/xcb/render.c b/modules/video_output/xcb/render.c
index 75b41bfd16..461a736771 100644
--- a/modules/video_output/xcb/render.c
+++ b/modules/video_output/xcb/render.c
@@ -30,8 +30,10 @@
 
 #include <xcb/xcb.h>
 #include <xcb/render.h>
+#include <xcb/shm.h>
 
 #include <vlc_common.h>
+#include <vlc_fs.h>
 #include <vlc_plugin.h>
 #include <vlc_vout_display.h>
 
@@ -55,6 +57,7 @@ struct vout_display_sys_t {
     } picture;
 
     xcb_gcontext_t gc;
+    xcb_shm_seg_t segment;
     xcb_window_t root;
     xcb_render_pictformat_t fmt_id;
 
@@ -63,6 +66,38 @@ struct vout_display_sys_t {
     int32_t src_y;
 };
 
+static size_t PictureAttach(vout_display_t *vd, picture_t *pic)
+{
+    vout_display_sys_t *sys = vd->sys;
+    xcb_connection_t *conn = sys->conn;
+    xcb_shm_seg_t segment = sys->segment;
+    const picture_buffer_t *buf = pic->p_sys;
+
+    if (segment == 0  /* SHM extension not supported */
+     || buf->fd == -1 /* picture buffer not in shared memory */)
+        return -1;
+
+    int fd = vlc_dup(buf->fd);
+    if (fd == -1)
+        return -1;
+
+    xcb_void_cookie_t c = xcb_shm_attach_fd_checked(conn, segment, fd, 1);
+    xcb_generic_error_t *e = xcb_request_check(conn, c);
+    if (e != NULL) /* attach failure (likely remote access) */
+    {
+        free(e);
+        return -1;
+    }
+    return buf->offset;
+}
+
+static void PictureDetach(vout_display_t *vd)
+{
+    vout_display_sys_t *sys = vd->sys;
+
+    xcb_shm_detach(sys->conn, sys->segment);
+}
+
 static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
                     vlc_tick_t date)
 {
@@ -70,10 +105,24 @@ static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
     vout_display_sys_t *sys = vd->sys;
     xcb_connection_t *conn = sys->conn;
 
-    xcb_put_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, sys->drawable.source,
-                  sys->gc, pic->p->i_pitch / pic->p->i_pixel_pitch,
-                  pic->p->i_lines, 0, 0, 0, 32,
-                  pic->p->i_pitch * pic->p->i_lines, pic->p->p_pixels);
+    size_t offset = PictureAttach(vd, pic);
+    if (offset != (size_t)-1) {
+        xcb_shm_put_image_checked(conn, sys->drawable.source, sys->gc,
+                                  pic->p->i_pitch / pic->p->i_pixel_pitch,
+                                  pic->p->i_lines,
+                                  0,
+                                  0,
+                      /* width */ pic->p->i_pitch / pic->p->i_pixel_pitch,
+                     /* height */ pic->p->i_lines,
+                                  0, 0, 32, XCB_IMAGE_FORMAT_Z_PIXMAP,
+                                  0, sys->segment, offset);
+    } else {
+        xcb_put_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, sys->drawable.source,
+                      sys->gc, pic->p->i_pitch / pic->p->i_pixel_pitch,
+                      pic->p->i_lines, 0, 0, 0, 32,
+                      pic->p->i_pitch * pic->p->i_lines, pic->p->p_pixels);
+    }
+
     /* Crop the picture with pixel accuracy */
     xcb_render_composite(conn, XCB_RENDER_PICT_OP_SRC,
                          sys->picture.source, XCB_RENDER_PICTURE_NONE,
@@ -97,7 +146,9 @@ static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
                          sys->picture.scale, sys->src_x, sys->src_y, 0, 0,
                          sys->place.x, sys->place.y,
                          sys->place.width, sys->place.height);
-
+    if (offset != (size_t)-1)
+        PictureDetach(vd);
+    xcb_flush(conn);
     (void) subpic; (void) date;
 }
 
@@ -484,6 +535,11 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
     sys->picture.dest = xcb_generate_id(conn);
     sys->gc = xcb_generate_id(conn);
 
+    if (XCB_shm_Check(obj, conn))
+        sys->segment = xcb_generate_id(conn);
+    else
+        sys->segment = 0;
+
     xcb_colormap_t cmap = xcb_generate_id(conn);
     uint32_t cw_mask =
         XCB_CW_BACK_PIXEL |



More information about the vlc-commits mailing list