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

bae666
From 4d8771a8c2ea11e37db8f86153286c741576b8ca Mon Sep 17 00:00:00 2001
07f135
From: "Owen W. Taylor" <otaylor@fishsoup.net>
07f135
Date: Sat, 26 Apr 2014 16:38:58 -0400
bae666
Subject: [PATCH] CoglTexturePixmapX11: add support for stereo content
07f135
07f135
Add cogl_texture_pixmap_x11_new_left() and
07f135
cogl_texture_pixmap_x11_new_right() (which takes the left texture
07f135
as an argument) for texture pixmap rendering with stereo content.
07f135
The underlying GLXPixmap is created using a stereo visual and shared
07f135
between the left and right textures.
bae666
bae666
Reviewed-by: Robert Bragg <robert.bragg@intel.com>
07f135
---
07f135
 cogl/cogl-glx-display-private.h               |   3 +-
07f135
 cogl/winsys/cogl-texture-pixmap-x11-private.h |  18 ++++
bae666
 cogl/winsys/cogl-texture-pixmap-x11.c         |  99 ++++++++++++++++++++--
07f135
 cogl/winsys/cogl-texture-pixmap-x11.h         |  56 +++++++++++++
07f135
 cogl/winsys/cogl-winsys-egl-x11.c             |   4 +-
07f135
 cogl/winsys/cogl-winsys-glx.c                 | 113 ++++++++++++++++++--------
07f135
 cogl/winsys/cogl-winsys-private.h             |   4 +-
bae666
 7 files changed, 253 insertions(+), 44 deletions(-)
07f135
07f135
diff --git a/cogl/cogl-glx-display-private.h b/cogl/cogl-glx-display-private.h
bae666
index 20b7e67..133c118 100644
07f135
--- a/cogl/cogl-glx-display-private.h
07f135
+++ b/cogl/cogl-glx-display-private.h
bae666
@@ -39,10 +39,11 @@ typedef struct _CoglGLXCachedConfig
07f135
   int depth;
07f135
   CoglBool found;
07f135
   GLXFBConfig fb_config;
07f135
+  CoglBool stereo;
07f135
   CoglBool can_mipmap;
07f135
 } CoglGLXCachedConfig;
07f135
 
07f135
-#define COGL_GLX_N_CACHED_CONFIGS 3
07f135
+#define COGL_GLX_N_CACHED_CONFIGS 6
07f135
 
07f135
 typedef struct _CoglGLXDisplay
07f135
 {
07f135
diff --git a/cogl/winsys/cogl-texture-pixmap-x11-private.h b/cogl/winsys/cogl-texture-pixmap-x11-private.h
bae666
index 948e67b..5da998f 100644
07f135
--- a/cogl/winsys/cogl-texture-pixmap-x11-private.h
07f135
+++ b/cogl/winsys/cogl-texture-pixmap-x11-private.h
bae666
@@ -55,10 +55,27 @@ struct _CoglDamageRectangle
07f135
   unsigned int y2;
07f135
 };
07f135
 
07f135
+/* For stereo, there are a pair of textures, but we want to share most
07f135
+ * other state (the GLXPixmap, visual, etc.) The way we do this is that
07f135
+ * the left-eye texture has all the state (there is in fact, no internal
07f135
+ * difference between the a MONO and a LEFT texture ), and the
07f135
+ * right-eye texture simply points to the left eye texture, with all
07f135
+ * other fields ignored.
07f135
+ */
07f135
+typedef enum
07f135
+{
07f135
+  COGL_TEXTURE_PIXMAP_MONO,
07f135
+  COGL_TEXTURE_PIXMAP_LEFT,
07f135
+  COGL_TEXTURE_PIXMAP_RIGHT
07f135
+} CoglTexturePixmapStereoMode;
07f135
+
07f135
 struct _CoglTexturePixmapX11
07f135
 {
07f135
   CoglTexture _parent;
07f135
 
07f135
+  CoglTexturePixmapStereoMode stereo_mode;
07f135
+  CoglTexturePixmapX11 *left; /* Set only if stereo_mode=RIGHT */
07f135
+
07f135
   Pixmap pixmap;
07f135
   CoglTexture *tex;
07f135
 
bae666
@@ -82,4 +99,5 @@ struct _CoglTexturePixmapX11
07f135
   CoglBool use_winsys_texture;
07f135
 };
07f135
 
07f135
+
07f135
 #endif /* __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H */
07f135
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/winsys/cogl-texture-pixmap-x11.c
bae666
index 6c1edeb..398c357 100644
07f135
--- a/cogl/winsys/cogl-texture-pixmap-x11.c
07f135
+++ b/cogl/winsys/cogl-texture-pixmap-x11.c
bae666
@@ -284,11 +284,12 @@ set_damage_object_internal (CoglContext *ctx,
07f135
                                    tex_pixmap);
07f135
 }
07f135
 
07f135
-CoglTexturePixmapX11 *
07f135
-cogl_texture_pixmap_x11_new (CoglContext *ctxt,
07f135
-                             uint32_t pixmap,
07f135
-                             CoglBool automatic_updates,
07f135
-                             CoglError **error)
07f135
+static CoglTexturePixmapX11 *
07f135
+_cogl_texture_pixmap_x11_new (CoglContext *ctxt,
07f135
+                              uint32_t pixmap,
07f135
+                              CoglBool automatic_updates,
07f135
+                              CoglTexturePixmapStereoMode stereo_mode,
07f135
+                              CoglError **error)
07f135
 {
07f135
   CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1);
07f135
   Display *display = cogl_xlib_renderer_get_display (ctxt->display->renderer);
bae666
@@ -327,6 +328,8 @@ cogl_texture_pixmap_x11_new (CoglContext *ctxt,
07f135
                       &cogl_texture_pixmap_x11_vtable);
07f135
 
07f135
   tex_pixmap->pixmap = pixmap;
07f135
+  tex_pixmap->stereo_mode = stereo_mode;
07f135
+  tex_pixmap->left = NULL;
07f135
   tex_pixmap->image = NULL;
07f135
   tex_pixmap->shm_info.shmid = -1;
07f135
   tex_pixmap->tex = NULL;
bae666
@@ -387,6 +390,59 @@ cogl_texture_pixmap_x11_new (CoglContext *ctxt,
07f135
   return _cogl_texture_pixmap_x11_object_new (tex_pixmap);
07f135
 }
07f135
 
07f135
+CoglTexturePixmapX11 *
07f135
+cogl_texture_pixmap_x11_new (CoglContext *ctxt,
07f135
+                             uint32_t pixmap,
07f135
+                             CoglBool automatic_updates,
07f135
+                             CoglError **error)
07f135
+
07f135
+{
07f135
+  return _cogl_texture_pixmap_x11_new (ctxt, pixmap,
07f135
+                                       automatic_updates, COGL_TEXTURE_PIXMAP_MONO,
07f135
+                                       error);
07f135
+}
07f135
+
07f135
+CoglTexturePixmapX11 *
07f135
+cogl_texture_pixmap_x11_new_left (CoglContext *ctxt,
07f135
+                                  uint32_t pixmap,
07f135
+                                  CoglBool automatic_updates,
07f135
+                                  CoglError **error)
07f135
+{
07f135
+  return _cogl_texture_pixmap_x11_new (ctxt, pixmap,
07f135
+                                       automatic_updates, COGL_TEXTURE_PIXMAP_LEFT,
07f135
+                                       error);
07f135
+}
07f135
+
07f135
+CoglTexturePixmapX11 *
07f135
+cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *tfp_left)
07f135
+{
07f135
+  CoglTexture *texture_left = COGL_TEXTURE (tfp_left);
07f135
+  CoglTexturePixmapX11 *tfp_right;
bae666
+  CoglPixelFormat internal_format;
07f135
+
07f135
+  g_return_val_if_fail (tfp_left->stereo_mode == COGL_TEXTURE_PIXMAP_LEFT, NULL);
07f135
+
07f135
+  tfp_right = g_new0 (CoglTexturePixmapX11, 1);
07f135
+  tfp_right->stereo_mode = COGL_TEXTURE_PIXMAP_RIGHT;
07f135
+  tfp_right->left = cogl_object_ref (tfp_left);
07f135
+
bae666
+  internal_format = (tfp_left->depth >= 32
bae666
+		     ? COGL_PIXEL_FORMAT_RGBA_8888_PRE
bae666
+		     : COGL_PIXEL_FORMAT_RGB_888);
07f135
+  _cogl_texture_init (COGL_TEXTURE (tfp_right),
07f135
+		      texture_left->context,
07f135
+		      texture_left->width,
07f135
+		      texture_left->height,
bae666
+		      internal_format,
bae666
+		      NULL, /* no loader */
07f135
+		      &cogl_texture_pixmap_x11_vtable);
07f135
+
bae666
+  _cogl_texture_set_allocated (COGL_TEXTURE (tfp_right), internal_format,
bae666
+                               texture_left->width, texture_left->height);
07f135
+
07f135
+  return _cogl_texture_pixmap_x11_object_new (tfp_right);
07f135
+}
07f135
+
07f135
 static CoglBool
07f135
 _cogl_texture_pixmap_x11_allocate (CoglTexture *tex,
07f135
                                    CoglError **error)
bae666
@@ -478,6 +534,9 @@ cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap,
07f135
      texture because we can't determine which will be needed until we
07f135
      actually render something */
07f135
 
07f135
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
07f135
+    tex_pixmap = tex_pixmap->left;
07f135
+
07f135
   if (tex_pixmap->winsys)
07f135
     {
07f135
       const CoglWinsysVtable *winsys;
bae666
@@ -492,6 +551,9 @@ cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap,
07f135
 CoglBool
07f135
 cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap)
07f135
 {
07f135
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
07f135
+    tex_pixmap = tex_pixmap->left;
07f135
+
07f135
   return !!tex_pixmap->winsys;
07f135
 }
07f135
 
bae666
@@ -505,6 +567,8 @@ cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *tex_pixmap,
07f135
 
07f135
   _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
07f135
 
07f135
+  g_return_if_fail (tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_RIGHT);
07f135
+
07f135
   damage_base = _cogl_xlib_get_damage_base ();
07f135
   if (damage_base >= 0)
07f135
     set_damage_object_internal (ctxt, tex_pixmap, damage, report_level);
bae666
@@ -717,12 +781,16 @@ static void
07f135
 _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
                                  CoglBool needs_mipmap)
07f135
 {
07f135
+  CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode;
07f135
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
07f135
+    tex_pixmap = tex_pixmap->left;
07f135
+
07f135
   if (tex_pixmap->winsys)
07f135
     {
07f135
       const CoglWinsysVtable *winsys =
07f135
         _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
07f135
 
07f135
-      if (winsys->texture_pixmap_x11_update (tex_pixmap, needs_mipmap))
07f135
+      if (winsys->texture_pixmap_x11_update (tex_pixmap, stereo_mode, needs_mipmap))
07f135
         {
07f135
           _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE);
07f135
           return;
bae666
@@ -739,8 +807,13 @@ _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
 static CoglTexture *
07f135
 _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
07f135
 {
07f135
+  CoglTexturePixmapX11 *original_pixmap = tex_pixmap;
07f135
   CoglTexture *tex;
07f135
   int i;
07f135
+  CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode;
07f135
+
07f135
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
07f135
+    tex_pixmap = tex_pixmap->left;
07f135
 
07f135
   /* We try getting the texture twice, once without flushing the
07f135
      updates and once with. If pre_paint has been called already then
bae666
@@ -757,7 +830,7 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
07f135
         {
07f135
           const CoglWinsysVtable *winsys =
07f135
             _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
07f135
-          tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap);
07f135
+          tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap, stereo_mode);
07f135
         }
07f135
       else
07f135
         tex = tex_pixmap->tex;
bae666
@@ -765,7 +838,7 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
07f135
       if (tex)
07f135
         return tex;
07f135
 
07f135
-      _cogl_texture_pixmap_x11_update (tex_pixmap, FALSE);
07f135
+      _cogl_texture_pixmap_x11_update (original_pixmap, FALSE);
07f135
     }
07f135
 
07f135
   g_assert_not_reached ();
bae666
@@ -1047,6 +1120,16 @@ _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
07f135
 
07f135
   _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
07f135
 
07f135
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
07f135
+    {
07f135
+      cogl_object_unref (tex_pixmap->left);
07f135
+
07f135
+      /* Chain up */
07f135
+      _cogl_texture_free (COGL_TEXTURE (tex_pixmap));
07f135
+
07f135
+      return;
07f135
+    }
07f135
+
07f135
   display = cogl_xlib_renderer_get_display (ctxt->display->renderer);
07f135
 
07f135
   set_damage_object_internal (ctxt, tex_pixmap, 0, 0);
07f135
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.h b/cogl/winsys/cogl-texture-pixmap-x11.h
bae666
index 35155cd..6340bb5 100644
07f135
--- a/cogl/winsys/cogl-texture-pixmap-x11.h
07f135
+++ b/cogl/winsys/cogl-texture-pixmap-x11.h
bae666
@@ -138,6 +138,62 @@ cogl_texture_pixmap_x11_new (CoglContext *context,
07f135
                              CoglError **error);
07f135
 
07f135
 /**
07f135
+ * cogl_texture_pixmap_x11_new_left:
07f135
+ * @context: A #CoglContext
07f135
+ * @pixmap: A X11 pixmap ID
07f135
+ * @automatic_updates: Whether to automatically copy the contents of
07f135
+ * the pixmap to the texture.
07f135
+ * @error: A #CoglError for exceptions
07f135
+ *
07f135
+ * Creates one of a pair of textures to contain the contents of @pixmap,
07f135
+ * which has stereo content. (Different images for the right and left eyes.)
07f135
+ * The left image is drawn using this texture; the right image is drawn
07f135
+ * using a texture created by calling
07f135
+ * cogl_texture_pixmap_x11_new_right() and passing in this texture as an
07f135
+ * argument.
07f135
+ *
07f135
+ * In general, you should not use this function unless you have
07f135
+ * queried the %GLX_STEREO_TREE_EXT attribute of the corresponding
07f135
+ * window using glXQueryDrawable() and determined that the window is
07f135
+ * stereo. Note that this attribute can change over time and
07f135
+ * notification is also provided through events defined in the
07f135
+ * EXT_stereo_tree GLX extension. As long as the system has support for
07f135
+ * stereo content, drawing using the left and right pixmaps will not
07f135
+ * produce an error even if the window doesn't have stereo
07f135
+ * content any more, but drawing with the right pixmap will produce
07f135
+ * undefined output, so you need to listen for these events and
07f135
+ * re-render to avoid race conditions. (Recreating a non-stereo
07f135
+ * pixmap is not necessary, but may save resources.)
07f135
+ *
07f135
+ * Return value: a new #CoglTexturePixmapX11 instance
07f135
+ *
07f135
+ * Since: 1.20
07f135
+ * Stability: Unstable
07f135
+ */
07f135
+CoglTexturePixmapX11 *
07f135
+cogl_texture_pixmap_x11_new_left (CoglContext *context,
07f135
+                                  uint32_t pixmap,
07f135
+                                  CoglBool automatic_updates,
07f135
+                                  CoglError **error);
07f135
+
07f135
+/**
07f135
+ * cogl_texture_pixmap_x11_new_right:
07f135
+ * @left_texture: A #CoglTexturePixmapX11 instance created with
07f135
+ *                cogl_texture_pixmap_x11_new_left().
07f135
+ *
07f135
+ * Creates a texture object that corresponds to the right-eye image
07f135
+ * of a pixmap with stereo content. @left_texture must have been
07f135
+ * created using cogl_texture_pixmap_x11_new_left().
07f135
+ *
07f135
+ * Return value: a new #CoglTexturePixmapX11 instance
07f135
+ *
07f135
+ * Since: 1.20
07f135
+ * Stability: Unstable
07f135
+ */
07f135
+CoglTexturePixmapX11 *
07f135
+cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *left_texture);
07f135
+
07f135
+/**
07f135
  * cogl_texture_pixmap_x11_update_area:
07f135
  * @texture: A #CoglTexturePixmapX11 instance
07f135
  * @x: x coordinate of the area to update
07f135
diff --git a/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/winsys/cogl-winsys-egl-x11.c
bae666
index 26c9606..0e55d41 100644
07f135
--- a/cogl/winsys/cogl-winsys-egl-x11.c
07f135
+++ b/cogl/winsys/cogl-winsys-egl-x11.c
bae666
@@ -784,6 +784,7 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
07f135
 
07f135
 static CoglBool
07f135
 _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
+                                        CoglBool right,
07f135
                                         CoglBool needs_mipmap)
07f135
 {
07f135
   if (needs_mipmap)
bae666
@@ -798,7 +799,8 @@ _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
07f135
 }
07f135
 
07f135
 static CoglTexture *
07f135
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
07f135
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap,
07f135
+                                             CoglBool right)
07f135
 {
07f135
   CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys;
07f135
 
07f135
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
bae666
index bf2b5be..0487b79 100644
07f135
--- a/cogl/winsys/cogl-winsys-glx.c
07f135
+++ b/cogl/winsys/cogl-winsys-glx.c
bae666
@@ -97,16 +97,21 @@ typedef struct _CoglOnscreenGLX
07f135
   CoglBool pending_resize_notify;
07f135
 } CoglOnscreenGLX;
07f135
 
07f135
+typedef struct _CoglPixmapTextureEyeGLX
07f135
+{
07f135
+  CoglTexture *glx_tex;
07f135
+  CoglBool bind_tex_image_queued;
07f135
+  CoglBool pixmap_bound;
07f135
+} CoglPixmapTextureEyeGLX;
07f135
+
07f135
 typedef struct _CoglTexturePixmapGLX
07f135
 {
07f135
   GLXPixmap glx_pixmap;
07f135
   CoglBool has_mipmap_space;
07f135
   CoglBool can_mipmap;
07f135
 
07f135
-  CoglTexture *glx_tex;
07f135
-
07f135
-  CoglBool bind_tex_image_queued;
07f135
-  CoglBool pixmap_bound;
07f135
+  CoglPixmapTextureEyeGLX left;
07f135
+  CoglPixmapTextureEyeGLX right;
07f135
 } CoglTexturePixmapGLX;
07f135
 
07f135
 /* Define a set of arrays containing the functions required from GL
bae666
@@ -2101,6 +2106,7 @@ _cogl_winsys_xlib_get_visual_info (void)
07f135
 static CoglBool
07f135
 get_fbconfig_for_depth (CoglContext *context,
07f135
                         unsigned int depth,
07f135
+                        CoglBool stereo,
07f135
                         GLXFBConfig *fbconfig_ret,
07f135
                         CoglBool *can_mipmap_ret)
07f135
 {
bae666
@@ -2118,11 +2124,12 @@ get_fbconfig_for_depth (CoglContext *context,
07f135
   glx_renderer = context->display->renderer->winsys;
07f135
   glx_display = context->display->winsys;
07f135
 
07f135
-  /* Check if we've already got a cached config for this depth */
07f135
+  /* Check if we've already got a cached config for this depth and stereo */
07f135
   for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++)
07f135
     if (glx_display->glx_cached_configs[i].depth == -1)
07f135
       spare_cache_slot = i;
07f135
-    else if (glx_display->glx_cached_configs[i].depth == depth)
07f135
+    else if (glx_display->glx_cached_configs[i].depth == depth &&
07f135
+             glx_display->glx_cached_configs[i].stereo == stereo)
07f135
       {
07f135
         *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config;
07f135
         *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap;
bae666
@@ -2166,6 +2173,13 @@ get_fbconfig_for_depth (CoglContext *context,
07f135
       if (value != depth && (value - alpha) != depth)
07f135
         continue;
07f135
 
07f135
+      glx_renderer->glXGetFBConfigAttrib (dpy,
07f135
+                                          fbconfigs[i],
07f135
+                                          GLX_STEREO,
07f135
+                                          &value);
07f135
+      if (!!value != !!stereo)
07f135
+        continue;
07f135
+
07f135
       if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4)
07f135
         {
07f135
           glx_renderer->glXGetFBConfigAttrib (dpy,
bae666
@@ -2323,7 +2337,9 @@ try_create_glx_pixmap (CoglContext *context,
07f135
   glx_renderer = renderer->winsys;
07f135
   dpy = xlib_renderer->xdpy;
07f135
 
07f135
-  if (!get_fbconfig_for_depth (context, depth, &fb_config,
07f135
+  if (!get_fbconfig_for_depth (context, depth,
07f135
+                               tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_MONO,
07f135
+                               &fb_config,
07f135
                                &glx_tex_pixmap->can_mipmap))
07f135
     {
07f135
       COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i",
bae666
@@ -2412,10 +2428,13 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
07f135
   glx_tex_pixmap->can_mipmap = FALSE;
07f135
   glx_tex_pixmap->has_mipmap_space = FALSE;
07f135
 
07f135
-  glx_tex_pixmap->glx_tex = NULL;
07f135
+  glx_tex_pixmap->left.glx_tex = NULL;
07f135
+  glx_tex_pixmap->right.glx_tex = NULL;
07f135
 
07f135
-  glx_tex_pixmap->bind_tex_image_queued = TRUE;
07f135
-  glx_tex_pixmap->pixmap_bound = FALSE;
07f135
+  glx_tex_pixmap->left.bind_tex_image_queued = TRUE;
07f135
+  glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
07f135
+  glx_tex_pixmap->left.pixmap_bound = FALSE;
07f135
+  glx_tex_pixmap->right.pixmap_bound = FALSE;
07f135
 
07f135
   tex_pixmap->winsys = glx_tex_pixmap;
07f135
 
bae666
@@ -2442,10 +2461,14 @@ free_glx_pixmap (CoglContext *context,
07f135
   xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
07f135
   glx_renderer = renderer->winsys;
07f135
 
07f135
-  if (glx_tex_pixmap->pixmap_bound)
07f135
+  if (glx_tex_pixmap->left.pixmap_bound)
07f135
     glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
07f135
                                       glx_tex_pixmap->glx_pixmap,
07f135
                                       GLX_FRONT_LEFT_EXT);
07f135
+  if (glx_tex_pixmap->right.pixmap_bound)
07f135
+    glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
07f135
+                                      glx_tex_pixmap->glx_pixmap,
07f135
+                                      GLX_FRONT_RIGHT_EXT);
07f135
 
07f135
   /* FIXME - we need to trap errors and synchronize here because
07f135
    * of ordering issues between the XPixmap destruction and the
bae666
@@ -2470,7 +2493,8 @@ free_glx_pixmap (CoglContext *context,
07f135
   _cogl_xlib_renderer_untrap_errors (renderer, &trap_state);
07f135
 
07f135
   glx_tex_pixmap->glx_pixmap = None;
07f135
-  glx_tex_pixmap->pixmap_bound = FALSE;
07f135
+  glx_tex_pixmap->left.pixmap_bound = FALSE;
07f135
+  glx_tex_pixmap->right.pixmap_bound = FALSE;
07f135
 }
07f135
 
07f135
 static void
bae666
@@ -2485,8 +2509,11 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
07f135
 
07f135
   free_glx_pixmap (COGL_TEXTURE (tex_pixmap)->context, glx_tex_pixmap);
07f135
 
07f135
-  if (glx_tex_pixmap->glx_tex)
07f135
-    cogl_object_unref (glx_tex_pixmap->glx_tex);
07f135
+  if (glx_tex_pixmap->left.glx_tex)
07f135
+    cogl_object_unref (glx_tex_pixmap->left.glx_tex);
07f135
+
07f135
+  if (glx_tex_pixmap->right.glx_tex)
07f135
+    cogl_object_unref (glx_tex_pixmap->right.glx_tex);
07f135
 
07f135
   tex_pixmap->winsys = NULL;
07f135
   g_free (glx_tex_pixmap);
bae666
@@ -2494,13 +2521,27 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
07f135
 
07f135
 static CoglBool
07f135
 _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
+                                        CoglTexturePixmapStereoMode stereo_mode,
07f135
                                         CoglBool needs_mipmap)
07f135
 {
07f135
   CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
07f135
   CoglContext *ctx = COGL_TEXTURE (tex_pixmap)->context;
07f135
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
07f135
+  CoglPixmapTextureEyeGLX *texture_info;
07f135
+  int buffer;
07f135
   CoglGLXRenderer *glx_renderer;
07f135
 
07f135
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
07f135
+    {
07f135
+      texture_info = &glx_tex_pixmap->right;
07f135
+      buffer = GLX_FRONT_RIGHT_EXT;
07f135
+    }
07f135
+  else
07f135
+    {
07f135
+      texture_info = &glx_tex_pixmap->left;
07f135
+      buffer = GLX_FRONT_LEFT_EXT;
07f135
+    }
07f135
+
07f135
   /* If we don't have a GLX pixmap then fallback */
07f135
   if (glx_tex_pixmap->glx_pixmap == None)
07f135
     return FALSE;
bae666
@@ -2508,7 +2549,7 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
   glx_renderer = ctx->display->renderer->winsys;
07f135
 
07f135
   /* Lazily create a texture to hold the pixmap */
07f135
-  if (glx_tex_pixmap->glx_tex == NULL)
07f135
+  if (texture_info->glx_tex == NULL)
07f135
     {
07f135
       CoglPixelFormat texture_format;
07f135
       CoglError *error = NULL;
bae666
@@ -2519,14 +2560,14 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
 
07f135
       if (should_use_rectangle (ctx))
07f135
         {
07f135
-          glx_tex_pixmap->glx_tex = COGL_TEXTURE (
07f135
+          texture_info->glx_tex = COGL_TEXTURE (
07f135
             cogl_texture_rectangle_new_with_size (ctx,
07f135
                                                   tex->width,
bae666
                                                   tex->height));
bae666
 
bae666
           _cogl_texture_set_internal_format (tex, texture_format);
07f135
 
bae666
-          if (cogl_texture_allocate (glx_tex_pixmap->glx_tex, &error))
bae666
+          if (cogl_texture_allocate (texture_info->glx_tex, &error))
07f135
             COGL_NOTE (TEXTURE_PIXMAP, "Created a texture rectangle for %p",
07f135
                        tex_pixmap);
07f135
           else
bae666
@@ -2541,14 +2582,14 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
         }
07f135
       else
07f135
         {
07f135
-          glx_tex_pixmap->glx_tex = COGL_TEXTURE (
07f135
+          texture_info->glx_tex = COGL_TEXTURE (
07f135
             cogl_texture_2d_new_with_size (ctx,
07f135
                                            tex->width,
bae666
                                            tex->height));
bae666
 
bae666
           _cogl_texture_set_internal_format (tex, texture_format);
07f135
 
07f135
-          if (cogl_texture_allocate (glx_tex_pixmap->glx_tex, &error))
07f135
+          if (cogl_texture_allocate (texture_info->glx_tex, &error))
07f135
             COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p",
07f135
                        tex_pixmap);
07f135
           else
bae666
@@ -2586,36 +2627,37 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
                          "updates for %p because creating the GLXPixmap "
07f135
                          "with mipmap support failed", tex_pixmap);
07f135
 
07f135
-              if (glx_tex_pixmap->glx_tex)
07f135
-                cogl_object_unref (glx_tex_pixmap->glx_tex);
07f135
+              if (texture_info->glx_tex)
07f135
+                cogl_object_unref (texture_info->glx_tex);
07f135
               return FALSE;
07f135
             }
07f135
 
07f135
-          glx_tex_pixmap->bind_tex_image_queued = TRUE;
07f135
+          glx_tex_pixmap->left.bind_tex_image_queued = TRUE;
07f135
+          glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
07f135
         }
07f135
     }
07f135
 
07f135
-  if (glx_tex_pixmap->bind_tex_image_queued)
07f135
+  if (texture_info->bind_tex_image_queued)
07f135
     {
07f135
       GLuint gl_handle, gl_target;
07f135
       CoglXlibRenderer *xlib_renderer =
07f135
         _cogl_xlib_renderer_get_data (ctx->display->renderer);
07f135
 
07f135
-      cogl_texture_get_gl_texture (glx_tex_pixmap->glx_tex,
07f135
+      cogl_texture_get_gl_texture (texture_info->glx_tex,
07f135
                                    &gl_handle, &gl_target);
07f135
 
07f135
       COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap);
07f135
 
07f135
       _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE);
07f135
 
07f135
-      if (glx_tex_pixmap->pixmap_bound)
07f135
+      if (texture_info->pixmap_bound)
07f135
         glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
07f135
                                           glx_tex_pixmap->glx_pixmap,
07f135
-                                          GLX_FRONT_LEFT_EXT);
07f135
+                                          buffer);
07f135
 
07f135
       glx_renderer->glXBindTexImage (xlib_renderer->xdpy,
07f135
                                      glx_tex_pixmap->glx_pixmap,
07f135
-                                     GLX_FRONT_LEFT_EXT,
07f135
+                                     buffer,
07f135
                                      NULL);
07f135
 
07f135
       /* According to the recommended usage in the spec for
bae666
@@ -2628,10 +2670,10 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
07f135
        * on Mesa and NVidia drivers and it is also what Compiz does so
07f135
        * it is probably ok */
07f135
 
07f135
-      glx_tex_pixmap->bind_tex_image_queued = FALSE;
07f135
-      glx_tex_pixmap->pixmap_bound = TRUE;
07f135
+      texture_info->bind_tex_image_queued = FALSE;
07f135
+      texture_info->pixmap_bound = TRUE;
07f135
 
07f135
-      _cogl_texture_2d_externally_modified (glx_tex_pixmap->glx_tex);
07f135
+      _cogl_texture_2d_externally_modified (texture_info->glx_tex);
07f135
     }
07f135
 
07f135
   return TRUE;
bae666
@@ -2642,15 +2684,20 @@ _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
07f135
 {
07f135
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
07f135
 
07f135
-  glx_tex_pixmap->bind_tex_image_queued = TRUE;
07f135
+  glx_tex_pixmap->left.bind_tex_image_queued = TRUE;
07f135
+  glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
07f135
 }
07f135
 
07f135
 static CoglTexture *
07f135
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
07f135
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap,
07f135
+                                             CoglTexturePixmapStereoMode stereo_mode)
07f135
 {
07f135
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
07f135
 
07f135
-  return glx_tex_pixmap->glx_tex;
07f135
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
07f135
+    return glx_tex_pixmap->right.glx_tex;
07f135
+  else
07f135
+    return glx_tex_pixmap->left.glx_tex;
07f135
 }
07f135
 
bae666
 static CoglWinsysVtable _cogl_winsys_vtable =
07f135
diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h
bae666
index d6ff165..2c9cc98 100644
07f135
--- a/cogl/winsys/cogl-winsys-private.h
07f135
+++ b/cogl/winsys/cogl-winsys-private.h
bae666
@@ -166,13 +166,15 @@ typedef struct _CoglWinsysVtable
07f135
 
07f135
   CoglBool
07f135
   (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap,
07f135
+                                CoglTexturePixmapStereoMode stereo_mode,
07f135
                                 CoglBool needs_mipmap);
07f135
 
07f135
   void
07f135
   (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap);
07f135
 
07f135
   CoglTexture *
07f135
-  (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap);
07f135
+  (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap,
07f135
+                                     CoglTexturePixmapStereoMode stereo_mode);
07f135
 #endif
07f135
 
07f135
   void
07f135
-- 
bae666
2.1.0
07f135