[Cogl] [PATCH 3/7] CoglTexturePixmapX11: add support for stereo content

Robert Bragg robert at sixbynine.org
Sun Jun 15 10:12:15 PDT 2014


On Thu, Jun 12, 2014 at 7:11 PM,  <otaylor at redhat.com> wrote:
> From: "Owen W. Taylor" <otaylor at fishsoup.net>
>
> 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.

I don't really understand why we would need a whole new texture object
to represent the right eye of a stereoscopic pixmap. Can't we just add
a cogl_texture_pixmap_x11_new_stereo() function that takes a
_LEFT/_RIGHT eye enum to effectively say that you want a
texture-from-pixmap-eye and the normal cogl_texture_pixmap_x11_new()
is equivalent to selecting the left eye?

--
Regards,
Robert

> ---
>  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(-)
>  create mode 100644 cogl/winsys/cogl-texture-pixmap-x11-right.c
>
> 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 at linux.intel.com>
> + *  Johan Bilien   <johan.bilien at nokia.com>
> + *  Robert Bragg   <robert at 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 5d2a858..0289d92 100644
> --- a/cogl/winsys/cogl-winsys-egl-x11.c
> +++ b/cogl/winsys/cogl-winsys-egl-x11.c
> @@ -776,6 +776,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)
> @@ -790,7 +791,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 f9c50bd..7ae7d2f 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
> @@ -2128,6 +2133,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)
>  {
> @@ -2145,11 +2151,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;
> @@ -2193,6 +2200,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,
> @@ -2350,7 +2364,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",
> @@ -2439,10 +2453,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;
>
> @@ -2469,10 +2486,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
> @@ -2497,7 +2518,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
> @@ -2512,8 +2534,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);
> @@ -2521,11 +2546,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 */
> @@ -2535,7 +2563,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;
> @@ -2546,14 +2574,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
> @@ -2568,14 +2596,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
> @@ -2613,36 +2641,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
> @@ -2655,10 +2684,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;
> @@ -2669,15 +2698,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
> --
> 1.9.3
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl


More information about the Cogl mailing list