Add glXSwapBuffers() workaround for NVIDIA.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Mon, 29 Mar 2010 13:40:27 +0000 (13:40 +0000)
committergb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Mon, 29 Mar 2010 13:40:27 +0000 (13:40 +0000)
gst-libs/gst/vaapi/gstvaapiutils_glx.c
gst-libs/gst/vaapi/gstvaapiutils_glx.h
gst-libs/gst/vaapi/gstvaapiwindow_glx.c

index de6ea3f..b7ba744 100644 (file)
@@ -212,6 +212,21 @@ gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state)
 }
 
 /**
+ * gl_swap_buffers:
+ * @dpy: an X11 #Display
+ * @win: an X11 #Window
+ *
+ * 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)
+{
+    glXSwapBuffers(dpy, win);
+}
+
+/**
  * gl_bind_texture:
  * @ts: a #GLTextureState
  * @target: the target to which the texture is bound
index 1902daa..69d0048 100644 (file)
@@ -64,6 +64,10 @@ gboolean
 gl_make_current(Display *dpy, Window win, GLXContext ctx, GLContextState *state)
     attribute_hidden;
 
+void
+gl_swap_buffers(Display *dpy, Window win)
+    attribute_hidden;
+
 typedef struct _GLTextureState GLTextureState;
 struct _GLTextureState {
     gboolean    was_enabled;
index 025bfbd..a1f9dc6 100644 (file)
@@ -50,6 +50,7 @@ struct _GstVaapiWindowGLXPrivate {
     guint               is_constructed  : 1;
     guint               foreign_context : 1;
     guint               foreign_window  : 1;
+    guint               swapped_buffers : 1;
 };
 
 enum {
@@ -112,8 +113,13 @@ gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window)
     if (priv->context) {
         if (!priv->foreign_context) {
             GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
-            if (glXGetCurrentContext() == priv->context)
+            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);
         }
@@ -429,6 +435,7 @@ gst_vaapi_window_glx_init(GstVaapiWindowGLX *window)
     priv->is_constructed        = FALSE;
     priv->foreign_context       = FALSE;
     priv->foreign_window        = FALSE;
+    priv->swapped_buffers       = FALSE;
 }
 
 /**
@@ -572,12 +579,14 @@ gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window)
     g_return_if_fail(window->priv->is_constructed);
 
     GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
-    glXSwapBuffers(
+    gl_swap_buffers(
         GST_VAAPI_OBJECT_XDISPLAY(window),
         GST_VAAPI_OBJECT_ID(window)
     );
     glClear(GL_COLOR_BUFFER_BIT);
     GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
+
+    window->priv->swapped_buffers = TRUE;
 }
 
 /**