Commit e51b412b authored by Jean-Paul Saman's avatar Jean-Paul Saman

VAAPI-X11: Workaround for X11 window resize updates.

Query the window size inside Manage() to catch changes. The parent
window does not forward resizes to the client.
parent 10821ecd
...@@ -333,6 +333,27 @@ static vout_window_t *MakeWindow (vout_display_t *vd) ...@@ -333,6 +333,27 @@ static vout_window_t *MakeWindow (vout_display_t *vd)
return wnd; return wnd;
} }
static int GetWindowSize(vout_display_t *vd, Display *dpy,
Window window, int *px, int *py,
unsigned int *pwidth, unsigned int *pheight)
{
vout_display_sys_t *sys = vd->sys;
Status status = 0;
Window root_window;
unsigned int bw, depth;
sys->conn->lock();
if ((window != None) || (window != BadDrawable))
{
status = XGetGeometry(dpy, window,
&root_window,
px, py, pwidth, pheight,
&bw, &depth);
}
sys->conn->unlock();
return (status == 0) ? VLC_EGENERIC : VLC_SUCCESS;
}
static Screen *FindScreen(vout_display_t *vd, Display *dpy, static Screen *FindScreen(vout_display_t *vd, Display *dpy,
int *px, int *py, unsigned int *pnum, unsigned int *pdepth, int *px, int *py, unsigned int *pnum, unsigned int *pdepth,
unsigned int *pwidth, unsigned int *pheight) unsigned int *pwidth, unsigned int *pheight)
...@@ -401,6 +422,7 @@ static Window CreateWindow(vout_display_t *vd, Display *dpy, Screen *screen) ...@@ -401,6 +422,7 @@ static Window CreateWindow(vout_display_t *vd, Display *dpy, Screen *screen)
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
assert(screen); assert(screen);
sys->conn->lock();
int scr = XScreenNumberOfScreen(screen); int scr = XScreenNumberOfScreen(screen);
XVisualInfo visualInfo; XVisualInfo visualInfo;
...@@ -426,35 +448,53 @@ static Window CreateWindow(vout_display_t *vd, Display *dpy, Screen *screen) ...@@ -426,35 +448,53 @@ static Window CreateWindow(vout_display_t *vd, Display *dpy, Screen *screen)
0, sys->geo.depth, 0, sys->geo.depth,
InputOutput, InputOutput,
vi->visual, xswa_mask, &xswa); vi->visual, xswa_mask, &xswa);
if (window == None) switch (window)
{ {
case None:
case BadAlloc:
case BadColor:
case BadCursor:
case BadMatch:
case BadPixmap:
case BadValue:
case BadWindow:
XFree(vi); XFree(vi);
return None; goto error;
default:
break;
} }
if (vi != &visualInfo) if (vi != &visualInfo)
XFree(vi); XFree(vi);
/* */ /* */
long mask = (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | long mask = (PointerMotionMask | StructureNotifyMask |
ResizeRedirectMask | StructureNotifyMask | SubstructureRedirectMask |
ExposureMask | VisibilityChangeMask); ExposureMask | VisibilityChangeMask);
if (var_InheritBool(vd, "mouse-events"))
mask |= (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
int err = XSelectInput(dpy, window, mask); int err = XSelectInput(dpy, window, mask);
if (err == BadWindow) if (err == BadWindow)
return None; goto error;
XMapWindow(dpy, window); XMapWindow(dpy, window);
WaitEvent(dpy, window, MapNotify); WaitEvent(dpy, window, MapNotify);
WaitEvent(dpy, window, Expose); /* XXX: workaround an XvBA init bug */ WaitEvent(dpy, window, Expose); /* XXX: workaround an XvBA init bug */
sys->conn->unlock();
XFlush(dpy);
return window; return window;
error:
sys->conn->unlock();
return None;
} }
static void DestroyWindow(Display *dpy, Window window) static void DestroyWindow(Display *dpy, Window window)
{ {
/* use unlocked */
XUnmapWindow(dpy, window); XUnmapWindow(dpy, window);
WaitEvent(dpy, window, UnmapNotify); WaitEvent(dpy, window, UnmapNotify);
int err = XSelectInput(dpy, window, NoEventMask);
if (err != BadWindow)
XFlush(dpy);
XDestroyWindow(dpy, window); XDestroyWindow(dpy, window);
} }
...@@ -469,17 +509,20 @@ static Cursor CreateBlankCursor(vout_display_t *vd, Display *dpy, ...@@ -469,17 +509,20 @@ static Cursor CreateBlankCursor(vout_display_t *vd, Display *dpy,
XColor dummy; XColor dummy;
static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0}; static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
sys->conn->lock();
int scr = XScreenNumberOfScreen(screen); int scr = XScreenNumberOfScreen(screen);
cmap = DefaultColormap(dpy, scr); cmap = DefaultColormap(dpy, scr);
XAllocNamedColor(dpy, cmap, "black", &sys->black, &dummy); XAllocNamedColor(dpy, cmap, "black", &sys->black, &dummy);
sys->bitmap = XCreateBitmapFromData(dpy, sys->window, bm_no_data, 8, 8); sys->bitmap = XCreateBitmapFromData(dpy, sys->window, bm_no_data, 8, 8);
no_ptr = XCreatePixmapCursor(dpy, sys->bitmap, sys->bitmap, &sys->black, &sys->black, 0, 0); no_ptr = XCreatePixmapCursor(dpy, sys->bitmap, sys->bitmap, &sys->black, &sys->black, 0, 0);
sys->conn->unlock();
return no_ptr; return no_ptr;
} }
static void DestroyBlankCursor(vout_display_t *vd, Display *dpy, static void DestroyBlankCursor(vout_display_t *vd, Display *dpy,
Window window, Screen *screen) Window window, Screen *screen)
{ {
/* use unlocked */
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
assert(screen); assert(screen);
...@@ -607,20 +650,22 @@ void CloseVaapiX11 (vlc_object_t *obj) ...@@ -607,20 +650,22 @@ void CloseVaapiX11 (vlc_object_t *obj)
{ {
XFlush(sys->conn->p_x11); XFlush(sys->conn->p_x11);
XSync(sys->conn->p_x11, False); XSync(sys->conn->p_x11, False);
}
if (sys->blank_cursor != None) if ((sys->window != None) && (sys->blank_cursor != None))
DestroyBlankCursor(vd, sys->conn->p_x11, DestroyBlankCursor(vd, sys->conn->p_x11,
sys->window, sys->screen); sys->window, sys->screen);
if (sys->window != None) if (sys->window != None)
DestroyWindow(sys->conn->p_x11, sys->window); DestroyWindow(sys->conn->p_x11, sys->window);
}
sys->blank_cursor = None; sys->blank_cursor = None;
sys->window = None; sys->window = None;
sys->conn->unlock(); sys->conn->unlock();
if (sys->embed) if (sys->embed)
vout_display_DeleteWindow (vd, sys->embed); vout_display_DeleteWindow (vd, sys->embed);
sys->embed = NULL;
/* Cleanup cache */ /* Cleanup cache */
vlc_mutex_destroy(&sys->cache_lock); vlc_mutex_destroy(&sys->cache_lock);
...@@ -695,8 +740,8 @@ static int Control (vout_display_t *vd, int query, va_list ap) ...@@ -695,8 +740,8 @@ static int Control (vout_display_t *vd, int query, va_list ap)
is_forced = (bool)va_arg (ap, int); is_forced = (bool)va_arg (ap, int);
} }
msg_Info(vd, "display size %dx%d %dx%d", // msg_Dbg(vd, "display size %dx%d %dx%d",
0, 0, cfg->display.width, cfg->display.height); // 0, 0, cfg->display.width, cfg->display.height);
/* */ /* */
if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE
...@@ -707,24 +752,41 @@ static int Control (vout_display_t *vd, int query, va_list ap) ...@@ -707,24 +752,41 @@ static int Control (vout_display_t *vd, int query, va_list ap)
cfg->display.width, cfg->display.height)) cfg->display.width, cfg->display.height))
return VLC_EGENERIC; return VLC_EGENERIC;
/* FIXME: updating picture geometry */
#if 0
vout_display_place_t place; vout_display_place_t place;
vout_display_PlacePicture(&place, source, cfg, false); vout_display_PlacePicture(&place, source, cfg, false);
/* */
sys->geo.x = place.x; sys->geo.x = place.x;
sys->geo.y = place.y; sys->geo.y = place.y;
sys->geo.width = place.width; sys->geo.width = place.width;
sys->geo.height = place.height; sys->geo.height = place.height;
#else
VLC_UNUSED(source);
XWindowChanges changes = { .x = place.x, .y = place.y, sys->geo.x = 0;
.width = place.width, .height = place.height }; sys->geo.y = 0;
sys->geo.width = cfg->display.width;
sys->geo.height = cfg->display.height;
#endif
if (sys->window == None)
return VLC_EGENERIC;
sys->conn->lock();
XWindowChanges changes = { .x = sys->geo.x, .y = sys->geo.y,
.width = sys->geo.width, .height = sys->geo.height };
int err = XConfigureWindow(sys->conn->p_x11, sys->window, int err = XConfigureWindow(sys->conn->p_x11, sys->window,
CWX | CWY | CWWidth | CWHeight, &changes); CWX | CWY | CWWidth | CWHeight, &changes);
if (err == BadMatch || err == BadValue || err == BadWindow) if (err == BadMatch || err == BadValue || err == BadWindow)
{
sys->conn->unlock();
return VLC_EGENERIC; return VLC_EGENERIC;
}
XFlush(sys->conn->p_x11);
sys->conn->unlock();
msg_Info(vd, "New window size %dx%d %dx%d", msg_Dbg(vd, "New window size %dx%d %dx%d",
place.x, place.y, place.width, place.height); sys->geo.x, sys->geo.y, sys->geo.width, sys->geo.height);
return VLC_SUCCESS; return VLC_SUCCESS;
} }
case VOUT_DISPLAY_RESET_PICTURES: case VOUT_DISPLAY_RESET_PICTURES:
...@@ -737,16 +799,17 @@ static int Control (vout_display_t *vd, int query, va_list ap) ...@@ -737,16 +799,17 @@ static int Control (vout_display_t *vd, int query, va_list ap)
* vout_display_t::info.b_hide_mouse is false */ * vout_display_t::info.b_hide_mouse is false */
case VOUT_DISPLAY_HIDE_MOUSE: case VOUT_DISPLAY_HIDE_MOUSE:
{ {
sys->conn->lock();
int err = XDefineCursor(sys->conn->p_x11, sys->window, int err = XDefineCursor(sys->conn->p_x11, sys->window,
sys->blank_cursor); sys->blank_cursor);
sys->conn->unlock();
if (err == BadAlloc || err == BadWindow || err == BadCursor) if (err == BadAlloc || err == BadWindow || err == BadCursor)
return VLC_EGENERIC; return VLC_EGENERIC;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
default: default:
msg_Err (vd, "Unknown request in XCB vout display"); msg_Err (vd, "Unknown request in VAAPI-X11 vout display");
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} }
...@@ -776,7 +839,9 @@ static int HandleEvent(vout_display_t *vd, Display *dpy, XEvent *event, ...@@ -776,7 +839,9 @@ static int HandleEvent(vout_display_t *vd, Display *dpy, XEvent *event,
vout_display_place_t place; vout_display_place_t place;
/* show the default cursor */ /* show the default cursor */
sys->conn->lock();
XUndefineCursor(dpy, sys->window); XUndefineCursor(dpy, sys->window);
sys->conn->unlock();
/* TODO it could be saved */ /* TODO it could be saved */
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false); vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
...@@ -823,7 +888,9 @@ static int HandleEvent(vout_display_t *vd, Display *dpy, XEvent *event, ...@@ -823,7 +888,9 @@ static int HandleEvent(vout_display_t *vd, Display *dpy, XEvent *event,
case DestroyNotify: case DestroyNotify:
vout_display_SendEventClose(vd); vout_display_SendEventClose(vd);
break; break;
case CreateNotify:
case Expose: case Expose:
case MapNotify:
case MappingNotify: case MappingNotify:
break; break;
default: default:
...@@ -837,12 +904,42 @@ static void Manage(vout_display_t *vd) ...@@ -837,12 +904,42 @@ static void Manage(vout_display_t *vd)
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
while (XPending(sys->conn->p_x11)) /* FIXME: workaround for not receiving updates from X11 when resizing */
int x, y;
unsigned int w, h;
if (GetWindowSize(vd, sys->conn->p_x11, sys->embed->handle.xid,
&x, &y, &w, &h) == VLC_SUCCESS)
{
if (sys->geo.width != w || sys->geo.height != h)
{
sys->geo.y = y;
sys->geo.x = x;
sys->geo.width = w;
sys->geo.height = h;
vout_display_SendEventDisplaySize(vd, w, h, vd->cfg->is_fullscreen);
}
}
/* */
int num = 0;
do
{
if (sys->window == None)
break;
sys->conn->lock();
num = XPending(sys->conn->p_x11);
if (num <= 0)
{ {
sys->conn->unlock();
break;
}
XEvent event; XEvent event;
XNextEvent(sys->conn->p_x11, &event); XNextEvent(sys->conn->p_x11, &event);
sys->conn->unlock();
HandleEvent(vd, sys->conn->p_x11, &event, &sys->visible); HandleEvent(vd, sys->conn->p_x11, &event, &sys->visible);
} } while(num > 0);
} }
static VASubpictureID SubpictureCreate(vout_display_t *vd, const subpicture_t *subpicture, static VASubpictureID SubpictureCreate(vout_display_t *vd, const subpicture_t *subpicture,
...@@ -1410,6 +1507,9 @@ static void DisplayPicture(vout_display_t *vd, picture_t *pic, subpicture_t *sub ...@@ -1410,6 +1507,9 @@ static void DisplayPicture(vout_display_t *vd, picture_t *pic, subpicture_t *sub
if (!sys->visible) if (!sys->visible)
goto out; goto out;
if (sys->window == None)
goto out;
assert(pic->format.i_chroma == VLC_CODEC_VAAPI_SURFACE); assert(pic->format.i_chroma == VLC_CODEC_VAAPI_SURFACE);
if ((pic->p_sys == NULL) || (pic->p_sys->i_id == VA_INVALID_SURFACE)) if ((pic->p_sys == NULL) || (pic->p_sys->i_id == VA_INVALID_SURFACE))
......
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