mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
Add gst_vaapi_window_glx_make_current(). Handle X11 window size changes and reset the GL viewport.
This commit is contained in:
parent
c3dcabd90c
commit
c9f62b7405
4 changed files with 106 additions and 3 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue