[Cogl] [PATCH] CoglTexturePixmapX11: add support for stereo content

otaylor at redhat.com otaylor at redhat.com
Mon Jul 7 09:13:59 PDT 2014


From: "Owen W. Taylor" <otaylor at fishsoup.net>

Add cogl_texture_pixmap_x11_new_left() and
cogl_texture_pixmap_x11_new_right() (which takes the left texture
as an argument) for texture pixmap rendering with stereo content.
The underlying GLXPixmap is created using a stereo visual and shared
between the left and right textures.
---
 cogl/cogl-glx-display-private.h               |   3 +-
 cogl/winsys/cogl-texture-pixmap-x11-private.h |  18 ++++
 cogl/winsys/cogl-texture-pixmap-x11.c         |  96 ++++++++++++++++++++--
 cogl/winsys/cogl-texture-pixmap-x11.h         |  56 +++++++++++++
 cogl/winsys/cogl-winsys-egl-x11.c             |   4 +-
 cogl/winsys/cogl-winsys-glx.c                 | 113 ++++++++++++++++++--------
 cogl/winsys/cogl-winsys-private.h             |   4 +-
 7 files changed, 250 insertions(+), 44 deletions(-)

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..5da998f 100644
--- a/cogl/winsys/cogl-texture-pixmap-x11-private.h
+++ b/cogl/winsys/cogl-texture-pixmap-x11-private.h
@@ -55,10 +55,27 @@ struct _CoglDamageRectangle
   unsigned int y2;
 };
 
+/* For stereo, there are a pair of textures, but we want to share most
+ * other state (the GLXPixmap, visual, etc.) The way we do this is that
+ * the left-eye texture has all the state (there is in fact, no internal
+ * difference between the a MONO and a LEFT texture ), and the
+ * right-eye texture simply points to the left eye texture, with all
+ * other fields ignored.
+ */
+typedef enum
+{
+  COGL_TEXTURE_PIXMAP_MONO,
+  COGL_TEXTURE_PIXMAP_LEFT,
+  COGL_TEXTURE_PIXMAP_RIGHT
+} CoglTexturePixmapStereoMode;
+
 struct _CoglTexturePixmapX11
 {
   CoglTexture _parent;
 
+  CoglTexturePixmapStereoMode stereo_mode;
+  CoglTexturePixmapX11 *left; /* Set only if stereo_mode=RIGHT */
+
   Pixmap pixmap;
   CoglTexture *tex;
 
@@ -82,4 +99,5 @@ struct _CoglTexturePixmapX11
   CoglBool use_winsys_texture;
 };
 
+
 #endif /* __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H */
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/winsys/cogl-texture-pixmap-x11.c
index 6c1edeb..f5113bf 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,
+                              CoglTexturePixmapStereoMode stereo_mode,
+                              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->stereo_mode = stereo_mode;
+  tex_pixmap->left = NULL;
   tex_pixmap->image = NULL;
   tex_pixmap->shm_info.shmid = -1;
   tex_pixmap->tex = NULL;
@@ -387,6 +390,56 @@ 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, COGL_TEXTURE_PIXMAP_MONO,
+                                       error);
+}
+
+CoglTexturePixmapX11 *
+cogl_texture_pixmap_x11_new_left (CoglContext *ctxt,
+                                  uint32_t pixmap,
+                                  CoglBool automatic_updates,
+                                  CoglError **error)
+{
+  return _cogl_texture_pixmap_x11_new (ctxt, pixmap,
+                                       automatic_updates, COGL_TEXTURE_PIXMAP_LEFT,
+                                       error);
+}
+
+CoglTexturePixmapX11 *
+cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *tfp_left)
+{
+  CoglTexture *texture_left = COGL_TEXTURE (tfp_left);
+  CoglTexturePixmapX11 *tfp_right;
+  CoglPixelFormat internal_format;
+
+  g_return_val_if_fail (tfp_left->stereo_mode == COGL_TEXTURE_PIXMAP_LEFT, NULL);
+
+  tfp_right = g_new0 (CoglTexturePixmapX11, 1);
+  tfp_right->stereo_mode = COGL_TEXTURE_PIXMAP_RIGHT;
+  tfp_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 (tfp_right),
+		      texture_left->context,
+		      texture_left->width,
+		      texture_left->height,
+		      internal_format,
+		      NULL, /* no loader */
+		      &cogl_texture_pixmap_x11_vtable);
+
+  return _cogl_texture_pixmap_x11_object_new (tfp_right);
+}
+
 static CoglBool
 _cogl_texture_pixmap_x11_allocate (CoglTexture *tex,
                                    CoglError **error)
@@ -478,6 +531,9 @@ cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap,
      texture because we can't determine which will be needed until we
      actually render something */
 
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
+    tex_pixmap = tex_pixmap->left;
+
   if (tex_pixmap->winsys)
     {
       const CoglWinsysVtable *winsys;
@@ -492,6 +548,9 @@ cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap,
 CoglBool
 cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap)
 {
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
+    tex_pixmap = tex_pixmap->left;
+
   return !!tex_pixmap->winsys;
 }
 
@@ -505,6 +564,8 @@ cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *tex_pixmap,
 
   _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
 
+  g_return_if_fail (tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_RIGHT);
+
   damage_base = _cogl_xlib_get_damage_base ();
   if (damage_base >= 0)
     set_damage_object_internal (ctxt, tex_pixmap, damage, report_level);
@@ -717,12 +778,16 @@ static void
 _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
                                  CoglBool needs_mipmap)
 {
+  CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode;
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
+    tex_pixmap = tex_pixmap->left;
+
   if (tex_pixmap->winsys)
     {
       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, stereo_mode, needs_mipmap))
         {
           _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE);
           return;
@@ -739,8 +804,13 @@ _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
 static CoglTexture *
 _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
 {
+  CoglTexturePixmapX11 *original_pixmap = tex_pixmap;
   CoglTexture *tex;
   int i;
+  CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode;
+
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
+    tex_pixmap = tex_pixmap->left;
 
   /* We try getting the texture twice, once without flushing the
      updates and once with. If pre_paint has been called already then
@@ -757,7 +827,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, stereo_mode);
         }
       else
         tex = tex_pixmap->tex;
@@ -765,7 +835,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 (original_pixmap, FALSE);
     }
 
   g_assert_not_reached ();
@@ -1047,6 +1117,16 @@ _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
 
   _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
 
+  if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
+    {
+      cogl_object_unref (tex_pixmap->left);
+
+      /* Chain up */
+      _cogl_texture_free (COGL_TEXTURE (tex_pixmap));
+
+      return;
+    }
+
   display = cogl_xlib_renderer_get_display (ctxt->display->renderer);
 
   set_damage_object_internal (ctxt, tex_pixmap, 0, 0);
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.h b/cogl/winsys/cogl-texture-pixmap-x11.h
index 35155cd..6340bb5 100644
--- a/cogl/winsys/cogl-texture-pixmap-x11.h
+++ b/cogl/winsys/cogl-texture-pixmap-x11.h
@@ -138,6 +138,62 @@ cogl_texture_pixmap_x11_new (CoglContext *context,
                              CoglError **error);
 
 /**
+ * cogl_texture_pixmap_x11_new_left:
+ * @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 one of a pair of textures to contain the contents of @pixmap,
+ * which has stereo content. (Different images for the right and left eyes.)
+ * The left image is drawn using this texture; the right image is drawn
+ * using a texture created by calling
+ * cogl_texture_pixmap_x11_new_right() and passing in this texture as an
+ * argument.
+ *
+ * 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 left and right pixmaps 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_left (CoglContext *context,
+                                  uint32_t pixmap,
+                                  CoglBool automatic_updates,
+                                  CoglError **error);
+
+/**
+ * cogl_texture_pixmap_x11_new_right:
+ * @left_texture: A #CoglTexturePixmapX11 instance created with
+ *                cogl_texture_pixmap_x11_new_left().
+ *
+ * Creates a texture object that corresponds to the right-eye image
+ * of a pixmap with stereo content. @left_texture must have been
+ * created using cogl_texture_pixmap_x11_new_left().
+ *
+ * Return value: a new #CoglTexturePixmapX11 instance
+ *
+ * Since: 1.20
+ * Stability: Unstable
+ */
+CoglTexturePixmapX11 *
+cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *left_texture);
+
+/**
  * cogl_texture_pixmap_x11_update_area:
  * @texture: A #CoglTexturePixmapX11 instance
  * @x: x coordinate of the area to update
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..d4540e3 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,9 @@ 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_mode != COGL_TEXTURE_PIXMAP_MONO,
+                               &fb_config,
                                &glx_tex_pixmap->can_mipmap))
     {
       COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i",
@@ -2412,10 +2428,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 +2461,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 +2493,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 +2509,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,13 +2521,27 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
 
 static CoglBool
 _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                        CoglTexturePixmapStereoMode stereo_mode,
                                         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;
+  int buffer;
   CoglGLXRenderer *glx_renderer;
 
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT)
+    {
+      texture_info = &glx_tex_pixmap->right;
+      buffer = GLX_FRONT_RIGHT_EXT;
+    }
+  else
+    {
+      texture_info = &glx_tex_pixmap->left;
+      buffer = GLX_FRONT_LEFT_EXT;
+    }
+
   /* If we don't have a GLX pixmap then fallback */
   if (glx_tex_pixmap->glx_pixmap == None)
     return FALSE;
@@ -2508,7 +2549,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 +2560,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 +2582,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 +2627,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;
+          glx_tex_pixmap->left.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 +2670,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 +2684,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,
+                                             CoglTexturePixmapStereoMode stereo_mode)
 {
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
 
-  return glx_tex_pixmap->glx_tex;
+  if (stereo_mode == COGL_TEXTURE_PIXMAP_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..2c9cc98 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,
+                                CoglTexturePixmapStereoMode stereo_mode,
                                 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,
+                                     CoglTexturePixmapStereoMode stereo_mode);
 #endif
 
   void
-- 
1.9.3



More information about the Cogl mailing list