[cogl/wip/quadbuffer-stereo: 11/13] CoglTexturePixmapX11: add support for stereo content



commit d0c2e439db45e08011f87b246cf7910fd35520ea
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Sat Apr 26 16:38:58 2014 -0400

    CoglTexturePixmapX11: add support for stereo content
    
    Add cogl_texture_pixmap_x11_new_stereo() to create a a texture
    pixmap using a stereo visual, which can be used to render pixmaps for
    windows with stereo content. The actual rendering is done by using
    cogl_texture_pixmap_x11_create_right_texture(), which returns a
    separate texture that renders with the right image.

 cogl/Makefile.am                              |    1 +
 cogl/cogl-glx-display-private.h               |    3 +-
 cogl/winsys/cogl-texture-pixmap-x11-private.h |   43 ++++
 cogl/winsys/cogl-texture-pixmap-x11-right.c   |  324 +++++++++++++++++++++++++
 cogl/winsys/cogl-texture-pixmap-x11.c         |  122 +++++++---
 cogl/winsys/cogl-texture-pixmap-x11.h         |   59 +++++-
 cogl/winsys/cogl-winsys-egl-x11.c             |    4 +-
 cogl/winsys/cogl-winsys-glx.c                 |  100 +++++---
 cogl/winsys/cogl-winsys-private.h             |    4 +-
 9 files changed, 593 insertions(+), 67 deletions(-)
---
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index 62d3762..5e30ea8 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -442,6 +442,7 @@ cogl_sources_c += \
        $(srcdir)/cogl-xlib.c \
        $(srcdir)/cogl-xlib-private.h \
        $(srcdir)/winsys/cogl-texture-pixmap-x11.c \
+       $(srcdir)/winsys/cogl-texture-pixmap-x11-right.c \
        $(srcdir)/winsys/cogl-texture-pixmap-x11-private.h
 endif
 if SUPPORT_GLX
diff --git a/cogl/cogl-glx-display-private.h b/cogl/cogl-glx-display-private.h
index 20b7e67..133c118 100644
--- a/cogl/cogl-glx-display-private.h
+++ b/cogl/cogl-glx-display-private.h
@@ -39,10 +39,11 @@ typedef struct _CoglGLXCachedConfig
   int depth;
   CoglBool found;
   GLXFBConfig fb_config;
+  CoglBool stereo;
   CoglBool can_mipmap;
 } CoglGLXCachedConfig;
 
-#define COGL_GLX_N_CACHED_CONFIGS 3
+#define COGL_GLX_N_CACHED_CONFIGS 6
 
 typedef struct _CoglGLXDisplay
 {
diff --git a/cogl/winsys/cogl-texture-pixmap-x11-private.h b/cogl/winsys/cogl-texture-pixmap-x11-private.h
index 948e67b..3b889da 100644
--- a/cogl/winsys/cogl-texture-pixmap-x11-private.h
+++ b/cogl/winsys/cogl-texture-pixmap-x11-private.h
@@ -46,6 +46,7 @@
 #include "cogl-texture-pixmap-x11.h"
 
 typedef struct _CoglDamageRectangle CoglDamageRectangle;
+typedef struct _CoglTexturePixmapX11Right CoglTexturePixmapX11Right;
 
 struct _CoglDamageRectangle
 {
@@ -59,6 +60,8 @@ struct _CoglTexturePixmapX11
 {
   CoglTexture _parent;
 
+  CoglTexture *right;
+
   Pixmap pixmap;
   CoglTexture *tex;
 
@@ -76,10 +79,50 @@ struct _CoglTexturePixmapX11
 
   void *winsys;
 
+  CoglBool stereo;
+
   /* During the pre_paint method, this will be set to TRUE if we
      should use the winsys texture, otherwise we will use the regular
      texture */
   CoglBool use_winsys_texture;
 };
 
+struct _CoglTexturePixmapX11Right
+{
+  CoglTexture _parent;
+
+  CoglTexturePixmapX11 *left;
+};
+
+void
+_cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                 CoglBool right,
+                                 CoglBool needs_mipmap);
+
+CoglTexture *
+_cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap,
+                                      CoglBool right);
+
+void
+_cogl_texture_pixmap_x11_do_foreach_sub_texture_in_region
+                                  (CoglTexturePixmapX11     *tex_pixmap,
+                                   CoglTexture              *child_tex,
+                                   float                     virtual_tx_1,
+                                   float                     virtual_ty_1,
+                                   float                     virtual_tx_2,
+                                   float                     virtual_ty_2,
+                                   CoglMetaTextureCallback   callback,
+                                   void                     *user_data);
+
+#define COGL_TEXTURE_PIXMAP_X11_RIGHT(X) ((CoglTexturePixmapX11Right *)X)
+
+GType cogl_texture_pixmap_x11_right_get_gtype (void);
+
+CoglTexture *
+_cogl_texture_pixmap_x11_right_new (CoglTexturePixmapX11 *left);
+
+CoglBool
+cogl_is_texture_pixmap_x11_right (void *object);
+
+
 #endif /* __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H */
diff --git a/cogl/winsys/cogl-texture-pixmap-x11-right.c b/cogl/winsys/cogl-texture-pixmap-x11-right.c
new file mode 100644
index 0000000..bd7112f
--- /dev/null
+++ b/cogl/winsys/cogl-texture-pixmap-x11-right.c
@@ -0,0 +1,324 @@
+/*
+ * Cogl
+ *
+ * A Low Level GPU Graphics and Utilities API
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ *
+ * Authors:
+ *  Neil Roberts   <neil linux intel com>
+ *  Johan Bilien   <johan bilien nokia com>
+ *  Robert Bragg   <robert linux intel com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cogl-debug.h"
+#include "cogl-util.h"
+#include "cogl-texture-pixmap-x11.h"
+#include "cogl-texture-pixmap-x11-private.h"
+#include "cogl-private.h"
+#include "cogl-texture-gl-private.h"
+#include "cogl-error-private.h"
+#include "cogl-gtype-private.h"
+
+static void _cogl_texture_pixmap_x11_right_free (CoglTexturePixmapX11Right *tex_right);
+
+COGL_TEXTURE_DEFINE (TexturePixmapX11Right, texture_pixmap_x11_right);
+COGL_GTYPE_DEFINE_CLASS (TexturePixmapX11Right, texture_pixmap_x11_right);
+
+static const CoglTextureVtable cogl_texture_pixmap_x11_right_vtable;
+
+CoglTexture *
+_cogl_texture_pixmap_x11_right_new (CoglTexturePixmapX11 *tfp_left)
+{
+  CoglTexture *texture_left = COGL_TEXTURE (tfp_left);
+  CoglTexturePixmapX11Right *tex_right = g_new (CoglTexturePixmapX11Right, 1);
+  CoglPixelFormat internal_format;
+
+  tex_right->left = cogl_object_ref (tfp_left);
+
+  internal_format = (tfp_left->depth >= 32
+                     ? COGL_PIXEL_FORMAT_RGBA_8888_PRE
+                     : COGL_PIXEL_FORMAT_RGB_888);
+  _cogl_texture_init (COGL_TEXTURE (tex_right),
+                     texture_left->context,
+                     texture_left->width,
+                     texture_left->height,
+                      internal_format,
+                      NULL, /* no loader */
+                      &cogl_texture_pixmap_x11_right_vtable);
+
+  return (CoglTexture *)_cogl_texture_pixmap_x11_right_object_new (tex_right);
+}
+
+static CoglBool
+_cogl_texture_pixmap_x11_right_allocate (CoglTexture *tex,
+                                         CoglError **error)
+{
+  return TRUE;
+}
+
+static CoglBool
+_cogl_texture_pixmap_x11_right_set_region (CoglTexture *tex,
+                                           int src_x,
+                                           int src_y,
+                                           int dst_x,
+                                           int dst_y,
+                                           int dst_width,
+                                           int dst_height,
+                                           int level,
+                                           CoglBitmap *bmp,
+                                           CoglError **error)
+{
+  /* This doesn't make much sense for texture from pixmap so it's not
+     supported */
+  _cogl_set_error (error,
+                   COGL_SYSTEM_ERROR,
+                   COGL_SYSTEM_ERROR_UNSUPPORTED,
+                   "Explicitly setting a region of a TFP texture unsupported");
+  return FALSE;
+}
+
+static CoglBool
+_cogl_texture_pixmap_x11_right_get_data (CoglTexture *tex,
+                                         CoglPixelFormat format,
+                                         int rowstride,
+                                         uint8_t *data)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  return cogl_texture_get_data (child_tex, format, rowstride, data);
+}
+
+static void
+_cogl_texture_pixmap_x11_right_foreach_sub_texture_in_region
+                                  (CoglTexture              *tex,
+                                   float                     virtual_tx_1,
+                                   float                     virtual_ty_1,
+                                   float                     virtual_tx_2,
+                                   float                     virtual_ty_2,
+                                   CoglMetaTextureCallback   callback,
+                                   void                     *user_data)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  _cogl_texture_pixmap_x11_do_foreach_sub_texture_in_region
+                                                 (tex_right->left,
+                                                  child_tex,
+                                                  virtual_tx_1, virtual_ty_1,
+                                                  virtual_tx_2, virtual_ty_2,
+                                                  callback, user_data);
+}
+
+static int
+_cogl_texture_pixmap_x11_right_get_max_waste (CoglTexture *tex)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  return cogl_texture_get_max_waste (child_tex);
+}
+
+static CoglBool
+_cogl_texture_pixmap_x11_right_is_sliced (CoglTexture *tex)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  return cogl_texture_is_sliced (child_tex);
+}
+
+static CoglBool
+_cogl_texture_pixmap_x11_right_can_hardware_repeat (CoglTexture *tex)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  return _cogl_texture_can_hardware_repeat (child_tex);
+}
+
+static void
+_cogl_texture_pixmap_x11_right_transform_coords_to_gl (CoglTexture *tex,
+                                                       float       *s,
+                                                       float       *t)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  _cogl_texture_transform_coords_to_gl (child_tex, s, t);
+}
+
+static CoglTransformResult
+_cogl_texture_pixmap_x11_right_transform_quad_coords_to_gl (CoglTexture *tex,
+                                                            float       *coords)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  return _cogl_texture_transform_quad_coords_to_gl (child_tex, coords);
+}
+
+static CoglBool
+_cogl_texture_pixmap_x11_right_get_gl_texture (CoglTexture *tex,
+                                               GLuint      *out_gl_handle,
+                                               GLenum      *out_gl_target)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  return cogl_texture_get_gl_texture (child_tex,
+                                      out_gl_handle,
+                                      out_gl_target);
+}
+
+static void
+_cogl_texture_pixmap_x11_right_gl_flush_legacy_texobj_filters (CoglTexture *tex,
+                                                         GLenum min_filter,
+                                                         GLenum mag_filter)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  _cogl_texture_gl_flush_legacy_texobj_filters (child_tex,
+                                                min_filter, mag_filter);
+}
+
+static void
+_cogl_texture_pixmap_x11_right_pre_paint (CoglTexture *tex,
+                                    CoglTexturePrePaintFlags flags)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex;
+
+  _cogl_texture_pixmap_x11_update (tex_right->left,
+                                   TRUE,
+                                   !!(flags & COGL_TEXTURE_NEEDS_MIPMAP));
+
+  child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  _cogl_texture_pre_paint (child_tex, flags);
+}
+
+static void
+_cogl_texture_pixmap_x11_right_ensure_non_quad_rendering (CoglTexture *tex)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  _cogl_texture_ensure_non_quad_rendering (child_tex);
+}
+
+static void
+_cogl_texture_pixmap_x11_right_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex,
+                                                                  GLenum wrap_mode_s,
+                                                                  GLenum wrap_mode_t,
+                                                                  GLenum wrap_mode_p)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  _cogl_texture_gl_flush_legacy_texobj_wrap_modes (child_tex,
+                                                   wrap_mode_s,
+                                                   wrap_mode_t,
+                                                   wrap_mode_p);
+}
+
+static CoglPixelFormat
+_cogl_texture_pixmap_x11_right_get_format (CoglTexture *tex)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  return _cogl_texture_get_format (child_tex);
+}
+
+static GLenum
+_cogl_texture_pixmap_x11_right_get_gl_format (CoglTexture *tex)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  return _cogl_texture_gl_get_format (child_tex);
+}
+
+static CoglTextureType
+_cogl_texture_pixmap_x11_right_get_type (CoglTexture *tex)
+{
+  CoglTexturePixmapX11Right *tex_right = COGL_TEXTURE_PIXMAP_X11_RIGHT (tex);
+  CoglTexture *child_tex;
+
+  child_tex = _cogl_texture_pixmap_x11_get_texture (tex_right->left, TRUE);
+
+  /* Forward on to the child texture */
+  return _cogl_texture_get_type (child_tex);
+}
+
+static void
+_cogl_texture_pixmap_x11_right_free (CoglTexturePixmapX11Right *tex_right)
+{
+  tex_right->left->right = NULL;
+  cogl_object_unref (tex_right->left);
+
+  /* Chain up */
+  _cogl_texture_free (COGL_TEXTURE (tex_right));
+}
+
+static const CoglTextureVtable
+cogl_texture_pixmap_x11_right_vtable =
+  {
+    FALSE, /* not primitive */
+    _cogl_texture_pixmap_x11_right_allocate,
+    _cogl_texture_pixmap_x11_right_set_region,
+    _cogl_texture_pixmap_x11_right_get_data,
+    _cogl_texture_pixmap_x11_right_foreach_sub_texture_in_region,
+    _cogl_texture_pixmap_x11_right_get_max_waste,
+    _cogl_texture_pixmap_x11_right_is_sliced,
+    _cogl_texture_pixmap_x11_right_can_hardware_repeat,
+    _cogl_texture_pixmap_x11_right_transform_coords_to_gl,
+    _cogl_texture_pixmap_x11_right_transform_quad_coords_to_gl,
+    _cogl_texture_pixmap_x11_right_get_gl_texture,
+    _cogl_texture_pixmap_x11_right_gl_flush_legacy_texobj_filters,
+    _cogl_texture_pixmap_x11_right_pre_paint,
+    _cogl_texture_pixmap_x11_right_ensure_non_quad_rendering,
+    _cogl_texture_pixmap_x11_right_gl_flush_legacy_texobj_wrap_modes,
+    _cogl_texture_pixmap_x11_right_get_format,
+    _cogl_texture_pixmap_x11_right_get_gl_format,
+    _cogl_texture_pixmap_x11_right_get_type,
+    NULL, /* is_foreign */
+    NULL /* set_auto_mipmap */
+  };
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/winsys/cogl-texture-pixmap-x11.c
index 6c1edeb..7eee11d 100644
--- a/cogl/winsys/cogl-texture-pixmap-x11.c
+++ b/cogl/winsys/cogl-texture-pixmap-x11.c
@@ -284,11 +284,12 @@ set_damage_object_internal (CoglContext *ctx,
                                    tex_pixmap);
 }
 
-CoglTexturePixmapX11 *
-cogl_texture_pixmap_x11_new (CoglContext *ctxt,
-                             uint32_t pixmap,
-                             CoglBool automatic_updates,
-                             CoglError **error)
+static CoglTexturePixmapX11 *
+_cogl_texture_pixmap_x11_new (CoglContext *ctxt,
+                              uint32_t pixmap,
+                              CoglBool automatic_updates,
+                              CoglBool stereo,
+                              CoglError **error)
 {
   CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1);
   Display *display = cogl_xlib_renderer_get_display (ctxt->display->renderer);
@@ -327,6 +328,8 @@ cogl_texture_pixmap_x11_new (CoglContext *ctxt,
                       &cogl_texture_pixmap_x11_vtable);
 
   tex_pixmap->pixmap = pixmap;
+  tex_pixmap->right = NULL;
+  tex_pixmap->stereo = stereo;
   tex_pixmap->image = NULL;
   tex_pixmap->shm_info.shmid = -1;
   tex_pixmap->tex = NULL;
@@ -387,6 +390,29 @@ cogl_texture_pixmap_x11_new (CoglContext *ctxt,
   return _cogl_texture_pixmap_x11_object_new (tex_pixmap);
 }
 
+CoglTexturePixmapX11 *
+cogl_texture_pixmap_x11_new (CoglContext *ctxt,
+                             uint32_t pixmap,
+                             CoglBool automatic_updates,
+                             CoglError **error)
+
+{
+  return _cogl_texture_pixmap_x11_new (ctxt, pixmap,
+                                       automatic_updates, FALSE,
+                                       error);
+}
+
+CoglTexturePixmapX11 *
+cogl_texture_pixmap_x11_new_stereo (CoglContext *ctxt,
+                                    uint32_t pixmap,
+                                    CoglBool automatic_updates,
+                                    CoglError **error)
+{
+  return _cogl_texture_pixmap_x11_new (ctxt, pixmap,
+                                       automatic_updates, TRUE,
+                                       error);
+}
+
 static CoglBool
 _cogl_texture_pixmap_x11_allocate (CoglTexture *tex,
                                    CoglError **error)
@@ -510,6 +536,19 @@ cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *tex_pixmap,
     set_damage_object_internal (ctxt, tex_pixmap, damage, report_level);
 }
 
+CoglTexture *
+cogl_texture_pixmap_x11_create_right_texture (CoglTexturePixmapX11 *tex_pixmap)
+{
+  g_return_val_if_fail (tex_pixmap->stereo, NULL);
+
+  if (tex_pixmap->right)
+    return cogl_object_ref (tex_pixmap->right);
+
+  tex_pixmap->right = _cogl_texture_pixmap_x11_right_new (tex_pixmap);
+
+  return tex_pixmap->right;
+}
+
 static CoglTexture *
 create_fallback_texture (CoglContext *ctx,
                          int width,
@@ -713,8 +752,9 @@ _cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixma
     }
 }
 
-static void
+void
 _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                 CoglBool right,
                                  CoglBool needs_mipmap)
 {
   if (tex_pixmap->winsys)
@@ -722,7 +762,7 @@ _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
       const CoglWinsysVtable *winsys =
         _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
 
-      if (winsys->texture_pixmap_x11_update (tex_pixmap, needs_mipmap))
+      if (winsys->texture_pixmap_x11_update (tex_pixmap, right, needs_mipmap))
         {
           _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE);
           return;
@@ -736,8 +776,9 @@ _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
   _cogl_texture_pixmap_x11_update_image_texture (tex_pixmap);
 }
 
-static CoglTexture *
-_cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+CoglTexture *
+_cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap,
+                                      CoglBool right)
 {
   CoglTexture *tex;
   int i;
@@ -757,7 +798,7 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
         {
           const CoglWinsysVtable *winsys =
             _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
-          tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap);
+          tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap, right);
         }
       else
         tex = tex_pixmap->tex;
@@ -765,7 +806,7 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
       if (tex)
         return tex;
 
-      _cogl_texture_pixmap_x11_update (tex_pixmap, FALSE);
+      _cogl_texture_pixmap_x11_update (tex_pixmap, right, FALSE);
     }
 
   g_assert_not_reached ();
@@ -801,7 +842,7 @@ _cogl_texture_pixmap_x11_get_data (CoglTexture *tex,
                                    uint8_t *data)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   return cogl_texture_get_data (child_tex, format, rowstride, data);
@@ -834,9 +875,10 @@ normalize_coords_wrapper_cb (CoglTexture *child_texture,
                   data->user_data);
 }
 
-static void
-_cogl_texture_pixmap_x11_foreach_sub_texture_in_region
-                                  (CoglTexture              *tex,
+void
+_cogl_texture_pixmap_x11_do_foreach_sub_texture_in_region
+                                  (CoglTexturePixmapX11     *tex_pixmap,
+                                   CoglTexture              *child_tex,
                                    float                     virtual_tx_1,
                                    float                     virtual_ty_1,
                                    float                     virtual_tx_2,
@@ -844,8 +886,7 @@ _cogl_texture_pixmap_x11_foreach_sub_texture_in_region
                                    CoglMetaTextureCallback   callback,
                                    void                     *user_data)
 {
-  CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
 
   /* Forward on to the child texture */
 
@@ -891,11 +932,31 @@ _cogl_texture_pixmap_x11_foreach_sub_texture_in_region
                                          user_data);
 }
 
+static void
+_cogl_texture_pixmap_x11_foreach_sub_texture_in_region
+                                  (CoglTexture              *tex,
+                                   float                     virtual_tx_1,
+                                   float                     virtual_ty_1,
+                                   float                     virtual_tx_2,
+                                   float                     virtual_ty_2,
+                                   CoglMetaTextureCallback   callback,
+                                   void                     *user_data)
+{
+  CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
+
+  _cogl_texture_pixmap_x11_do_foreach_sub_texture_in_region
+                                                 (tex_pixmap, child_tex,
+                                                  virtual_tx_1, virtual_ty_1,
+                                                  virtual_tx_2, virtual_ty_2,
+                                                  callback, user_data);
+}
+
 static int
 _cogl_texture_pixmap_x11_get_max_waste (CoglTexture *tex)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   return cogl_texture_get_max_waste (child_tex);
 }
@@ -904,7 +965,7 @@ static CoglBool
 _cogl_texture_pixmap_x11_is_sliced (CoglTexture *tex)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   return cogl_texture_is_sliced (child_tex);
 }
@@ -913,7 +974,7 @@ static CoglBool
 _cogl_texture_pixmap_x11_can_hardware_repeat (CoglTexture *tex)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   return _cogl_texture_can_hardware_repeat (child_tex);
 }
@@ -924,7 +985,7 @@ _cogl_texture_pixmap_x11_transform_coords_to_gl (CoglTexture *tex,
                                                  float       *t)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   _cogl_texture_transform_coords_to_gl (child_tex, s, t);
@@ -935,7 +996,7 @@ _cogl_texture_pixmap_x11_transform_quad_coords_to_gl (CoglTexture *tex,
                                                       float       *coords)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   return _cogl_texture_transform_quad_coords_to_gl (child_tex, coords);
@@ -947,7 +1008,7 @@ _cogl_texture_pixmap_x11_get_gl_texture (CoglTexture *tex,
                                          GLenum      *out_gl_target)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   return cogl_texture_get_gl_texture (child_tex,
@@ -961,7 +1022,7 @@ _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_filters (CoglTexture *tex,
                                                          GLenum mag_filter)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   _cogl_texture_gl_flush_legacy_texobj_filters (child_tex,
@@ -976,9 +1037,10 @@ _cogl_texture_pixmap_x11_pre_paint (CoglTexture *tex,
   CoglTexture *child_tex;
 
   _cogl_texture_pixmap_x11_update (tex_pixmap,
+                                   FALSE,
                                    !!(flags & COGL_TEXTURE_NEEDS_MIPMAP));
 
-  child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   _cogl_texture_pre_paint (child_tex, flags);
 }
@@ -987,7 +1049,7 @@ static void
 _cogl_texture_pixmap_x11_ensure_non_quad_rendering (CoglTexture *tex)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   _cogl_texture_ensure_non_quad_rendering (child_tex);
@@ -1000,7 +1062,7 @@ _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex,
                                                             GLenum wrap_mode_p)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   _cogl_texture_gl_flush_legacy_texobj_wrap_modes (child_tex,
@@ -1013,7 +1075,7 @@ static CoglPixelFormat
 _cogl_texture_pixmap_x11_get_format (CoglTexture *tex)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   return _cogl_texture_get_format (child_tex);
@@ -1023,7 +1085,7 @@ static GLenum
 _cogl_texture_pixmap_x11_get_gl_format (CoglTexture *tex)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
-  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   return _cogl_texture_gl_get_format (child_tex);
 }
@@ -1034,7 +1096,7 @@ _cogl_texture_pixmap_x11_get_type (CoglTexture *tex)
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
   CoglTexture *child_tex;
 
-  child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+  child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap, FALSE);
 
   /* Forward on to the child texture */
   return _cogl_texture_get_type (child_tex);
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.h b/cogl/winsys/cogl-texture-pixmap-x11.h
index 35155cd..e74ca3f 100644
--- a/cogl/winsys/cogl-texture-pixmap-x11.h
+++ b/cogl/winsys/cogl-texture-pixmap-x11.h
@@ -138,6 +138,44 @@ cogl_texture_pixmap_x11_new (CoglContext *context,
                              CoglError **error);
 
 /**
+ * cogl_texture_pixmap_x11_new_stereo:
+ * @context: A #CoglContext
+ * @pixmap: A X11 pixmap ID
+ * @automatic_updates: Whether to automatically copy the contents of
+ * the pixmap to the texture.
+ * @error: A #CoglError for exceptions
+ *
+ * Creates a texture that contains the contents of @pixmap, which has
+ * stereo content. (Different images for the right and left eyes.)
+ * The left image is accessed by using the texture directly; the
+ * right image is accessed by using the texture returned by
+ * cogl_texture_pixmap_x11_create_right_texture().
+ *
+ * In general, you should not use this function unless you have
+ * queried the %GLX_STEREO_TREE_EXT attribute of the corresponding
+ * window using glXQueryDrawable() and determined that the window is
+ * stereo. Note that this attribute can change over time and
+ * notification is also provided through events defined in the
+ * EXT_stereo_tree GLX extension. As long as the system has support for
+ * stereo content, drawing using the stereo pixmap will not
+ * produce an error even if the window doesn't have stereo
+ * content any more, but drawing with the right pixmap will produce
+ * undefined output, so you need to listen for these events and
+ * re-render to avoid race conditions. (Recreating a non-stereo
+ * pixmap is not necessary, but may save resources.)
+ *
+ * Return value: a new #CoglTexturePixmapX11 instance
+ *
+ * Since: 1.20
+ * Stability: Unstable
+ */
+CoglTexturePixmapX11 *
+cogl_texture_pixmap_x11_new_stereo (CoglContext *context,
+                                    uint32_t pixmap,
+                                    CoglBool automatic_updates,
+                                    CoglError **error);
+
+/**
  * cogl_texture_pixmap_x11_update_area:
  * @texture: A #CoglTexturePixmapX11 instance
  * @x: x coordinate of the area to update
@@ -204,6 +242,25 @@ cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *texture,
                                                                   report_level);
 
 /**
+ * cogl_texture_pixmap_x11_create_right_texture:
+ * @texture: A #CoglTexturePixmapX11 instance created with
+ *           cogl_texture_pixmap_x1_new_stereo().
+ *
+ * Creates a texture object that corresponds to the right-eye image of a stereo
+ * #CoglTexturePixmapX11. If such an object already exists, a new reference
+ * to the existing object will be returned. @texture must be created
+ * using cogl_texture_pixmap_x1_new_stereo().
+ *
+ * Return value: a newly created #ClutterTexture or a reference to
+ *  a previously created #ClutterTexture.
+ *
+ * Since: 1.20
+ * Stability: Unstable
+ */
+CoglTexture *
+cogl_texture_pixmap_x11_create_right_texture (CoglTexturePixmapX11 *texture);
+
+/**
  * cogl_is_texture_pixmap_x11:
  * @object: A pointer to a #CoglObject
  *
@@ -212,7 +269,7 @@ cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *texture,
  * Return value: %TRUE if the object is a #CoglTexturePixmapX11, and
  *   %FALSE otherwise
  *
- * Since: 1.4
+* Since: 1.4
  * Stability: Unstable
  */
 CoglBool
diff --git a/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/winsys/cogl-winsys-egl-x11.c
index 26c9606..0e55d41 100644
--- a/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/winsys/cogl-winsys-egl-x11.c
@@ -784,6 +784,7 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
 
 static CoglBool
 _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                        CoglBool right,
                                         CoglBool needs_mipmap)
 {
   if (needs_mipmap)
@@ -798,7 +799,8 @@ _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
 }
 
 static CoglTexture *
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap,
+                                             CoglBool right)
 {
   CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys;
 
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
index bf2b5be..22ff11d 100644
--- a/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/winsys/cogl-winsys-glx.c
@@ -97,16 +97,21 @@ typedef struct _CoglOnscreenGLX
   CoglBool pending_resize_notify;
 } CoglOnscreenGLX;
 
+typedef struct _CoglPixmapTextureInfoGLX
+{
+  CoglTexture *glx_tex;
+  CoglBool bind_tex_image_queued;
+  CoglBool pixmap_bound;
+} CoglPixmapTextureInfoGLX;
+
 typedef struct _CoglTexturePixmapGLX
 {
   GLXPixmap glx_pixmap;
   CoglBool has_mipmap_space;
   CoglBool can_mipmap;
 
-  CoglTexture *glx_tex;
-
-  CoglBool bind_tex_image_queued;
-  CoglBool pixmap_bound;
+  CoglPixmapTextureInfoGLX left;
+  CoglPixmapTextureInfoGLX right;
 } CoglTexturePixmapGLX;
 
 /* Define a set of arrays containing the functions required from GL
@@ -2101,6 +2106,7 @@ _cogl_winsys_xlib_get_visual_info (void)
 static CoglBool
 get_fbconfig_for_depth (CoglContext *context,
                         unsigned int depth,
+                        CoglBool stereo,
                         GLXFBConfig *fbconfig_ret,
                         CoglBool *can_mipmap_ret)
 {
@@ -2118,11 +2124,12 @@ get_fbconfig_for_depth (CoglContext *context,
   glx_renderer = context->display->renderer->winsys;
   glx_display = context->display->winsys;
 
-  /* Check if we've already got a cached config for this depth */
+  /* Check if we've already got a cached config for this depth and stereo */
   for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++)
     if (glx_display->glx_cached_configs[i].depth == -1)
       spare_cache_slot = i;
-    else if (glx_display->glx_cached_configs[i].depth == depth)
+    else if (glx_display->glx_cached_configs[i].depth == depth &&
+             glx_display->glx_cached_configs[i].stereo == stereo)
       {
         *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config;
         *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap;
@@ -2166,6 +2173,13 @@ get_fbconfig_for_depth (CoglContext *context,
       if (value != depth && (value - alpha) != depth)
         continue;
 
+      glx_renderer->glXGetFBConfigAttrib (dpy,
+                                          fbconfigs[i],
+                                          GLX_STEREO,
+                                          &value);
+      if (!!value != !!stereo)
+        continue;
+
       if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4)
         {
           glx_renderer->glXGetFBConfigAttrib (dpy,
@@ -2323,7 +2337,7 @@ try_create_glx_pixmap (CoglContext *context,
   glx_renderer = renderer->winsys;
   dpy = xlib_renderer->xdpy;
 
-  if (!get_fbconfig_for_depth (context, depth, &fb_config,
+  if (!get_fbconfig_for_depth (context, depth, tex_pixmap->stereo, &fb_config,
                                &glx_tex_pixmap->can_mipmap))
     {
       COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i",
@@ -2412,10 +2426,13 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
   glx_tex_pixmap->can_mipmap = FALSE;
   glx_tex_pixmap->has_mipmap_space = FALSE;
 
-  glx_tex_pixmap->glx_tex = NULL;
+  glx_tex_pixmap->left.glx_tex = NULL;
+  glx_tex_pixmap->right.glx_tex = NULL;
 
-  glx_tex_pixmap->bind_tex_image_queued = TRUE;
-  glx_tex_pixmap->pixmap_bound = FALSE;
+  glx_tex_pixmap->left.bind_tex_image_queued = TRUE;
+  glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
+  glx_tex_pixmap->left.pixmap_bound = FALSE;
+  glx_tex_pixmap->right.pixmap_bound = FALSE;
 
   tex_pixmap->winsys = glx_tex_pixmap;
 
@@ -2442,10 +2459,14 @@ free_glx_pixmap (CoglContext *context,
   xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
   glx_renderer = renderer->winsys;
 
-  if (glx_tex_pixmap->pixmap_bound)
+  if (glx_tex_pixmap->left.pixmap_bound)
     glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
                                       glx_tex_pixmap->glx_pixmap,
                                       GLX_FRONT_LEFT_EXT);
+  if (glx_tex_pixmap->right.pixmap_bound)
+    glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
+                                      glx_tex_pixmap->glx_pixmap,
+                                      GLX_FRONT_RIGHT_EXT);
 
   /* FIXME - we need to trap errors and synchronize here because
    * of ordering issues between the XPixmap destruction and the
@@ -2470,7 +2491,8 @@ free_glx_pixmap (CoglContext *context,
   _cogl_xlib_renderer_untrap_errors (renderer, &trap_state);
 
   glx_tex_pixmap->glx_pixmap = None;
-  glx_tex_pixmap->pixmap_bound = FALSE;
+  glx_tex_pixmap->left.pixmap_bound = FALSE;
+  glx_tex_pixmap->right.pixmap_bound = FALSE;
 }
 
 static void
@@ -2485,8 +2507,11 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
 
   free_glx_pixmap (COGL_TEXTURE (tex_pixmap)->context, glx_tex_pixmap);
 
-  if (glx_tex_pixmap->glx_tex)
-    cogl_object_unref (glx_tex_pixmap->glx_tex);
+  if (glx_tex_pixmap->left.glx_tex)
+    cogl_object_unref (glx_tex_pixmap->left.glx_tex);
+
+  if (glx_tex_pixmap->right.glx_tex)
+    cogl_object_unref (glx_tex_pixmap->right.glx_tex);
 
   tex_pixmap->winsys = NULL;
   g_free (glx_tex_pixmap);
@@ -2494,11 +2519,14 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
 
 static CoglBool
 _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                        CoglBool right,
                                         CoglBool needs_mipmap)
 {
   CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
   CoglContext *ctx = COGL_TEXTURE (tex_pixmap)->context;
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
+  CoglPixmapTextureInfoGLX *texture_info = right ? &glx_tex_pixmap->right : &glx_tex_pixmap->left;
+  int buffer = right ? GLX_FRONT_RIGHT_EXT : GLX_FRONT_LEFT_EXT;
   CoglGLXRenderer *glx_renderer;
 
   /* If we don't have a GLX pixmap then fallback */
@@ -2508,7 +2536,7 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
   glx_renderer = ctx->display->renderer->winsys;
 
   /* Lazily create a texture to hold the pixmap */
-  if (glx_tex_pixmap->glx_tex == NULL)
+  if (texture_info->glx_tex == NULL)
     {
       CoglPixelFormat texture_format;
       CoglError *error = NULL;
@@ -2519,14 +2547,14 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
 
       if (should_use_rectangle (ctx))
         {
-          glx_tex_pixmap->glx_tex = COGL_TEXTURE (
+          texture_info->glx_tex = COGL_TEXTURE (
             cogl_texture_rectangle_new_with_size (ctx,
                                                   tex->width,
                                                   tex->height));
 
           _cogl_texture_set_internal_format (tex, texture_format);
 
-          if (cogl_texture_allocate (glx_tex_pixmap->glx_tex, &error))
+          if (cogl_texture_allocate (texture_info->glx_tex, &error))
             COGL_NOTE (TEXTURE_PIXMAP, "Created a texture rectangle for %p",
                        tex_pixmap);
           else
@@ -2541,14 +2569,14 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
         }
       else
         {
-          glx_tex_pixmap->glx_tex = COGL_TEXTURE (
+          texture_info->glx_tex = COGL_TEXTURE (
             cogl_texture_2d_new_with_size (ctx,
                                            tex->width,
                                            tex->height));
 
           _cogl_texture_set_internal_format (tex, texture_format);
 
-          if (cogl_texture_allocate (glx_tex_pixmap->glx_tex, &error))
+          if (cogl_texture_allocate (texture_info->glx_tex, &error))
             COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p",
                        tex_pixmap);
           else
@@ -2586,36 +2614,37 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
                          "updates for %p because creating the GLXPixmap "
                          "with mipmap support failed", tex_pixmap);
 
-              if (glx_tex_pixmap->glx_tex)
-                cogl_object_unref (glx_tex_pixmap->glx_tex);
+              if (texture_info->glx_tex)
+                cogl_object_unref (texture_info->glx_tex);
               return FALSE;
             }
 
-          glx_tex_pixmap->bind_tex_image_queued = TRUE;
+          texture_info->bind_tex_image_queued = TRUE;
+          glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
         }
     }
 
-  if (glx_tex_pixmap->bind_tex_image_queued)
+  if (texture_info->bind_tex_image_queued)
     {
       GLuint gl_handle, gl_target;
       CoglXlibRenderer *xlib_renderer =
         _cogl_xlib_renderer_get_data (ctx->display->renderer);
 
-      cogl_texture_get_gl_texture (glx_tex_pixmap->glx_tex,
+      cogl_texture_get_gl_texture (texture_info->glx_tex,
                                    &gl_handle, &gl_target);
 
       COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap);
 
       _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE);
 
-      if (glx_tex_pixmap->pixmap_bound)
+      if (texture_info->pixmap_bound)
         glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
                                           glx_tex_pixmap->glx_pixmap,
-                                          GLX_FRONT_LEFT_EXT);
+                                          buffer);
 
       glx_renderer->glXBindTexImage (xlib_renderer->xdpy,
                                      glx_tex_pixmap->glx_pixmap,
-                                     GLX_FRONT_LEFT_EXT,
+                                     buffer,
                                      NULL);
 
       /* According to the recommended usage in the spec for
@@ -2628,10 +2657,10 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
        * on Mesa and NVidia drivers and it is also what Compiz does so
        * it is probably ok */
 
-      glx_tex_pixmap->bind_tex_image_queued = FALSE;
-      glx_tex_pixmap->pixmap_bound = TRUE;
+      texture_info->bind_tex_image_queued = FALSE;
+      texture_info->pixmap_bound = TRUE;
 
-      _cogl_texture_2d_externally_modified (glx_tex_pixmap->glx_tex);
+      _cogl_texture_2d_externally_modified (texture_info->glx_tex);
     }
 
   return TRUE;
@@ -2642,15 +2671,20 @@ _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
 {
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
 
-  glx_tex_pixmap->bind_tex_image_queued = TRUE;
+  glx_tex_pixmap->left.bind_tex_image_queued = TRUE;
+  glx_tex_pixmap->right.bind_tex_image_queued = TRUE;
 }
 
 static CoglTexture *
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap,
+                                             CoglBool right)
 {
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
 
-  return glx_tex_pixmap->glx_tex;
+  if (right)
+    return glx_tex_pixmap->right.glx_tex;
+  else
+    return glx_tex_pixmap->left.glx_tex;
 }
 
 static CoglWinsysVtable _cogl_winsys_vtable =
diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h
index d6ff165..3f9ea90 100644
--- a/cogl/winsys/cogl-winsys-private.h
+++ b/cogl/winsys/cogl-winsys-private.h
@@ -166,13 +166,15 @@ typedef struct _CoglWinsysVtable
 
   CoglBool
   (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap,
+                                CoglBool right,
                                 CoglBool needs_mipmap);
 
   void
   (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap);
 
   CoglTexture *
-  (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap);
+  (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap,
+                                     CoglBool right);
 #endif
 
   void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]