From 702f844a7e61488bdb6f2fcfcd24a291ba456501 Mon Sep 17 00:00:00 2001 From: gb Date: Wed, 31 Mar 2010 15:25:19 +0000 Subject: [PATCH] Improve handling of GL contexts. --- gst-libs/gst/vaapi/gstvaapitexture.c | 21 +++ gst-libs/gst/vaapi/gstvaapiutils_glx.c | 151 ++++++++++++++++-- gst-libs/gst/vaapi/gstvaapiutils_glx.h | 23 ++- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 275 ++++++++++++-------------------- 4 files changed, 280 insertions(+), 190 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 2022c29..155d7d4 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -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; diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.c b/gst-libs/gst/vaapi/gstvaapiutils_glx.c index 93e8465..60a7bc7 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.c @@ -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; } /** diff --git a/gst-libs/gst/vaapi/gstvaapiutils_glx.h b/gst-libs/gst/vaapi/gstvaapiutils_glx.h index 3c83da2..a13adbd 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_glx.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_glx.h @@ -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; }; +GLContextState * +gl_create_context(Display *dpy, int screen, GLContextState *parent) + attribute_hidden; + +void +gl_destroy_context(GLContextState *cs) + attribute_hidden; + +void +gl_get_current_context(GLContextState *cs) + attribute_hidden; + gboolean -gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state) +gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs) attribute_hidden; void -gl_swap_buffers(Display *dpy, Window win) +gl_swap_buffers(GLContextState *cs) attribute_hidden; typedef struct _GLTextureState GLTextureState; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index a1f9dc6..bd905e9 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -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( - GstVaapiWindowGLX *window, - GLXContext context, - gboolean is_foreign -) -{ - GstVaapiWindowGLXPrivate * const priv = window->priv; - - priv->context = context; - priv->foreign_context = is_foreign; -} - static void -gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window) +_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; + 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) +_gst_vaapi_window_glx_create_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 parent_cs; - if (!gst_vaapi_window_glx_create_visual(window)) - return FALSE; + parent_cs.display = dpy; + parent_cs.window = None; + parent_cs.context = foreign_context; 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 = gl_create_context(dpy, DefaultScreen(dpy), &parent_cs); + if (!priv->gl_context) { + GST_DEBUG("could not create GLX context"); + goto end; } - else if (ctx) - glXDestroyContext(dpy, ctx); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window); - return !has_errors; + 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 inline void -gst_vaapi_window_glx_destroy_visual(GstVaapiWindowGLX *window) +static gboolean +_gst_vaapi_window_glx_ensure_context( + GstVaapiWindowGLX *window, + GLXContext foreign_context +) { GstVaapiWindowGLXPrivate * const priv = window->priv; - if (priv->vi) { - if (priv->vi != &priv->vi_static) - XFree(priv->vi); - priv->vi = NULL; + 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 XVisualInfo * -gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window) +static gboolean +gst_vaapi_window_glx_ensure_context( + GstVaapiWindowGLX *window, + GLXContext foreign_context +) { 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); + GLContextState old_cs; + guint width, height; - if (has_errors) - return NULL; + if (!_gst_vaapi_window_glx_ensure_context(window, foreign_context)) + return 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; } - return priv->vi; + + 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); + 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; } /** -- 2.7.4