Commit 267a4bdb authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

XCB: GLX 1.3

(This is untested as my current hardware driver only has GLX 1.2)
parent b656e58f
...@@ -65,7 +65,9 @@ struct vout_display_sys_t ...@@ -65,7 +65,9 @@ struct vout_display_sys_t
xcb_cursor_t cursor; /* blank cursor */ xcb_cursor_t cursor; /* blank cursor */
xcb_window_t window; /* drawable X window */ xcb_window_t window; /* drawable X window */
xcb_window_t glwin; /* GLX window */
bool visible; /* whether to draw */ bool visible; /* whether to draw */
bool v1_3; /* whether GLX >= 1.3 is available */
GLXContext ctx; GLXContext ctx;
vout_opengl_t gl; vout_opengl_t gl;
...@@ -142,7 +144,7 @@ FindWindow (vout_display_t *vd, xcb_connection_t *conn, ...@@ -142,7 +144,7 @@ FindWindow (vout_display_t *vd, xcb_connection_t *conn,
return screen; return screen;
} }
static bool CheckGLX (vout_display_t *vd, Display *dpy) static bool CheckGLX (vout_display_t *vd, Display *dpy, bool *restrict pv13)
{ {
int major, minor; int major, minor;
bool ok = false; bool ok = false;
...@@ -159,10 +161,40 @@ static bool CheckGLX (vout_display_t *vd, Display *dpy) ...@@ -159,10 +161,40 @@ static bool CheckGLX (vout_display_t *vd, Display *dpy)
{ {
msg_Dbg (vd, "using GLX extension version %d.%d", major, minor); msg_Dbg (vd, "using GLX extension version %d.%d", major, minor);
ok = true; ok = true;
*pv13 = minor >= 3;
} }
return ok; return ok;
} }
static int CreateWindow (vout_display_t *vd, xcb_connection_t *conn,
uint_fast8_t depth, xcb_visualid_t vid)
{
vout_display_sys_t *sys = vd->sys;
unsigned width, height;
if (GetWindowSize (sys->embed, conn, &width, &height))
return VLC_EGENERIC;
const uint32_t mask = XCB_CW_EVENT_MASK;
const uint32_t values[] = {
/* XCB_CW_EVENT_MASK */
XCB_EVENT_MASK_VISIBILITY_CHANGE,
};
xcb_void_cookie_t cc, cm;
cc = xcb_create_window_checked (conn, depth, sys->window,
sys->embed->xid, 0, 0, width, height, 0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
vid, mask, values);
cm = xcb_map_window_checked (conn, sys->window);
if (CheckError (vd, conn, "cannot create X11 window", cc)
|| CheckError (vd, conn, "cannot map X11 window", cm))
return VLC_EGENERIC;
msg_Dbg (vd, "using X11 window %08"PRIx32, sys->window);
return VLC_SUCCESS;
}
/** /**
* Probe the X server. * Probe the X server.
*/ */
...@@ -198,7 +230,7 @@ static int Open (vlc_object_t *obj) ...@@ -198,7 +230,7 @@ static int Open (vlc_object_t *obj)
sys->ctx = NULL; sys->ctx = NULL;
XSetEventQueueOwner (dpy, XCBOwnsEventQueue); XSetEventQueueOwner (dpy, XCBOwnsEventQueue);
if (!CheckGLX (vd, dpy)) if (!CheckGLX (vd, dpy, &sys->v1_3))
goto error; goto error;
xcb_connection_t *conn = XGetXCBConnection (dpy); xcb_connection_t *conn = XGetXCBConnection (dpy);
...@@ -212,15 +244,62 @@ static int Open (vlc_object_t *obj) ...@@ -212,15 +244,62 @@ static int Open (vlc_object_t *obj)
if (scr == NULL) if (scr == NULL)
goto error; goto error;
sys->window = xcb_generate_id (conn);
/* Determine our pixel format */ /* Determine our pixel format */
if (sys->v1_3)
{ /* GLX 1.3 */
static const int attr[] = {
GLX_RED_SIZE, 5,
GLX_GREEN_SIZE, 5,
GLX_BLUE_SIZE, 5,
GLX_DOUBLEBUFFER, True,
GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
None };
int nelem;
GLXFBConfig *confs = glXChooseFBConfig (dpy, snum, attr, &nelem);
if (confs == NULL)
{ {
msg_Err (vd, "no GLX frame bufer configurations");
goto error;
}
/*XVisualInfo *vi = glXGetVisualFromFBConfig (dpy, confs[0]);*/
CreateWindow (vd, conn, depth, 0 /* ??? */);
/*XFree (vi);*/
sys->glwin = glXCreateWindow (dpy, confs[0], sys->window, NULL );
if (sys->glwin == None)
{
msg_Err (vd, "cannot create GLX window");
XFree (confs);
goto error;
}
/* Create an OpenGL context */
sys->ctx = glXCreateNewContext (dpy, confs[0], GLX_RGBA_TYPE, NULL,
True);
XFree (confs);
if (sys->ctx == NULL)
{
msg_Err (vd, "cannot create GLX context");
goto error;
}
if (glXMakeContextCurrent (dpy, sys->glwin, sys->glwin, sys->ctx))
goto error;
}
else
{ /* GLX 1.2 */
int attr[] = { int attr[] = {
GLX_RGBA, GLX_RGBA,
GLX_RED_SIZE, 5, GLX_RED_SIZE, 5,
GLX_GREEN_SIZE, 5, GLX_GREEN_SIZE, 5,
GLX_BLUE_SIZE, 5, GLX_BLUE_SIZE, 5,
GLX_DOUBLEBUFFER, GLX_DOUBLEBUFFER,
0 }; None };
XVisualInfo *vi = glXChooseVisual (dpy, snum, attr); XVisualInfo *vi = glXChooseVisual (dpy, snum, attr);
if (vi == NULL) if (vi == NULL)
...@@ -228,7 +307,9 @@ static int Open (vlc_object_t *obj) ...@@ -228,7 +307,9 @@ static int Open (vlc_object_t *obj)
msg_Err (vd, "cannot find GLX 1.2 visual" ); msg_Err (vd, "cannot find GLX 1.2 visual" );
goto error; goto error;
} }
msg_Dbg (vd, "using GLX visual ID 0x%"PRIx32, (uint32_t)vi->visualid);
if (CreateWindow (vd, conn, depth, 0 /* ??? */) == 0)
sys->ctx = glXCreateContext (dpy, vi, 0, True); sys->ctx = glXCreateContext (dpy, vi, 0, True);
XFree (vi); XFree (vi);
if (sys->ctx == NULL) if (sys->ctx == NULL)
...@@ -236,35 +317,11 @@ static int Open (vlc_object_t *obj) ...@@ -236,35 +317,11 @@ static int Open (vlc_object_t *obj)
msg_Err (vd, "cannot create GLX context"); msg_Err (vd, "cannot create GLX context");
goto error; goto error;
} }
}
/* Create window */
unsigned width, height;
if (GetWindowSize (sys->embed, conn, &width, &height))
goto error;
sys->window = xcb_generate_id (conn);
{
const uint32_t mask = XCB_CW_EVENT_MASK;
const uint32_t values[] = {
/* XCB_CW_EVENT_MASK */
XCB_EVENT_MASK_VISIBILITY_CHANGE,
};
xcb_void_cookie_t c;
c = xcb_create_window_checked (conn, depth, sys->window,
sys->embed->xid, 0, 0, width, height, 0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
0, mask, values);
xcb_map_window (conn, sys->window);
if (CheckError (vd, conn, "cannot create X11 window", c))
goto error;
}
msg_Dbg (vd, "using X11 window %08"PRIx32, sys->window);
if (glXMakeCurrent (dpy, sys->window, sys->ctx) == False) if (glXMakeCurrent (dpy, sys->window, sys->ctx) == False)
goto error; goto error;
sys->glwin = sys->window;
}
/* Initialize common OpenGL video display */ /* Initialize common OpenGL video display */
sys->gl.lock = NULL; sys->gl.lock = NULL;
...@@ -296,7 +353,7 @@ static int Open (vlc_object_t *obj) ...@@ -296,7 +353,7 @@ static int Open (vlc_object_t *obj)
/* */ /* */
vout_display_SendEventFullscreen (vd, false); vout_display_SendEventFullscreen (vd, false);
vout_display_SendEventDisplaySize (vd, width, height, false); //vout_display_SendEventDisplaySize (vd, width, height, false);
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -320,7 +377,13 @@ static void Close (vlc_object_t *obj) ...@@ -320,7 +377,13 @@ static void Close (vlc_object_t *obj)
if (sys->ctx != NULL) if (sys->ctx != NULL)
{ {
glXMakeCurrent (dpy, 0, NULL); if (sys->v1_3)
{
glXMakeContextCurrent (dpy, None, None, NULL);
glXDestroyWindow (dpy, sys->glwin);
}
else
glXMakeCurrent (dpy, None, NULL);
glXDestroyContext (dpy, sys->ctx); glXDestroyContext (dpy, sys->ctx);
} }
XCloseDisplay (dpy); XCloseDisplay (dpy);
...@@ -332,7 +395,7 @@ static void SwapBuffers (vout_opengl_t *gl) ...@@ -332,7 +395,7 @@ static void SwapBuffers (vout_opengl_t *gl)
{ {
vout_display_sys_t *sys = gl->sys; vout_display_sys_t *sys = gl->sys;
glXSwapBuffers (sys->display, sys->window); glXSwapBuffers (sys->display, sys->glwin);
} }
/** /**
......
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