mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +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);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
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)
|
gl_resize(guint width, guint height)
|
||||||
attribute_hidden;
|
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 */
|
#endif /* GST_VAAPI_UTILS_GLX_H */
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct _GstVaapiWindowGLXPrivate {
|
||||||
XVisualInfo vi_static;
|
XVisualInfo vi_static;
|
||||||
Colormap cmap;
|
Colormap cmap;
|
||||||
GLXContext context;
|
GLXContext context;
|
||||||
|
guint is_constructed : 1;
|
||||||
guint foreign_context : 1;
|
guint foreign_context : 1;
|
||||||
guint foreign_window : 1;
|
guint foreign_window : 1;
|
||||||
};
|
};
|
||||||
|
@ -83,7 +84,7 @@ gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window)
|
||||||
if (!priv->foreign_context) {
|
if (!priv->foreign_context) {
|
||||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||||
if (glXGetCurrentContext() == priv->context)
|
if (glXGetCurrentContext() == priv->context)
|
||||||
glXMakeCurrent(dpy, None, NULL);
|
gl_make_current(dpy, None, NULL, NULL);
|
||||||
glXDestroyContext(dpy, priv->context);
|
glXDestroyContext(dpy, priv->context);
|
||||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||||
}
|
}
|
||||||
|
@ -98,6 +99,7 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window)
|
||||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||||
GLXContext ctx = NULL;
|
GLXContext ctx = NULL;
|
||||||
|
GLContextState cs;
|
||||||
guint width, height;
|
guint width, height;
|
||||||
gboolean has_errors = TRUE;
|
gboolean has_errors = TRUE;
|
||||||
|
|
||||||
|
@ -108,7 +110,7 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window)
|
||||||
ctx = glXCreateContext(dpy, priv->vi, NULL, True);
|
ctx = glXCreateContext(dpy, priv->vi, NULL, True);
|
||||||
if (ctx && glXIsDirect(dpy, ctx)) {
|
if (ctx && glXIsDirect(dpy, ctx)) {
|
||||||
_gst_vaapi_window_glx_set_context(window, ctx, FALSE);
|
_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);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
@ -122,6 +124,8 @@ gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window)
|
||||||
|
|
||||||
gl_set_bgcolor(0);
|
gl_set_bgcolor(0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
if (cs.context)
|
||||||
|
gl_make_current(dpy, cs.window, cs.context, NULL);
|
||||||
has_errors = FALSE;
|
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));
|
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
|
static void
|
||||||
gst_vaapi_window_glx_finalize(GObject *object)
|
gst_vaapi_window_glx_finalize(GObject *object)
|
||||||
{
|
{
|
||||||
|
@ -325,7 +349,7 @@ gst_vaapi_window_glx_constructed(GObject *object)
|
||||||
priv->foreign_window =
|
priv->foreign_window =
|
||||||
gst_vaapi_window_x11_is_foreign_xid(GST_VAAPI_WINDOW_X11(object));
|
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));
|
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)
|
gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass * const object_class = G_OBJECT_CLASS(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);
|
GstVaapiWindowX11Class * const xwin_class = GST_VAAPI_WINDOW_X11_CLASS(klass);
|
||||||
|
|
||||||
g_type_class_add_private(klass, sizeof(GstVaapiWindowGLXPrivate));
|
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->get_property = gst_vaapi_window_glx_get_property;
|
||||||
object_class->constructed = gst_vaapi_window_glx_constructed;
|
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_visual = gst_vaapi_window_glx_get_visual;
|
||||||
xwin_class->get_colormap = gst_vaapi_window_glx_get_colormap;
|
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->vi = NULL;
|
||||||
priv->cmap = None;
|
priv->cmap = None;
|
||||||
priv->context = NULL;
|
priv->context = NULL;
|
||||||
|
priv->is_constructed = FALSE;
|
||||||
priv->foreign_context = FALSE;
|
priv->foreign_context = FALSE;
|
||||||
|
priv->foreign_window = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -437,6 +465,7 @@ GLXContext
|
||||||
gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window)
|
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(GST_VAAPI_IS_WINDOW_GLX(window), NULL);
|
||||||
|
g_return_val_if_fail(window->priv->is_constructed, FALSE);
|
||||||
|
|
||||||
return window->priv->context;
|
return window->priv->context;
|
||||||
}
|
}
|
||||||
|
@ -457,6 +486,7 @@ gboolean
|
||||||
gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx)
|
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(GST_VAAPI_IS_WINDOW_GLX(window), FALSE);
|
||||||
|
g_return_val_if_fail(window->priv->is_constructed, FALSE);
|
||||||
|
|
||||||
gst_vaapi_window_glx_destroy_context(window);
|
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);
|
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:
|
* gst_vaapi_window_glx_swap_buffers:
|
||||||
* @window: a #GstVaapiWindowGLX
|
* @window: a #GstVaapiWindowGLX
|
||||||
|
@ -479,10 +538,13 @@ void
|
||||||
gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window)
|
gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window)
|
||||||
{
|
{
|
||||||
g_return_if_fail(GST_VAAPI_IS_WINDOW_GLX(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(
|
glXSwapBuffers(
|
||||||
GST_VAAPI_OBJECT_XDISPLAY(window),
|
GST_VAAPI_OBJECT_XDISPLAY(window),
|
||||||
GST_VAAPI_OBJECT_ID(window)
|
GST_VAAPI_OBJECT_ID(window)
|
||||||
);
|
);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,9 @@ gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window);
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx);
|
gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window);
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window);
|
gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue