mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-29 11:40:38 +00:00
Improve handling of GL contexts.
This commit is contained in:
parent
bc9060f425
commit
702f844a7e
4 changed files with 291 additions and 201 deletions
|
@ -46,6 +46,7 @@ struct _GstVaapiTexturePrivate {
|
|||
GLenum format;
|
||||
guint width;
|
||||
guint height;
|
||||
GLContextState *gl_context;
|
||||
void *gl_surface;
|
||||
GLPixmapObject *pixo;
|
||||
GLFramebufferObject *fbo;
|
||||
|
@ -103,6 +104,13 @@ gst_vaapi_texture_destroy(GstVaapiTexture *texture)
|
|||
glDeleteTextures(1, &texture_id);
|
||||
GST_VAAPI_OBJECT_ID(texture) = 0;
|
||||
}
|
||||
|
||||
if (priv->gl_context) {
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(texture);
|
||||
gl_destroy_context(priv->gl_context);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture);
|
||||
priv->gl_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -151,6 +159,18 @@ gst_vaapi_texture_create(GstVaapiTexture *texture)
|
|||
{
|
||||
GstVaapiTexturePrivate * const priv = texture->priv;
|
||||
GLuint texture_id;
|
||||
GLContextState old_cs;
|
||||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(texture);
|
||||
gl_get_current_context(&old_cs);
|
||||
priv->gl_context = gl_create_context(
|
||||
GST_VAAPI_OBJECT_XDISPLAY(texture),
|
||||
DefaultScreen(GST_VAAPI_OBJECT_XDISPLAY(texture)),
|
||||
&old_cs
|
||||
);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture);
|
||||
if (!priv->gl_context)
|
||||
return FALSE;
|
||||
|
||||
if (priv->foreign_texture)
|
||||
texture_id = GST_VAAPI_OBJECT_ID(texture);
|
||||
|
@ -310,6 +330,7 @@ gst_vaapi_texture_init(GstVaapiTexture *texture)
|
|||
priv->format = GL_NONE;
|
||||
priv->width = 0;
|
||||
priv->height = 0;
|
||||
priv->gl_context = NULL;
|
||||
priv->gl_surface = NULL;
|
||||
priv->pixo = NULL;
|
||||
priv->fbo = NULL;
|
||||
|
|
|
@ -273,46 +273,165 @@ gl_resize(guint width, guint height)
|
|||
}
|
||||
|
||||
/**
|
||||
* gl_make_current:
|
||||
* gl_create_context:
|
||||
* @dpy: an X11 #Display
|
||||
* @win: an X11 #Window
|
||||
* @ctx: the requested GLX context
|
||||
* @state: an optional #GLContextState
|
||||
* @screen: the associated screen of @dpy
|
||||
* @parent: the parent #GLContextState, or %NULL if none is to be used
|
||||
*
|
||||
* Makes the @window GLX context the current GLX rendering context of
|
||||
* Creates a GLX context sharing textures and displays lists with
|
||||
* @parent, if not %NULL.
|
||||
*
|
||||
* Return value: the newly created GLX context
|
||||
*/
|
||||
GLContextState *
|
||||
gl_create_context(Display *dpy, int screen, GLContextState *parent)
|
||||
{
|
||||
GLContextState *cs;
|
||||
GLXFBConfig *fb_configs = NULL;
|
||||
int n_fb_configs;
|
||||
|
||||
static GLint fb_config_attrs[] = {
|
||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DOUBLEBUFFER, True,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
None
|
||||
};
|
||||
|
||||
cs = malloc(sizeof(*cs));
|
||||
if (!cs)
|
||||
goto error;
|
||||
|
||||
cs->display = dpy;
|
||||
cs->window = parent ? parent->window : None;
|
||||
cs->visual = NULL;
|
||||
cs->context = NULL;
|
||||
cs->swapped_buffers = FALSE;
|
||||
|
||||
fb_configs = glXChooseFBConfig(dpy, screen, fb_config_attrs, &n_fb_configs);
|
||||
if (!fb_configs)
|
||||
goto error;
|
||||
|
||||
cs->visual = glXGetVisualFromFBConfig(dpy, fb_configs[0]);
|
||||
if (!cs->visual)
|
||||
goto error;
|
||||
|
||||
cs->context = glXCreateNewContext(
|
||||
dpy,
|
||||
fb_configs[0],
|
||||
GLX_RGBA_TYPE,
|
||||
parent ? parent->context : NULL,
|
||||
True
|
||||
);
|
||||
if (cs->context)
|
||||
goto end;
|
||||
|
||||
error:
|
||||
gl_destroy_context(cs);
|
||||
cs = NULL;
|
||||
end:
|
||||
if (fb_configs)
|
||||
XFree(fb_configs);
|
||||
return cs;
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_destroy_context:
|
||||
* @cs: a #GLContextState
|
||||
*
|
||||
* Destroys the GLX context @cs
|
||||
*/
|
||||
void
|
||||
gl_destroy_context(GLContextState *cs)
|
||||
{
|
||||
if (!cs)
|
||||
return;
|
||||
|
||||
if (cs->visual) {
|
||||
XFree(cs->visual);
|
||||
cs->visual = NULL;
|
||||
}
|
||||
|
||||
if (cs->display && cs->context) {
|
||||
if (glXGetCurrentContext() == cs->context) {
|
||||
/* XXX: if buffers were never swapped, the application
|
||||
will crash later with the NVIDIA driver */
|
||||
if (!cs->swapped_buffers)
|
||||
gl_swap_buffers(cs);
|
||||
glXMakeCurrent(cs->display, None, NULL);
|
||||
}
|
||||
glXDestroyContext(cs->display, cs->context);
|
||||
cs->display = NULL;
|
||||
cs->context = NULL;
|
||||
}
|
||||
free(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_get_current_context:
|
||||
* @cs: return location to the current #GLContextState
|
||||
*
|
||||
* Retrieves the current GLX context, display and drawable packed into
|
||||
* the #GLContextState struct.
|
||||
*/
|
||||
void
|
||||
gl_get_current_context(GLContextState *cs)
|
||||
{
|
||||
cs->display = glXGetCurrentDisplay();
|
||||
cs->window = glXGetCurrentDrawable();
|
||||
cs->context = glXGetCurrentContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_set_current_context:
|
||||
* @new_cs: the requested new #GLContextState
|
||||
* @old_cs: return location to the context that was previously current
|
||||
*
|
||||
* Makes the @new_cs 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
|
||||
* If @old_cs 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)
|
||||
gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs)
|
||||
{
|
||||
if (state) {
|
||||
state->context = glXGetCurrentContext();
|
||||
state->window = glXGetCurrentDrawable();
|
||||
if (state->context == ctx && state->window == win)
|
||||
/* If display is NULL, this could be that new_cs was retrieved from
|
||||
gl_get_current_context() with none set previously. If that case,
|
||||
the other fields are also NULL and we don't return an error */
|
||||
if (!new_cs->display)
|
||||
return !new_cs->window && !new_cs->context;
|
||||
|
||||
if (old_cs) {
|
||||
if (old_cs == new_cs)
|
||||
return TRUE;
|
||||
gl_get_current_context(old_cs);
|
||||
if (old_cs->display == new_cs->display &&
|
||||
old_cs->window == new_cs->window &&
|
||||
old_cs->context == new_cs->context)
|
||||
return TRUE;
|
||||
}
|
||||
return glXMakeCurrent(dpy, win, ctx);
|
||||
return glXMakeCurrent(new_cs->display, new_cs->window, new_cs->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_swap_buffers:
|
||||
* @dpy: an X11 #Display
|
||||
* @win: an X11 #Window
|
||||
* @cs: a #GLContextState
|
||||
*
|
||||
* Promotes the contents of the back buffer of the @win window to
|
||||
* become the contents of the front buffer. This simply is wrapper
|
||||
* around glXSwapBuffers().
|
||||
*/
|
||||
void
|
||||
gl_swap_buffers(Display *dpy, Window win)
|
||||
gl_swap_buffers(GLContextState *cs)
|
||||
{
|
||||
glXSwapBuffers(dpy, win);
|
||||
glXSwapBuffers(cs->display, cs->window);
|
||||
cs->swapped_buffers = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,16 +67,31 @@ gl_resize(guint width, guint height)
|
|||
|
||||
typedef struct _GLContextState GLContextState;
|
||||
struct _GLContextState {
|
||||
GLXContext context;
|
||||
Window window;
|
||||
Display *display;
|
||||
Window window;
|
||||
XVisualInfo *visual;
|
||||
GLXContext context;
|
||||
guint swapped_buffers;
|
||||
};
|
||||
|
||||
gboolean
|
||||
gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state)
|
||||
GLContextState *
|
||||
gl_create_context(Display *dpy, int screen, GLContextState *parent)
|
||||
attribute_hidden;
|
||||
|
||||
void
|
||||
gl_swap_buffers(Display *dpy, Window win)
|
||||
gl_destroy_context(GLContextState *cs)
|
||||
attribute_hidden;
|
||||
|
||||
void
|
||||
gl_get_current_context(GLContextState *cs)
|
||||
attribute_hidden;
|
||||
|
||||
gboolean
|
||||
gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs)
|
||||
attribute_hidden;
|
||||
|
||||
void
|
||||
gl_swap_buffers(GLContextState *cs)
|
||||
attribute_hidden;
|
||||
|
||||
typedef struct _GLTextureState GLTextureState;
|
||||
|
|
|
@ -43,14 +43,10 @@ G_DEFINE_TYPE(GstVaapiWindowGLX,
|
|||
GstVaapiWindowGLXPrivate))
|
||||
|
||||
struct _GstVaapiWindowGLXPrivate {
|
||||
XVisualInfo *vi;
|
||||
XVisualInfo vi_static;
|
||||
Colormap cmap;
|
||||
GLXContext context;
|
||||
GLContextState *gl_context;
|
||||
guint is_constructed : 1;
|
||||
guint foreign_context : 1;
|
||||
guint foreign_window : 1;
|
||||
guint swapped_buffers : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -59,9 +55,6 @@ enum {
|
|||
PROP_GLX_CONTEXT
|
||||
};
|
||||
|
||||
static XVisualInfo *
|
||||
gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window);
|
||||
|
||||
/* Fill rectangle coords with capped bounds */
|
||||
static inline void
|
||||
fill_rect(
|
||||
|
@ -91,149 +84,114 @@ fill_rect(
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_gst_vaapi_window_glx_set_context(
|
||||
static void
|
||||
_gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
if (priv->gl_context) {
|
||||
gl_destroy_context(priv->gl_context);
|
||||
priv->gl_context = NULL;
|
||||
}
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gst_vaapi_window_glx_create_context(
|
||||
GstVaapiWindowGLX *window,
|
||||
GLXContext context,
|
||||
gboolean is_foreign
|
||||
GLXContext foreign_context
|
||||
)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
GLContextState parent_cs;
|
||||
|
||||
parent_cs.display = dpy;
|
||||
parent_cs.window = None;
|
||||
parent_cs.context = foreign_context;
|
||||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
priv->gl_context = gl_create_context(dpy, DefaultScreen(dpy), &parent_cs);
|
||||
if (!priv->gl_context) {
|
||||
GST_DEBUG("could not create GLX context");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!glXIsDirect(dpy, priv->gl_context->context)) {
|
||||
GST_DEBUG("could not create a direct-rendering GLX context");
|
||||
goto out_destroy_context;
|
||||
}
|
||||
goto end;
|
||||
|
||||
out_destroy_context:
|
||||
gl_destroy_context(priv->gl_context);
|
||||
priv->gl_context = NULL;
|
||||
end:
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
return priv->gl_context != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gst_vaapi_window_glx_ensure_context(
|
||||
GstVaapiWindowGLX *window,
|
||||
GLXContext foreign_context
|
||||
)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
|
||||
priv->context = context;
|
||||
priv->foreign_context = is_foreign;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
|
||||
if (priv->context) {
|
||||
if (!priv->foreign_context) {
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
if (glXGetCurrentContext() == priv->context) {
|
||||
/* XXX: if buffers were never swapped, the application
|
||||
will crash later with the NVIDIA driver */
|
||||
if (!priv->swapped_buffers)
|
||||
gl_swap_buffers(dpy, GST_VAAPI_OBJECT_ID(window));
|
||||
gl_make_current(dpy, None, NULL, NULL);
|
||||
}
|
||||
glXDestroyContext(dpy, priv->context);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
}
|
||||
priv->context = NULL;
|
||||
priv->foreign_context = FALSE;
|
||||
if (priv->gl_context) {
|
||||
if (!foreign_context || foreign_context == priv->gl_context->context)
|
||||
return TRUE;
|
||||
_gst_vaapi_window_glx_destroy_context(window);
|
||||
}
|
||||
return _gst_vaapi_window_glx_create_context(window, foreign_context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window)
|
||||
gst_vaapi_window_glx_ensure_context(
|
||||
GstVaapiWindowGLX *window,
|
||||
GLXContext foreign_context
|
||||
)
|
||||
{
|
||||
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;
|
||||
GLContextState old_cs;
|
||||
guint width, height;
|
||||
|
||||
if (!gst_vaapi_window_glx_create_visual(window))
|
||||
if (!_gst_vaapi_window_glx_ensure_context(window, foreign_context))
|
||||
return FALSE;
|
||||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
ctx = glXCreateContext(dpy, priv->vi, NULL, True);
|
||||
if (ctx && glXIsDirect(dpy, ctx)) {
|
||||
_gst_vaapi_window_glx_set_context(window, ctx, FALSE);
|
||||
if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), ctx, &cs)) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDrawBuffer(GL_BACK);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &width, &height);
|
||||
gl_resize(width, height);
|
||||
|
||||
gl_set_bgcolor(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (cs.context)
|
||||
gl_make_current(dpy, cs.window, cs.context, NULL);
|
||||
has_errors = FALSE;
|
||||
}
|
||||
priv->gl_context->window = GST_VAAPI_OBJECT_ID(window);
|
||||
if (!gl_set_current_context(priv->gl_context, &old_cs)) {
|
||||
GST_DEBUG("could not make newly created GLX context current");
|
||||
return FALSE;
|
||||
}
|
||||
else if (ctx)
|
||||
glXDestroyContext(dpy, ctx);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
|
||||
return !has_errors;
|
||||
}
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDrawBuffer(GL_BACK);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
static inline void
|
||||
gst_vaapi_window_glx_destroy_visual(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &width, &height);
|
||||
gl_resize(width, height);
|
||||
|
||||
if (priv->vi) {
|
||||
if (priv->vi != &priv->vi_static)
|
||||
XFree(priv->vi);
|
||||
priv->vi = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static XVisualInfo *
|
||||
gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
XWindowAttributes wattr;
|
||||
int screen;
|
||||
gboolean has_errors;
|
||||
|
||||
/* XXX: add and use a GstVaapiWindow:double-buffer property? */
|
||||
static GLint gl_visual_attr[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GL_NONE
|
||||
};
|
||||
|
||||
if (!priv->vi) {
|
||||
/* XXX: add and use a GstVaapiDisplayX11:x11-screen property? */
|
||||
screen = DefaultScreen(dpy);
|
||||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
x11_trap_errors();
|
||||
if (!priv->foreign_window)
|
||||
priv->vi = glXChooseVisual(dpy, screen, gl_visual_attr);
|
||||
else {
|
||||
XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr);
|
||||
if (XMatchVisualInfo(dpy, screen, wattr.depth, wattr.visual->class,
|
||||
&priv->vi_static))
|
||||
priv->vi = &priv->vi_static;
|
||||
}
|
||||
has_errors = x11_untrap_errors() != 0;
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
|
||||
if (has_errors)
|
||||
return NULL;
|
||||
}
|
||||
return priv->vi;
|
||||
gl_set_bgcolor(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
gl_set_current_context(&old_cs, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Visual *
|
||||
gst_vaapi_window_glx_get_visual(GstVaapiWindow *window)
|
||||
{
|
||||
XVisualInfo *vi;
|
||||
GstVaapiWindowGLX * const glx_window = GST_VAAPI_WINDOW_GLX(window);
|
||||
|
||||
vi = gst_vaapi_window_glx_create_visual(GST_VAAPI_WINDOW_GLX(window));
|
||||
if (!vi)
|
||||
if (!_gst_vaapi_window_glx_ensure_context(glx_window, NULL))
|
||||
return NULL;
|
||||
return vi->visual;
|
||||
return glx_window->priv->gl_context->visual->visual;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -259,33 +217,34 @@ gst_vaapi_window_glx_create_colormap(GstVaapiWindowGLX *window)
|
|||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
int screen;
|
||||
XWindowAttributes wattr;
|
||||
XVisualInfo *vi;
|
||||
gboolean has_errors;
|
||||
gboolean success = FALSE;
|
||||
|
||||
if (!priv->cmap) {
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
x11_trap_errors();
|
||||
if (!priv->foreign_window) {
|
||||
vi = gst_vaapi_window_glx_create_visual(window);
|
||||
if (vi) {
|
||||
/* XXX: add a GstVaapiDisplayX11:x11-screen property? */
|
||||
screen = DefaultScreen(dpy);
|
||||
priv->cmap = XCreateColormap(
|
||||
dpy,
|
||||
RootWindow(dpy, screen),
|
||||
vi->visual,
|
||||
AllocNone
|
||||
);
|
||||
}
|
||||
if (!_gst_vaapi_window_glx_ensure_context(window, NULL))
|
||||
return None;
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
x11_trap_errors();
|
||||
/* XXX: add a GstVaapiDisplayX11:x11-screen property? */
|
||||
screen = DefaultScreen(dpy);
|
||||
priv->cmap = XCreateColormap(
|
||||
dpy,
|
||||
RootWindow(dpy, screen),
|
||||
priv->gl_context->visual->visual,
|
||||
AllocNone
|
||||
);
|
||||
success = x11_untrap_errors() == 0;
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
}
|
||||
else {
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
x11_trap_errors();
|
||||
XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr);
|
||||
priv->cmap = wattr.colormap;
|
||||
success = x11_untrap_errors() == 0;
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
}
|
||||
has_errors = x11_untrap_errors() != 0;
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
|
||||
if (has_errors)
|
||||
if (!success)
|
||||
return None;
|
||||
}
|
||||
return priv->cmap;
|
||||
|
@ -302,7 +261,7 @@ 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;
|
||||
GLContextState old_cs;
|
||||
|
||||
if (!GST_VAAPI_WINDOW_CLASS(gst_vaapi_window_glx_parent_class)->
|
||||
resize(window, width, height))
|
||||
|
@ -310,10 +269,9 @@ gst_vaapi_window_glx_resize(GstVaapiWindow *window, guint width, guint height)
|
|||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
XSync(dpy, False); /* make sure resize completed */
|
||||
if (gl_make_current(dpy, GST_VAAPI_OBJECT_ID(window), priv->context, &cs)) {
|
||||
if (gl_set_current_context(priv->gl_context, &old_cs)) {
|
||||
gl_resize(width, height);
|
||||
if (cs.context)
|
||||
gl_make_current(dpy, cs.window, cs.context, NULL);
|
||||
gl_set_current_context(&old_cs, NULL);
|
||||
}
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
return TRUE;
|
||||
|
@ -324,8 +282,7 @@ gst_vaapi_window_glx_finalize(GObject *object)
|
|||
{
|
||||
GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object);
|
||||
|
||||
gst_vaapi_window_glx_destroy_context(window);
|
||||
gst_vaapi_window_glx_destroy_visual(window);
|
||||
_gst_vaapi_window_glx_destroy_context(window);
|
||||
gst_vaapi_window_glx_destroy_colormap(window);
|
||||
|
||||
G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class)->finalize(object);
|
||||
|
@ -377,8 +334,6 @@ gst_vaapi_window_glx_constructed(GObject *object)
|
|||
GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(object)->priv;
|
||||
GObjectClass *parent_class;
|
||||
|
||||
priv->foreign_context = priv->context != NULL;
|
||||
|
||||
parent_class = G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class);
|
||||
if (parent_class->constructed)
|
||||
parent_class->constructed(object);
|
||||
|
@ -386,8 +341,8 @@ gst_vaapi_window_glx_constructed(GObject *object)
|
|||
priv->foreign_window =
|
||||
gst_vaapi_window_x11_is_foreign_xid(GST_VAAPI_WINDOW_X11(object));
|
||||
|
||||
priv->is_constructed = priv->foreign_context ||
|
||||
gst_vaapi_window_glx_create_context(GST_VAAPI_WINDOW_GLX(object));
|
||||
priv->is_constructed =
|
||||
gst_vaapi_window_glx_ensure_context(GST_VAAPI_WINDOW_GLX(object), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -429,13 +384,10 @@ gst_vaapi_window_glx_init(GstVaapiWindowGLX *window)
|
|||
GstVaapiWindowGLXPrivate *priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window);
|
||||
|
||||
window->priv = priv;
|
||||
priv->vi = NULL;
|
||||
priv->cmap = None;
|
||||
priv->context = NULL;
|
||||
priv->gl_context = NULL;
|
||||
priv->is_constructed = FALSE;
|
||||
priv->foreign_context = FALSE;
|
||||
priv->foreign_window = FALSE;
|
||||
priv->swapped_buffers = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -505,7 +457,7 @@ 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;
|
||||
return window->priv->gl_context->context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -526,13 +478,7 @@ 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);
|
||||
|
||||
if (ctx) {
|
||||
_gst_vaapi_window_glx_set_context(window, ctx, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
return gst_vaapi_window_glx_create_context(window);
|
||||
return gst_vaapi_window_glx_ensure_context(window, ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -554,12 +500,7 @@ gst_vaapi_window_glx_make_current(GstVaapiWindowGLX *window)
|
|||
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
|
||||
);
|
||||
success = gl_set_current_context(window->priv->gl_context, NULL);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
return success;
|
||||
}
|
||||
|
@ -579,14 +520,8 @@ gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window)
|
|||
g_return_if_fail(window->priv->is_constructed);
|
||||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
gl_swap_buffers(
|
||||
GST_VAAPI_OBJECT_XDISPLAY(window),
|
||||
GST_VAAPI_OBJECT_ID(window)
|
||||
);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
gl_swap_buffers(window->priv->gl_context);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
|
||||
window->priv->swapped_buffers = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue