Blame SOURCES/CoglTexturePixmapX11-add-support-for-stereo-content.patch

b987e2
From e0243443ccb12eb1a9f62d9b4258bb111551998c Mon Sep 17 00:00:00 2001
b987e2
From: "Owen W. Taylor" <otaylor@fishsoup.net>
b987e2
Date: Sat, 26 Apr 2014 16:38:58 -0400
b987e2
Subject: [PATCH 6/8] CoglTexturePixmapX11: add support for stereo content
b987e2
b987e2
Add cogl_texture_pixmap_x11_new_left() and
b987e2
cogl_texture_pixmap_x11_new_right() (which takes the left texture
b987e2
as an argument) for texture pixmap rendering with stereo content.
b987e2
The underlying GLXPixmap is created using a stereo visual and shared
b987e2
between the left and right textures.
b987e2
---
b987e2
 cogl/cogl-glx-display-private.h               |   3 +-
b987e2
 cogl/winsys/cogl-texture-pixmap-x11-private.h |  18 ++++
b987e2
 cogl/winsys/cogl-texture-pixmap-x11.c         |  92 +++++++++++++++++++--
b987e2
 cogl/winsys/cogl-texture-pixmap-x11.h         |  56 +++++++++++++
b987e2
 cogl/winsys/cogl-winsys-egl-x11.c             |   4 +-
b987e2
 cogl/winsys/cogl-winsys-glx.c                 | 113 ++++++++++++++++++--------
b987e2
 cogl/winsys/cogl-winsys-private.h             |   4 +-
b987e2
 7 files changed, 246 insertions(+), 44 deletions(-)
b987e2
b987e2
diff --git a/cogl/cogl-glx-display-private.h b/cogl/cogl-glx-display-private.h
b987e2
index 69b1570..9f7ad47 100644
b987e2
--- a/cogl/cogl-glx-display-private.h
b987e2
+++ b/cogl/cogl-glx-display-private.h
b987e2
@@ -33,10 +33,11 @@ typedef struct _CoglGLXCachedConfig
b987e2
   int depth;
b987e2
   CoglBool found;
b987e2
   GLXFBConfig fb_config;
b987e2
+  CoglBool stereo;
b987e2
   CoglBool can_mipmap;
b987e2
 } CoglGLXCachedConfig;
b987e2
 
b987e2
-#define COGL_GLX_N_CACHED_CONFIGS 3
b987e2
+#define COGL_GLX_N_CACHED_CONFIGS 6
b987e2
 
b987e2
 typedef struct _CoglGLXDisplay
b987e2
 {
b987e2
diff --git a/cogl/winsys/cogl-texture-pixmap-x11-private.h b/cogl/winsys/cogl-texture-pixmap-x11-private.h
b987e2
index b99dfa6..ce79bd3 100644
b987e2
--- a/cogl/winsys/cogl-texture-pixmap-x11-private.h
b987e2
+++ b/cogl/winsys/cogl-texture-pixmap-x11-private.h
b987e2
@@ -48,10 +48,27 @@ struct _CoglDamageRectangle
b987e2
   unsigned int y2;
b987e2
 };
b987e2
 
b987e2
+/* For stereo, there are a pair of textures, but we want to share most
b987e2
+ * other state (the GLXPixmap, visual, etc.) The way we do this is that
b987e2
+ * the left-eye texture has all the state (there is in fact, no internal
b987e2
+ * difference between the a MONO and a LEFT texture ), and the
b987e2
+ * right-eye texture simply points to the left eye texture, with all
b987e2
+ * other fields ignored.
b987e2
+ */
b987e2
+typedef enum
b987e2
+{
b987e2
+  COGL_TEXTURE_PIXMAP_MONO,
b987e2
+  COGL_TEXTURE_PIXMAP_LEFT,
b987e2
+  COGL_TEXTURE_PIXMAP_RIGHT
b987e2
+} CoglTexturePixmapStereoMode;
b987e2
+
b987e2
 struct _CoglTexturePixmapX11
b987e2
 {
b987e2
   CoglTexture _parent;
b987e2
 
b987e2
+  CoglTexturePixmapStereoMode stereo_mode;
b987e2
+  CoglTexturePixmapX11 *left; /* Set only if stereo_mode=RIGHT */
b987e2
+
b987e2
   Pixmap pixmap;
b987e2
   CoglTexture *tex;
b987e2
 
b987e2
@@ -75,4 +92,5 @@ struct _CoglTexturePixmapX11
b987e2
   CoglBool use_winsys_texture;
b987e2
 };
b987e2
 
b987e2
+
b987e2
 #endif /* __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H */
b987e2
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/winsys/cogl-texture-pixmap-x11.c
b987e2
index 71d00ea..baf27e1 100644
b987e2
--- a/cogl/winsys/cogl-texture-pixmap-x11.c
b987e2
+++ b/cogl/winsys/cogl-texture-pixmap-x11.c
b987e2
@@ -274,11 +274,12 @@ set_damage_object_internal (CoglContext *ctx,
b987e2
                                    tex_pixmap);
b987e2
 }
b987e2
 
b987e2
-CoglTexturePixmapX11 *
b987e2
-cogl_texture_pixmap_x11_new (CoglContext *ctxt,
b987e2
-                             uint32_t pixmap,
b987e2
-                             CoglBool automatic_updates,
b987e2
-                             CoglError **error)
b987e2
+static CoglTexturePixmapX11 *
b987e2
+_cogl_texture_pixmap_x11_new (CoglContext *ctxt,
b987e2
+                              uint32_t pixmap,
b987e2
+                              CoglBool automatic_updates,
b987e2
+                              CoglTexturePixmapStereoMode stereo_mode,
b987e2
+                              CoglError **error)
b987e2
 {
b987e2
   CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1);
b987e2
   Display *display = cogl_xlib_renderer_get_display (ctxt->display->renderer);
b987e2
@@ -308,6 +309,8 @@ cogl_texture_pixmap_x11_new (CoglContext *ctxt,
b987e2
                       &cogl_texture_pixmap_x11_vtable);
b987e2
 
b987e2
   tex_pixmap->pixmap = pixmap;
b987e2
+  tex_pixmap->stereo_mode = stereo_mode;
b987e2
+  tex_pixmap->left = NULL;
b987e2
   tex_pixmap->image = NULL;
b987e2
   tex_pixmap->shm_info.shmid = -1;
b987e2
   tex_pixmap->tex = NULL;
b987e2
@@ -366,6 +369,52 @@ cogl_texture_pixmap_x11_new (CoglContext *ctxt,
b987e2
   return _cogl_texture_pixmap_x11_object_new (tex_pixmap);
b987e2
 }
b987e2
 
b987e2
+CoglTexturePixmapX11 *
b987e2
+cogl_texture_pixmap_x11_new (CoglContext *ctxt,
b987e2
+                             uint32_t pixmap,
b987e2
+                             CoglBool automatic_updates,
b987e2
+                             CoglError **error)
b987e2
+
b987e2
+{
b987e2
+  return _cogl_texture_pixmap_x11_new (ctxt, pixmap,
b987e2
+                                       automatic_updates, COGL_TEXTURE_PIXMAP_MONO,
b987e2
+                                       error);
b987e2
+}
b987e2
+
b987e2
+CoglTexturePixmapX11 *
b987e2
+cogl_texture_pixmap_x11_new_left (CoglContext *ctxt,
b987e2
+                                  uint32_t pixmap,
b987e2
+                                  CoglBool automatic_updates,
b987e2
+                                  CoglError **error)
b987e2
+{
b987e2
+  return _cogl_texture_pixmap_x11_new (ctxt, pixmap,
b987e2
+                                       automatic_updates, COGL_TEXTURE_PIXMAP_LEFT,
b987e2
+                                       error);
b987e2
+}
b987e2
+
b987e2
+CoglTexturePixmapX11 *
b987e2
+cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *tfp_left)
b987e2
+{
b987e2
+  CoglTexture *texture_left = COGL_TEXTURE (tfp_left);
b987e2
+  CoglTexturePixmapX11 *tfp_right;
b987e2
+
b987e2
+  g_return_val_if_fail (tfp_left->stereo_mode == COGL_TEXTURE_PIXMAP_LEFT, NULL);
b987e2
+
b987e2
+  tfp_right = g_new0 (CoglTexturePixmapX11, 1);
b987e2
+  tfp_right->stereo_mode = COGL_TEXTURE_PIXMAP_RIGHT;
b987e2
+  tfp_right->left = cogl_object_ref (tfp_left);
b987e2
+
b987e2
+  _cogl_texture_init (COGL_TEXTURE (tfp_right),
b987e2
+		      texture_left->context,
b987e2
+		      texture_left->width,
b987e2
+		      texture_left->height,
b987e2
+		      &cogl_texture_pixmap_x11_vtable);
b987e2
+
b987e2
+  _cogl_texture_set_allocated (COGL_TEXTURE (tfp_right), TRUE);
b987e2
+
b987e2
+  return _cogl_texture_pixmap_x11_object_new (tfp_right);
b987e2
+}
b987e2
+
b987e2
 static CoglBool
b987e2
 _cogl_texture_pixmap_x11_allocate (CoglTexture *tex,
b987e2
                                    CoglError **error)
b987e2
@@ -457,6 +506,9 @@ cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap,
b987e2
      texture because we can't determine which will be needed until we
b987e2
      actually render something */
b987e2
 
b987e2
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
b987e2
+    tex_pixmap = tex_pixmap->left;
b987e2
+
b987e2
   if (tex_pixmap->winsys)
b987e2
     {
b987e2
       const CoglWinsysVtable *winsys;
b987e2
@@ -471,6 +523,9 @@ cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap,
b987e2
 CoglBool
b987e2
 cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap)
b987e2
 {
b987e2
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
b987e2
+    tex_pixmap = tex_pixmap->left;
b987e2
+
b987e2
   return !!tex_pixmap->winsys;
b987e2
 }
b987e2
 
b987e2
@@ -484,6 +539,8 @@ cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *tex_pixmap,
b987e2
 
b987e2
   _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
b987e2
 
b987e2
+  g_return_if_fail (tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_RIGHT);
b987e2
+
b987e2
   damage_base = _cogl_xlib_get_damage_base ();
b987e2
   if (damage_base >= 0)
b987e2
     set_damage_object_internal (ctxt, tex_pixmap, damage, report_level);
b987e2
@@ -648,12 +705,16 @@ static void
b987e2
 _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
                                  CoglBool needs_mipmap)
b987e2
 {
b987e2
+  CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode;
b987e2
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
b987e2
+    tex_pixmap = tex_pixmap->left;
b987e2
+
b987e2
   if (tex_pixmap->winsys)
b987e2
     {
b987e2
       const CoglWinsysVtable *winsys =
b987e2
         _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
b987e2
 
b987e2
-      if (winsys->texture_pixmap_x11_update (tex_pixmap, needs_mipmap))
b987e2
+      if (winsys->texture_pixmap_x11_update (tex_pixmap, stereo_mode, needs_mipmap))
b987e2
         {
b987e2
           _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE);
b987e2
           return;
b987e2
@@ -670,8 +731,13 @@ _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
 static CoglTexture *
b987e2
 _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
b987e2
 {
b987e2
+  CoglTexturePixmapX11 *original_pixmap = tex_pixmap;
b987e2
   CoglTexture *tex;
b987e2
   int i;
b987e2
+  CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode;
b987e2
+
b987e2
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
b987e2
+    tex_pixmap = tex_pixmap->left;
b987e2
 
b987e2
   /* We try getting the texture twice, once without flushing the
b987e2
      updates and once with. If pre_paint has been called already then
b987e2
@@ -688,7 +754,7 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
b987e2
         {
b987e2
           const CoglWinsysVtable *winsys =
b987e2
             _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
b987e2
-          tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap);
b987e2
+          tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap, stereo_mode);
b987e2
         }
b987e2
       else
b987e2
         tex = tex_pixmap->tex;
b987e2
@@ -696,7 +762,7 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
b987e2
       if (tex)
b987e2
         return tex;
b987e2
 
b987e2
-      _cogl_texture_pixmap_x11_update (tex_pixmap, FALSE);
b987e2
+      _cogl_texture_pixmap_x11_update (original_pixmap, FALSE);
b987e2
     }
b987e2
 
b987e2
   g_assert_not_reached ();
b987e2
@@ -978,6 +1044,16 @@ _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
b987e2
 
b987e2
   _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
b987e2
 
b987e2
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
b987e2
+    {
b987e2
+      cogl_object_unref (tex_pixmap->left);
b987e2
+
b987e2
+      /* Chain up */
b987e2
+      _cogl_texture_free (COGL_TEXTURE (tex_pixmap));
b987e2
+
b987e2
+      return;
b987e2
+    }
b987e2
+
b987e2
   display = cogl_xlib_renderer_get_display (ctxt->display->renderer);
b987e2
 
b987e2
   set_damage_object_internal (ctxt, tex_pixmap, 0, 0);
b987e2
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.h b/cogl/winsys/cogl-texture-pixmap-x11.h
b987e2
index 5d78af3..a3652a4 100644
b987e2
--- a/cogl/winsys/cogl-texture-pixmap-x11.h
b987e2
+++ b/cogl/winsys/cogl-texture-pixmap-x11.h
b987e2
@@ -103,6 +103,62 @@ cogl_texture_pixmap_x11_new (CoglContext *context,
b987e2
                              CoglError **error);
b987e2
 
b987e2
 /**
b987e2
+ * cogl_texture_pixmap_x11_new_left:
b987e2
+ * @context: A #CoglContext
b987e2
+ * @pixmap: A X11 pixmap ID
b987e2
+ * @automatic_updates: Whether to automatically copy the contents of
b987e2
+ * the pixmap to the texture.
b987e2
+ * @error: A #CoglError for exceptions
b987e2
+ *
b987e2
+ * Creates one of a pair of textures to contain the contents of @pixmap,
b987e2
+ * which has stereo content. (Different images for the right and left eyes.)
b987e2
+ * The left image is drawn using this texture; the right image is drawn
b987e2
+ * using a texture created by calling
b987e2
+ * cogl_texture_pixmap_x11_new_right() and passing in this texture as an
b987e2
+ * argument.
b987e2
+ *
b987e2
+ * In general, you should not use this function unless you have
b987e2
+ * queried the %GLX_STEREO_TREE_EXT attribute of the corresponding
b987e2
+ * window using glXQueryDrawable() and determined that the window is
b987e2
+ * stereo. Note that this attribute can change over time and
b987e2
+ * notification is also provided through events defined in the
b987e2
+ * EXT_stereo_tree GLX extension. As long as the system has support for
b987e2
+ * stereo content, drawing using the left and right pixmaps will not
b987e2
+ * produce an error even if the window doesn't have stereo
b987e2
+ * content any more, but drawing with the right pixmap will produce
b987e2
+ * undefined output, so you need to listen for these events and
b987e2
+ * re-render to avoid race conditions. (Recreating a non-stereo
b987e2
+ * pixmap is not necessary, but may save resources.)
b987e2
+ *
b987e2
+ * Return value: a new #CoglTexturePixmapX11 instance
b987e2
+ *
b987e2
+ * Since: 1.20
b987e2
+ * Stability: Unstable
b987e2
+ */
b987e2
+CoglTexturePixmapX11 *
b987e2
+cogl_texture_pixmap_x11_new_left (CoglContext *context,
b987e2
+                                  uint32_t pixmap,
b987e2
+                                  CoglBool automatic_updates,
b987e2
+                                  CoglError **error);
b987e2
+
b987e2
+/**
b987e2
+ * cogl_texture_pixmap_x11_new_right:
b987e2
+ * @left_texture: A #CoglTexturePixmapX11 instance created with
b987e2
+ *                cogl_texture_pixmap_x11_new_left().
b987e2
+ *
b987e2
+ * Creates a texture object that corresponds to the right-eye image
b987e2
+ * of a pixmap with stereo content. @left_texture must have been
b987e2
+ * created using cogl_texture_pixmap_x11_new_left().
b987e2
+ *
b987e2
+ * Return value: a new #CoglTexturePixmapX11 instance
b987e2
+ *
b987e2
+ * Since: 1.20
b987e2
+ * Stability: Unstable
b987e2
+ */
b987e2
+CoglTexturePixmapX11 *
b987e2
+cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *left_texture);
b987e2
+
b987e2
+/**
b987e2
  * cogl_texture_pixmap_x11_update_area:
b987e2
  * @texture: A #CoglTexturePixmapX11 instance
b987e2
  * @x: x coordinate of the area to update
b987e2
diff --git a/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/winsys/cogl-winsys-egl-x11.c
b987e2
index 3e91b99..6752029 100644
b987e2
--- a/cogl/winsys/cogl-winsys-egl-x11.c
b987e2
+++ b/cogl/winsys/cogl-winsys-egl-x11.c
b987e2
@@ -760,6 +760,7 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
b987e2
 
b987e2
 static CoglBool
b987e2
 _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
+                                        CoglBool right,
b987e2
                                         CoglBool needs_mipmap)
b987e2
 {
b987e2
   if (needs_mipmap)
b987e2
@@ -774,7 +775,8 @@ _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
b987e2
 }
b987e2
 
b987e2
 static CoglTexture *
b987e2
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
b987e2
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap,
b987e2
+                                             CoglBool right)
b987e2
 {
b987e2
   CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys;
b987e2
 
b987e2
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
b987e2
index bff5178..334691c 100644
b987e2
--- a/cogl/winsys/cogl-winsys-glx.c
b987e2
+++ b/cogl/winsys/cogl-winsys-glx.c
b987e2
@@ -89,16 +89,21 @@ typedef struct _CoglOnscreenGLX
b987e2
   CoglBool pending_resize_notify;
b987e2
 } CoglOnscreenGLX;
b987e2
 
b987e2
+typedef struct _CoglPixmapTextureEyeGLX
b987e2
+{
b987e2
+  CoglTexture *glx_tex;
b987e2
+  CoglBool bind_tex_image_queued;
b987e2
+  CoglBool pixmap_bound;
b987e2
+} CoglPixmapTextureEyeGLX;
b987e2
+
b987e2
 typedef struct _CoglTexturePixmapGLX
b987e2
 {
b987e2
   GLXPixmap glx_pixmap;
b987e2
   CoglBool has_mipmap_space;
b987e2
   CoglBool can_mipmap;
b987e2
 
b987e2
-  CoglTexture *glx_tex;
b987e2
-
b987e2
-  CoglBool bind_tex_image_queued;
b987e2
-  CoglBool pixmap_bound;
b987e2
+  CoglPixmapTextureEyeGLX left;
b987e2
+  CoglPixmapTextureEyeGLX right;
b987e2
 } CoglTexturePixmapGLX;
b987e2
 
b987e2
 /* Define a set of arrays containing the functions required from GL
b987e2
@@ -1965,6 +1970,7 @@ _cogl_winsys_xlib_get_visual_info (void)
b987e2
 static CoglBool
b987e2
 get_fbconfig_for_depth (CoglContext *context,
b987e2
                         unsigned int depth,
b987e2
+                        CoglBool stereo,
b987e2
                         GLXFBConfig *fbconfig_ret,
b987e2
                         CoglBool *can_mipmap_ret)
b987e2
 {
b987e2
@@ -1982,11 +1988,12 @@ get_fbconfig_for_depth (CoglContext *context,
b987e2
   glx_renderer = context->display->renderer->winsys;
b987e2
   glx_display = context->display->winsys;
b987e2
 
b987e2
-  /* Check if we've already got a cached config for this depth */
b987e2
+  /* Check if we've already got a cached config for this depth and stereo */
b987e2
   for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++)
b987e2
     if (glx_display->glx_cached_configs[i].depth == -1)
b987e2
       spare_cache_slot = i;
b987e2
-    else if (glx_display->glx_cached_configs[i].depth == depth)
b987e2
+    else if (glx_display->glx_cached_configs[i].depth == depth &&
b987e2
+             glx_display->glx_cached_configs[i].stereo == stereo)
b987e2
       {
b987e2
         *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config;
b987e2
         *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap;
b987e2
@@ -2030,6 +2037,13 @@ get_fbconfig_for_depth (CoglContext *context,
b987e2
       if (value != depth && (value - alpha) != depth)
b987e2
         continue;
b987e2
 
b987e2
+      glx_renderer->glXGetFBConfigAttrib (dpy,
b987e2
+                                          fbconfigs[i],
b987e2
+                                          GLX_STEREO,
b987e2
+                                          &value);
b987e2
+      if (!!value != !!stereo)
b987e2
+        continue;
b987e2
+
b987e2
       if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4)
b987e2
         {
b987e2
           glx_renderer->glXGetFBConfigAttrib (dpy,
b987e2
@@ -2187,7 +2201,9 @@ try_create_glx_pixmap (CoglContext *context,
b987e2
   glx_renderer = renderer->winsys;
b987e2
   dpy = xlib_renderer->xdpy;
b987e2
 
b987e2
-  if (!get_fbconfig_for_depth (context, depth, &fb_config,
b987e2
+  if (!get_fbconfig_for_depth (context, depth,
b987e2
+                               tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_MONO,
b987e2
+                               &fb_config,
b987e2
                                &glx_tex_pixmap->can_mipmap))
b987e2
     {
b987e2
       COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i",
b987e2
@@ -2276,10 +2292,13 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
b987e2
   glx_tex_pixmap->can_mipmap = FALSE;
b987e2
   glx_tex_pixmap->has_mipmap_space = FALSE;
b987e2
 
b987e2
-  glx_tex_pixmap->glx_tex = NULL;
b987e2
+  glx_tex_pixmap->left.glx_tex = NULL;
b987e2
+  glx_tex_pixmap->right.glx_tex = NULL;
b987e2
 
b987e2
-  glx_tex_pixmap->bind_tex_image_queued = TRUE;
b987e2
-  glx_tex_pixmap->pixmap_bound = FALSE;
b987e2
+  glx_tex_pixmap->left.bind_tex_image_queued = TRUE;
b987e2
+  glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
b987e2
+  glx_tex_pixmap->left.pixmap_bound = FALSE;
b987e2
+  glx_tex_pixmap->right.pixmap_bound = FALSE;
b987e2
 
b987e2
   tex_pixmap->winsys = glx_tex_pixmap;
b987e2
 
b987e2
@@ -2306,10 +2325,14 @@ free_glx_pixmap (CoglContext *context,
b987e2
   xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
b987e2
   glx_renderer = renderer->winsys;
b987e2
 
b987e2
-  if (glx_tex_pixmap->pixmap_bound)
b987e2
+  if (glx_tex_pixmap->left.pixmap_bound)
b987e2
     glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
b987e2
                                       glx_tex_pixmap->glx_pixmap,
b987e2
                                       GLX_FRONT_LEFT_EXT);
b987e2
+  if (glx_tex_pixmap->right.pixmap_bound)
b987e2
+    glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
b987e2
+                                      glx_tex_pixmap->glx_pixmap,
b987e2
+                                      GLX_FRONT_RIGHT_EXT);
b987e2
 
b987e2
   /* FIXME - we need to trap errors and synchronize here because
b987e2
    * of ordering issues between the XPixmap destruction and the
b987e2
@@ -2334,7 +2357,8 @@ free_glx_pixmap (CoglContext *context,
b987e2
   _cogl_xlib_renderer_untrap_errors (renderer, &trap_state);
b987e2
 
b987e2
   glx_tex_pixmap->glx_pixmap = None;
b987e2
-  glx_tex_pixmap->pixmap_bound = FALSE;
b987e2
+  glx_tex_pixmap->left.pixmap_bound = FALSE;
b987e2
+  glx_tex_pixmap->right.pixmap_bound = FALSE;
b987e2
 }
b987e2
 
b987e2
 static void
b987e2
@@ -2349,8 +2373,11 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
b987e2
 
b987e2
   free_glx_pixmap (COGL_TEXTURE (tex_pixmap)->context, glx_tex_pixmap);
b987e2
 
b987e2
-  if (glx_tex_pixmap->glx_tex)
b987e2
-    cogl_object_unref (glx_tex_pixmap->glx_tex);
b987e2
+  if (glx_tex_pixmap->left.glx_tex)
b987e2
+    cogl_object_unref (glx_tex_pixmap->left.glx_tex);
b987e2
+
b987e2
+  if (glx_tex_pixmap->right.glx_tex)
b987e2
+    cogl_object_unref (glx_tex_pixmap->right.glx_tex);
b987e2
 
b987e2
   tex_pixmap->winsys = NULL;
b987e2
   g_free (glx_tex_pixmap);
b987e2
@@ -2358,13 +2385,27 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
b987e2
 
b987e2
 static CoglBool
b987e2
 _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
+                                        CoglTexturePixmapStereoMode stereo_mode,
b987e2
                                         CoglBool needs_mipmap)
b987e2
 {
b987e2
   CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
b987e2
   CoglContext *ctx = COGL_TEXTURE (tex_pixmap)->context;
b987e2
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
b987e2
+  CoglPixmapTextureEyeGLX *texture_info;
b987e2
+  int buffer;
b987e2
   CoglGLXRenderer *glx_renderer;
b987e2
 
b987e2
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
b987e2
+    {
b987e2
+      texture_info = &glx_tex_pixmap->right;
b987e2
+      buffer = GLX_FRONT_RIGHT_EXT;
b987e2
+    }
b987e2
+  else
b987e2
+    {
b987e2
+      texture_info = &glx_tex_pixmap->left;
b987e2
+      buffer = GLX_FRONT_LEFT_EXT;
b987e2
+    }
b987e2
+
b987e2
   /* If we don't have a GLX pixmap then fallback */
b987e2
   if (glx_tex_pixmap->glx_pixmap == None)
b987e2
     return FALSE;
b987e2
@@ -2372,7 +2413,7 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
   glx_renderer = ctx->display->renderer->winsys;
b987e2
 
b987e2
   /* Lazily create a texture to hold the pixmap */
b987e2
-  if (glx_tex_pixmap->glx_tex == NULL)
b987e2
+  if (texture_info->glx_tex == NULL)
b987e2
     {
b987e2
       CoglPixelFormat texture_format;
b987e2
       CoglError *error = NULL;
b987e2
@@ -2383,14 +2424,14 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
 
b987e2
       if (should_use_rectangle (ctx))
b987e2
         {
b987e2
-          glx_tex_pixmap->glx_tex = COGL_TEXTURE (
b987e2
+          texture_info->glx_tex = COGL_TEXTURE (
b987e2
             cogl_texture_rectangle_new_with_size (ctx,
b987e2
                                                   tex->width,
b987e2
                                                   tex->height,
b987e2
                                                   texture_format,
b987e2
                                                   &error));
b987e2
 
b987e2
-          if (glx_tex_pixmap->glx_tex)
b987e2
+          if (texture_info->glx_tex)
b987e2
             COGL_NOTE (TEXTURE_PIXMAP, "Created a texture rectangle for %p",
b987e2
                        tex_pixmap);
b987e2
           else
b987e2
@@ -2405,13 +2446,13 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
         }
b987e2
       else
b987e2
         {
b987e2
-          glx_tex_pixmap->glx_tex = COGL_TEXTURE (
b987e2
+          texture_info->glx_tex = COGL_TEXTURE (
b987e2
             cogl_texture_2d_new_with_size (ctx,
b987e2
                                            tex->width,
b987e2
                                            tex->height,
b987e2
                                            texture_format));
b987e2
 
b987e2
-          if (cogl_texture_allocate (glx_tex_pixmap->glx_tex, &error))
b987e2
+          if (cogl_texture_allocate (texture_info->glx_tex, &error))
b987e2
             COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p",
b987e2
                        tex_pixmap);
b987e2
           else
b987e2
@@ -2449,36 +2490,37 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
                          "updates for %p because creating the GLXPixmap "
b987e2
                          "with mipmap support failed", tex_pixmap);
b987e2
 
b987e2
-              if (glx_tex_pixmap->glx_tex)
b987e2
-                cogl_object_unref (glx_tex_pixmap->glx_tex);
b987e2
+              if (texture_info->glx_tex)
b987e2
+                cogl_object_unref (texture_info->glx_tex);
b987e2
               return FALSE;
b987e2
             }
b987e2
 
b987e2
-          glx_tex_pixmap->bind_tex_image_queued = TRUE;
b987e2
+          glx_tex_pixmap->left.bind_tex_image_queued = TRUE;
b987e2
+          glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
b987e2
         }
b987e2
     }
b987e2
 
b987e2
-  if (glx_tex_pixmap->bind_tex_image_queued)
b987e2
+  if (texture_info->bind_tex_image_queued)
b987e2
     {
b987e2
       GLuint gl_handle, gl_target;
b987e2
       CoglXlibRenderer *xlib_renderer =
b987e2
         _cogl_xlib_renderer_get_data (ctx->display->renderer);
b987e2
 
b987e2
-      cogl_texture_get_gl_texture (glx_tex_pixmap->glx_tex,
b987e2
+      cogl_texture_get_gl_texture (texture_info->glx_tex,
b987e2
                                    &gl_handle, &gl_target);
b987e2
 
b987e2
       COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap);
b987e2
 
b987e2
       _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE);
b987e2
 
b987e2
-      if (glx_tex_pixmap->pixmap_bound)
b987e2
+      if (texture_info->pixmap_bound)
b987e2
         glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
b987e2
                                           glx_tex_pixmap->glx_pixmap,
b987e2
-                                          GLX_FRONT_LEFT_EXT);
b987e2
+                                          buffer);
b987e2
 
b987e2
       glx_renderer->glXBindTexImage (xlib_renderer->xdpy,
b987e2
                                      glx_tex_pixmap->glx_pixmap,
b987e2
-                                     GLX_FRONT_LEFT_EXT,
b987e2
+                                     buffer,
b987e2
                                      NULL);
b987e2
 
b987e2
       /* According to the recommended usage in the spec for
b987e2
@@ -2491,10 +2533,10 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
b987e2
        * on Mesa and NVidia drivers and it is also what Compiz does so
b987e2
        * it is probably ok */
b987e2
 
b987e2
-      glx_tex_pixmap->bind_tex_image_queued = FALSE;
b987e2
-      glx_tex_pixmap->pixmap_bound = TRUE;
b987e2
+      texture_info->bind_tex_image_queued = FALSE;
b987e2
+      texture_info->pixmap_bound = TRUE;
b987e2
 
b987e2
-      _cogl_texture_2d_externally_modified (glx_tex_pixmap->glx_tex);
b987e2
+      _cogl_texture_2d_externally_modified (texture_info->glx_tex);
b987e2
     }
b987e2
 
b987e2
   return TRUE;
b987e2
@@ -2505,15 +2547,20 @@ _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
b987e2
 {
b987e2
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
b987e2
 
b987e2
-  glx_tex_pixmap->bind_tex_image_queued = TRUE;
b987e2
+  glx_tex_pixmap->left.bind_tex_image_queued = TRUE;
b987e2
+  glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
b987e2
 }
b987e2
 
b987e2
 static CoglTexture *
b987e2
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
b987e2
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap,
b987e2
+                                             CoglTexturePixmapStereoMode stereo_mode)
b987e2
 {
b987e2
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
b987e2
 
b987e2
-  return glx_tex_pixmap->glx_tex;
b987e2
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
b987e2
+    return glx_tex_pixmap->right.glx_tex;
b987e2
+  else
b987e2
+    return glx_tex_pixmap->left.glx_tex;
b987e2
 }
b987e2
 
b987e2
 static void
b987e2
diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h
b987e2
index 7cd2b24..31a1af9 100644
b987e2
--- a/cogl/winsys/cogl-winsys-private.h
b987e2
+++ b/cogl/winsys/cogl-winsys-private.h
b987e2
@@ -172,13 +172,15 @@ typedef struct _CoglWinsysVtable
b987e2
 
b987e2
   CoglBool
b987e2
   (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap,
b987e2
+                                CoglTexturePixmapStereoMode stereo_mode,
b987e2
                                 CoglBool needs_mipmap);
b987e2
 
b987e2
   void
b987e2
   (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap);
b987e2
 
b987e2
   CoglTexture *
b987e2
-  (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap);
b987e2
+  (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap,
b987e2
+                                     CoglTexturePixmapStereoMode stereo_mode);
b987e2
 #endif
b987e2
 
b987e2
   void
b987e2
-- 
b987e2
1.9.3
b987e2