Add gst_vaapi_window_glx_make_current(). Handle X11 window size changes and reset the GL viewport.

This commit is contained in:
gb 2010-03-26 09:41:12 +00:00
parent c3dcabd90c
commit c9f62b7405
4 changed files with 106 additions and 3 deletions

View file

@ -181,3 +181,31 @@ gl_resize(guint width, guint height)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/**
* gl_make_current:
* @dpy: an X11 #Display
* @win: an X11 #Window
* @ctx: the requested GLX context
* @state: an optional #GLContextState
*
* Makes the @window GLX context the current GLX rendering context of
* the calling thread, replacing the previously current context if
* there was one.
*
* If @state is non %NULL, the previously current GLX context and
* window are recorded.
*
* Return value: %TRUE on success
*/
gboolean
gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state)
{
if (state) {
state->context = glXGetCurrentContext();
state->window = glXGetCurrentDrawable();
if (state->context == ctx && state->window == win)
return TRUE;
}
return glXMakeCurrent(dpy, win, ctx);
}

View file

@ -54,4 +54,14 @@ void
gl_resize(guint width, guint height)
attribute_hidden;
typedef struct _GLContextState GLContextState;
struct _GLContextState {
GLXContext context;
Window window;
};
gboolean
gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state)
attribute_hidden;
#endif /* GST_VAAPI_UTILS_GLX_H */

View file

@ -47,6 +47,7 @@ struct _GstVaapiWindowGLXPrivate {
XVisualInfo vi_static;
Colormap cmap;
GLXContext context;
guint is_constructed : 1;
guint foreign_context : 1;
guint foreign_window : 1;
};
@ -83,7 +84,7 @@ gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window)
if (!priv->foreign_context) {
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
if (glXGetCurrentContext() == priv->context)
glXMakeCurrent(dpy, None, NULL);
gl_make_current(dpy, None, NULL, NULL);
glXDestroyContext(dpy, priv->context);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
}
@ -98,6 +99,7 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window)
GstVaapiWindowGLXPrivate * const priv = window->priv;
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
GLXContext ctx = NULL;
GLContextState cs;
guint width, height;
gboolean has_errors = TRUE;
@ -108,7 +110,7 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window)
ctx = glXCreateContext(dpy, priv->vi, NULL, True);
if (ctx && glXIsDirect(dpy, ctx)) {
_gst_vaapi_window_glx_set_context(window, ctx, FALSE);
if (glXMakeCurrent(dpy, GST_VAAPI_OBJECT_ID(window), ctx)) {
if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), ctx, &cs)) {
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
@ -122,6 +124,8 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window)
gl_set_bgcolor(0);
glClear(GL_COLOR_BUFFER_BIT);
if (cs.context)
gl_make_current(dpy, cs.window, cs.context, NULL);
has_errors = FALSE;
}
}
@ -258,6 +262,26 @@ gst_vaapi_window_glx_get_colormap(GstVaapiWindow *window)
return gst_vaapi_window_glx_create_colormap(GST_VAAPI_WINDOW_GLX(window));
}
static gboolean
gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height)
{
GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(window)->priv;
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
GLContextState cs;
if (!GST_VAAPI_WINDOW_CLASS(gst_vaapi_window_glx_parent_class)->
resize(window, width, height))
return FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), priv->context, &cs)) {
gl_resize(width, height);
gl_make_current(dpy, cs.window, cs.context, NULL);
}
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
return TRUE;
}
static void
gst_vaapi_window_glx_finalize(GObject *object)
{
@ -325,7 +349,7 @@ gst_vaapi_window_glx_constructed(GObject *object)
priv->foreign_window =
gst_vaapi_window_x11_is_foreign_xid(GST_VAAPI_WINDOW_X11(object));
if (!priv->foreign_context)
priv->is_constructed = priv->foreign_context ||
gst_vaapi_window_glx_create_context(GST_VAAPI_WINDOW_GLX(object));
}
@ -333,6 +357,7 @@ static void
gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass)
{
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
GstVaapiWindowClass * const win_class = GST_VAAPI_WINDOW_CLASS(klass);
GstVaapiWindowX11Class * const xwin_class = GST_VAAPI_WINDOW_X11_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiWindowGLXPrivate));
@ -342,6 +367,7 @@ gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass)
object_class->get_property = gst_vaapi_window_glx_get_property;
object_class->constructed = gst_vaapi_window_glx_constructed;
win_class->resize = gst_vaapi_window_glx_resize;
xwin_class->get_visual = gst_vaapi_window_glx_get_visual;
xwin_class->get_colormap = gst_vaapi_window_glx_get_colormap;
@ -369,7 +395,9 @@ gst_vaapi_window_glx_init(GstVaapiWindowGLX *window)
priv->vi = NULL;
priv->cmap = None;
priv->context = NULL;
priv->is_constructed = FALSE;
priv->foreign_context = FALSE;
priv->foreign_window = FALSE;
}
/**
@ -437,6 +465,7 @@ GLXContext
gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window)
{
g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), NULL);
g_return_val_if_fail(window->priv->is_constructed, FALSE);
return window->priv->context;
}
@ -457,6 +486,7 @@ gboolean
gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx)
{
g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE);
g_return_val_if_fail(window->priv->is_constructed, FALSE);
gst_vaapi_window_glx_destroy_context(window);
@ -467,6 +497,35 @@ gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx)
return gst_vaapi_window_glx_create_context(window);
}
/**
* gst_vaapi_window_glx_make_current:
* @window: a #GstVaapiWindowGLX
*
* Makes the @window GLX context the current GLX rendering context of
* the calling thread, replacing the previously current context if
* there was one.
*
* Return value: %TRUE on success
*/
gboolean
gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window)
{
gboolean success;
g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE);
g_return_val_if_fail(window->priv->is_constructed, FALSE);
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
success = gl_make_current(
GST_VAAPI_OBJECT_XDISPLAY(window),
GST_VAAPI_OBJECT_ID(window),
window->priv->context,
NULL
);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
return success;
}
/**
* gst_vaapi_window_glx_swap_buffers:
* @window: a #GstVaapiWindowGLX
@ -479,10 +538,13 @@ void
gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window)
{
g_return_if_fail(GST_VAAPI_IS_WINDOW_GLX(window));
g_return_if_fail(window->priv->is_constructed);
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
glXSwapBuffers(
GST_VAAPI_OBJECT_XDISPLAY(window),
GST_VAAPI_OBJECT_ID(window)
);
glClear(GL_COLOR_BUFFER_BIT);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
}

View file

@ -92,6 +92,9 @@ gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window);
gboolean
gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx);
gboolean
gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window);
void
gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window);