Commit 776fb1cb authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

XCB: use custom picture destroy callback, simplify

parent e3764808
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#ifdef HAVE_SYS_SHM_H #ifdef HAVE_SYS_SHM_H
# include <sys/shm.h> # include <sys/shm.h>
# include <sys/stat.h> # include <sys/stat.h>
#else
# define shmdt(mem) free(mem)
#endif #endif
#include <xcb/xcb.h> #include <xcb/xcb.h>
...@@ -65,27 +67,31 @@ bool XCB_shm_Check (vlc_object_t *obj, xcb_connection_t *conn) ...@@ -65,27 +67,31 @@ bool XCB_shm_Check (vlc_object_t *obj, xcb_connection_t *conn)
return false; return false;
} }
/**
* Release picture private data: detach the shared memory segment.
*/
static void XCB_picture_Destroy (picture_t *pic)
{
shmdt (pic->p[0].p_pixels);
free (pic);
}
/** /**
* Initialize a picture buffer as shared memory, according to the video output * Initialize a picture buffer as shared memory, according to the video output
* format. If a attach is true, the segment is attached to * format. If a attach is true, the segment is attached to
* the X server (MIT-SHM extension). * the X server (MIT-SHM extension).
*/ */
void *XCB_pictures_Alloc (vout_display_t *vd, picture_sys_t **sysp, int XCB_picture_Alloc (vout_display_t *vd, picture_resource_t *res,
size_t size, xcb_connection_t *conn, size_t size, xcb_connection_t *conn,
xcb_shm_seg_t segment) xcb_shm_seg_t segment)
{ {
picture_sys_t *picsys = malloc (sizeof (*picsys));
if (unlikely(picsys == NULL))
return NULL;
#ifdef HAVE_SYS_SHM_H #ifdef HAVE_SYS_SHM_H
/* Allocate shared memory segment */ /* Allocate shared memory segment */
int id = shmget (IPC_PRIVATE, size, IPC_CREAT | S_IRWXU); int id = shmget (IPC_PRIVATE, size, IPC_CREAT | S_IRWXU);
if (id == -1) if (id == -1)
{ {
msg_Err (vd, "shared memory allocation error: %m"); msg_Err (vd, "shared memory allocation error: %m");
free (picsys); return -1;
return NULL;
} }
/* Attach the segment to VLC */ /* Attach the segment to VLC */
...@@ -94,8 +100,7 @@ void *XCB_pictures_Alloc (vout_display_t *vd, picture_sys_t **sysp, ...@@ -94,8 +100,7 @@ void *XCB_pictures_Alloc (vout_display_t *vd, picture_sys_t **sysp,
{ {
msg_Err (vd, "shared memory attachment error: %m"); msg_Err (vd, "shared memory attachment error: %m");
shmctl (id, IPC_RMID, 0); shmctl (id, IPC_RMID, 0);
free (picsys); return -1;
return NULL;
} }
if (segment != 0) if (segment != 0)
...@@ -127,30 +132,25 @@ void *XCB_pictures_Alloc (vout_display_t *vd, picture_sys_t **sysp, ...@@ -127,30 +132,25 @@ void *XCB_pictures_Alloc (vout_display_t *vd, picture_sys_t **sysp,
} }
shmctl (id, IPC_RMID, NULL); shmctl (id, IPC_RMID, NULL);
picsys->segment = segment;
#else #else
assert (!attach); assert (segment == 0);
picsys->segment = 0;
/* XXX: align on 32 bytes for VLC chroma filters */ /* XXX: align on 32 bytes for VLC chroma filters */
void *shm = malloc (size); void *shm = malloc (size);
if (unlikely(shm == NULL)) if (unlikely(shm == NULL))
free (picsys); return -1;
#endif #endif
*sysp = picsys; res->p_sys = (void *)(uintptr_t)segment;
return shm; res->pf_destroy = XCB_picture_Destroy;
res->p[0].p_pixels = shm;
return 0;
} }
/** picture_t *XCB_picture_NewFromResource (const video_format_t *restrict fmt,
* Release picture private data: detach the shared memory segment. const picture_resource_t *restrict res)
*/
void XCB_pictures_Free (void *mem)
{ {
#ifdef HAVE_SYS_SHM_H picture_t *pic = picture_NewFromResource (fmt, res);
if (mem != NULL) if (unlikely(pic == NULL))
shmdt (mem); shmdt (res->p[0].p_pixels);
#else return pic;
free (mem);
#endif
} }
...@@ -31,11 +31,12 @@ ...@@ -31,11 +31,12 @@
#include <xcb/shm.h> #include <xcb/shm.h>
bool XCB_shm_Check (vlc_object_t *obj, xcb_connection_t *conn); bool XCB_shm_Check (vlc_object_t *obj, xcb_connection_t *conn);
int XCB_picture_Alloc (vout_display_t *, picture_resource_t *, size_t size,
xcb_connection_t *, xcb_shm_seg_t);
picture_t *XCB_picture_NewFromResource (const video_format_t *,
const picture_resource_t *);
struct picture_sys_t static inline xcb_shm_seg_t XCB_picture_GetSegment(const picture_t *pic)
{ {
xcb_shm_seg_t segment; return (uintptr_t)pic->p_sys;
}; }
void *XCB_pictures_Alloc (vout_display_t *, picture_sys_t **, size_t size,
xcb_connection_t *, xcb_shm_seg_t);
void XCB_pictures_Free (void *);
...@@ -74,7 +74,6 @@ struct vout_display_sys_t ...@@ -74,7 +74,6 @@ struct vout_display_sys_t
uint8_t depth; /* useful bits per pixel */ uint8_t depth; /* useful bits per pixel */
picture_pool_t *pool; /* picture pool */ picture_pool_t *pool; /* picture pool */
void *segments[MAX_PICTURES];
}; };
static picture_pool_t *Pool (vout_display_t *, unsigned); static picture_pool_t *Pool (vout_display_t *, unsigned);
...@@ -390,29 +389,22 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count) ...@@ -390,29 +389,22 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
}; };
picture_Release (pic); picture_Release (pic);
for (unsigned count = 0; count < MAX_PICTURES; count++)
sys->segments[count] = NULL;
unsigned count; unsigned count;
picture_t *pic_array[MAX_PICTURES]; 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++) for (count = 0; count < MAX_PICTURES; count++)
{ {
xcb_shm_seg_t seg = (sys->seg_base != 0) ? (sys->seg_base + count) : 0; xcb_shm_seg_t seg = (sys->seg_base != 0) ? (sys->seg_base + count) : 0;
res.p[0].p_pixels = XCB_pictures_Alloc (vd, &res.p_sys, if (XCB_picture_Alloc (vd, &res, size, sys->conn, seg))
res.p->i_pitch * res.p->i_lines, sys->conn, seg);
if (res.p[0].p_pixels == NULL)
break; break;
pic_array[count] = picture_NewFromResource (&vd->fmt, &res); pic_array[count] = XCB_picture_NewFromResource (&vd->fmt, &res);
if (!pic_array[count]) if (unlikely(pic_array[count] == NULL))
{ {
free (res.p_sys);
XCB_pictures_Free (res.p[0].p_pixels);
if (seg != 0) if (seg != 0)
xcb_shm_detach (sys->conn, seg); xcb_shm_detach (sys->conn, seg);
break; break;
} }
sys->segments[count] = res.p[0].p_pixels;
} }
if (count == 0) if (count == 0)
...@@ -430,7 +422,7 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count) ...@@ -430,7 +422,7 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
static void Display (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture) static void Display (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
xcb_shm_seg_t segment = pic->p_sys->segment; xcb_shm_seg_t segment = XCB_picture_GetSegment(pic);
xcb_void_cookie_t ck; xcb_void_cookie_t ck;
if (!sys->visible) if (!sys->visible)
...@@ -582,12 +574,10 @@ static void ResetPictures (vout_display_t *vd) ...@@ -582,12 +574,10 @@ static void ResetPictures (vout_display_t *vd)
if (!sys->pool) if (!sys->pool)
return; return;
for (unsigned i = 0; i < MAX_PICTURES; i++) if (sys->seg_base != 0)
{ for (unsigned i = 0; i < MAX_PICTURES; i++)
XCB_pictures_Free (sys->segments[i]);
if (sys->seg_base != 0)
xcb_shm_detach (sys->conn, sys->seg_base + i); xcb_shm_detach (sys->conn, sys->seg_base + i);
}
picture_pool_Delete (sys->pool); picture_pool_Delete (sys->pool);
sys->pool = NULL; sys->pool = NULL;
} }
...@@ -96,7 +96,6 @@ struct vout_display_sys_t ...@@ -96,7 +96,6 @@ struct vout_display_sys_t
xcb_xv_query_image_attributes_reply_t *att; xcb_xv_query_image_attributes_reply_t *att;
picture_pool_t *pool; /* picture pool */ picture_pool_t *pool; /* picture pool */
void *segments[MAX_PICTURES];
}; };
static picture_pool_t *Pool (vout_display_t *, unsigned); static picture_pool_t *Pool (vout_display_t *, unsigned);
...@@ -599,11 +598,7 @@ static void Close (vlc_object_t *obj) ...@@ -599,11 +598,7 @@ static void Close (vlc_object_t *obj)
vout_display_sys_t *p_sys = vd->sys; vout_display_sys_t *p_sys = vd->sys;
if (p_sys->pool) if (p_sys->pool)
{
for (unsigned i = 0; i < MAX_PICTURES; i++)
XCB_pictures_Free(p_sys->segments[i]);
picture_pool_Delete (p_sys->pool); picture_pool_Delete (p_sys->pool);
}
/* show the default cursor */ /* show the default cursor */
xcb_change_window_attributes (p_sys->conn, p_sys->embed->handle.xid, XCB_CW_CURSOR, xcb_change_window_attributes (p_sys->conn, p_sys->embed->handle.xid, XCB_CW_CURSOR,
...@@ -620,9 +615,6 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count) ...@@ -620,9 +615,6 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count)
{ {
vout_display_sys_t *p_sys = vd->sys; vout_display_sys_t *p_sys = vd->sys;
for (unsigned count = 0; count < MAX_PICTURES; count++)
p_sys->segments[count] = NULL;
const uint32_t *pitches= xcb_xv_query_image_attributes_pitches (p_sys->att); const uint32_t *pitches= xcb_xv_query_image_attributes_pitches (p_sys->att);
const uint32_t *offsets= xcb_xv_query_image_attributes_offsets (p_sys->att); const uint32_t *offsets= xcb_xv_query_image_attributes_offsets (p_sys->att);
const unsigned num_planes= __MIN(p_sys->att->num_planes, PICTURE_PLANE_MAX); const unsigned num_planes= __MIN(p_sys->att->num_planes, PICTURE_PLANE_MAX);
...@@ -646,9 +638,7 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count) ...@@ -646,9 +638,7 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count)
{ {
xcb_shm_seg_t seg = p_sys->shm ? xcb_generate_id (p_sys->conn) : 0; xcb_shm_seg_t seg = p_sys->shm ? xcb_generate_id (p_sys->conn) : 0;
res.p[0].p_pixels = XCB_pictures_Alloc (vd, &res.p_sys, if (XCB_picture_Alloc (vd, &res, p_sys->data_size, p_sys->conn, seg))
p_sys->data_size, p_sys->conn, seg);
if (res.p[0].p_pixels == NULL)
break; break;
/* Allocate further planes as specified by XVideo */ /* Allocate further planes as specified by XVideo */
...@@ -663,16 +653,9 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count) ...@@ -663,16 +653,9 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count)
res.p[1].p_pixels = buf; res.p[1].p_pixels = buf;
} }
pic_array[count] = picture_NewFromResource (&vd->fmt, &res); pic_array[count] = XCB_picture_NewFromResource (&vd->fmt, &res);
if (!pic_array[count]) if (unlikely(pic_array[count] == NULL))
{
free (res.p_sys);
XCB_pictures_Free (res.p[0].p_pixels);
if (seg != 0)
xcb_shm_detach (p_sys->conn, seg);
break; break;
}
p_sys->segments[count] = res.p[0].p_pixels;
} }
if (count == 0) if (count == 0)
...@@ -702,7 +685,7 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count) ...@@ -702,7 +685,7 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
static void Display (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture) static void Display (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{ {
vout_display_sys_t *p_sys = vd->sys; vout_display_sys_t *p_sys = vd->sys;
xcb_shm_seg_t segment = pic->p_sys->segment; xcb_shm_seg_t segment = XCB_picture_GetSegment(pic);
xcb_void_cookie_t ck; xcb_void_cookie_t ck;
if (!p_sys->visible) if (!p_sys->visible)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment