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

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