[clutter/wip/cogl-winsys-egl: 3/21] texture-pixmap-x11: Move GLX code to cogl-winsys-glx.c



commit 76e950c1bbb89451addda811e9e6a779790ee95e
Author: Robert Bragg <robert linux intel com>
Date:   Tue Mar 1 14:43:43 2011 +0000

    texture-pixmap-x11: Move GLX code to cogl-winsys-glx.c
    
    This moves the GLX specific code from cogl-texture-pixmap-x11.c into
    cogl-winsys-glx.c. If we want the winsys components to by dynamically
    loadable then we can't have GLX code scattered outside of
    cogl-winsys-glx.c. This also sets us up for supporting the
    EGL_texture_from_pixmap extension which is almost identical to the
    GLX_texture_from_pixmap extension.

 .../cogl/winsys/cogl-texture-pixmap-x11-private.h  |   15 +-
 clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c |  530 +------------------
 clutter/cogl/cogl/winsys/cogl-winsys-egl.c         |   35 ++
 clutter/cogl/cogl/winsys/cogl-winsys-glx.c         |  549 ++++++++++++++++++++
 clutter/cogl/cogl/winsys/cogl-winsys-private.h     |   22 +
 5 files changed, 632 insertions(+), 519 deletions(-)
---
diff --git a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h b/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h
index 55da841..60c11b9 100644
--- a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h
+++ b/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h
@@ -36,6 +36,7 @@
 
 #include "cogl-handle.h"
 #include "cogl-texture-private.h"
+#include "cogl-texture-pixmap-x11.h"
 
 #define COGL_TEXTURE_PIXMAP_X11(tex) ((CoglTexturePixmapX11 *) tex)
 
@@ -72,18 +73,12 @@ struct _CoglTexturePixmapX11
   gboolean damage_owned;
   CoglDamageRectangle damage_rect;
 
-#ifdef COGL_HAS_GLX_SUPPORT
+  void *winsys;
+
   /* During the pre_paint method, this will be set to TRUE if we
-     should use the GLX texture, otherwise we will use the regular
+     should use the winsys texture, otherwise we will use the regular
      texture */
-  gboolean use_glx_texture;
-  CoglHandle glx_tex;
-  GLXPixmap glx_pixmap;
-  gboolean glx_pixmap_has_mipmap;
-  gboolean glx_can_mipmap;
-  gboolean bind_tex_image_queued;
-  gboolean pixmap_bound;
-#endif
+  gboolean use_winsys_texture;
 };
 
 GQuark
diff --git a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c b/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
index 32e48dc..c59d760 100644
--- a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
+++ b/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
@@ -23,6 +23,7 @@
  * Authors:
  *  Neil Roberts   <neil linux intel com>
  *  Johan Bilien   <johan bilien nokia com>
+ *  Robert Bragg   <robert linux intel com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -42,11 +43,7 @@
 #include "cogl-texture-rectangle-private.h"
 #include "cogl-context-private.h"
 #include "cogl-handle.h"
-#if COGL_HAS_GLX_SUPPORT
-#include "cogl-display-glx-private.h"
-#include "cogl-renderer-private.h"
-#include "cogl-renderer-glx-private.h"
-#endif
+#include "cogl-winsys-private.h"
 #include "cogl-pipeline-opengl-private.h"
 
 #include <X11/Xlib.h>
@@ -198,9 +195,7 @@ process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
   /* If we're using the texture from pixmap extension then there's no
      point in getting the region and we can just mark that the texture
      needs updating */
-#ifdef COGL_HAS_GLX_SUPPORT
-  tex_pixmap->bind_tex_image_queued = TRUE;
-#endif
+  _cogl_winsys_texture_pixmap_x11_damage_notify (tex_pixmap);
 }
 
 static CoglFilterReturn
@@ -224,283 +219,6 @@ _cogl_texture_pixmap_x11_filter (void *native_event, void *data)
   return COGL_FILTER_CONTINUE;
 }
 
-#ifdef COGL_HAS_GLX_SUPPORT
-
-static gboolean
-get_fbconfig_for_depth (unsigned int depth,
-                        GLXFBConfig *fbconfig_ret,
-                        gboolean *can_mipmap_ret)
-{
-  GLXFBConfig *fbconfigs;
-  int n_elements, i;
-  Display *dpy;
-  int db, stencil, alpha, mipmap, rgba, value;
-  int spare_cache_slot = 0;
-  gboolean found = FALSE;
-  CoglDisplayGLX *glx_display;
-
-  _COGL_GET_CONTEXT (ctxt, FALSE);
-  glx_display = ctxt->display->winsys;
-
-  /* Check if we've already got a cached config for this depth */
-  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)
-      {
-        *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config;
-        *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap;
-        return glx_display->glx_cached_configs[i].found;
-      }
-
-  dpy = cogl_xlib_get_display ();
-
-  fbconfigs = glXGetFBConfigs (dpy, DefaultScreen (dpy),
-                               &n_elements);
-
-  db      = G_MAXSHORT;
-  stencil = G_MAXSHORT;
-  mipmap  = 0;
-  rgba    = 0;
-
-  for (i = 0; i < n_elements; i++)
-    {
-      XVisualInfo *vi;
-      int          visual_depth;
-
-      vi = glXGetVisualFromFBConfig (dpy,
-                                     fbconfigs[i]);
-      if (vi == NULL)
-        continue;
-
-      visual_depth = vi->depth;
-
-      XFree (vi);
-
-      if (visual_depth != depth)
-        continue;
-
-      glXGetFBConfigAttrib (dpy,
-                            fbconfigs[i],
-                            GLX_ALPHA_SIZE,
-                            &alpha);
-      glXGetFBConfigAttrib (dpy,
-                            fbconfigs[i],
-                            GLX_BUFFER_SIZE,
-                            &value);
-      if (value != depth && (value - alpha) != depth)
-        continue;
-
-      value = 0;
-      if (depth == 32)
-        {
-          glXGetFBConfigAttrib (dpy,
-                                fbconfigs[i],
-                                GLX_BIND_TO_TEXTURE_RGBA_EXT,
-                                &value);
-          if (value)
-            rgba = 1;
-        }
-
-      if (!value)
-        {
-          if (rgba)
-            continue;
-
-          glXGetFBConfigAttrib (dpy,
-                                fbconfigs[i],
-                                GLX_BIND_TO_TEXTURE_RGB_EXT,
-                                &value);
-          if (!value)
-            continue;
-        }
-
-      glXGetFBConfigAttrib (dpy,
-                            fbconfigs[i],
-                            GLX_DOUBLEBUFFER,
-                            &value);
-      if (value > db)
-        continue;
-
-      db = value;
-
-      glXGetFBConfigAttrib (dpy,
-                            fbconfigs[i],
-                            GLX_STENCIL_SIZE,
-                            &value);
-      if (value > stencil)
-        continue;
-
-      stencil = value;
-
-      /* glGenerateMipmap is defined in the offscreen extension */
-      if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
-        {
-          glXGetFBConfigAttrib (dpy,
-                                fbconfigs[i],
-                                GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
-                                &value);
-
-          if (value < mipmap)
-            continue;
-
-          mipmap =  value;
-        }
-
-      *fbconfig_ret = fbconfigs[i];
-      *can_mipmap_ret = mipmap;
-      found = TRUE;
-    }
-
-  if (n_elements)
-    XFree (fbconfigs);
-
-  glx_display->glx_cached_configs[spare_cache_slot].depth = depth;
-  glx_display->glx_cached_configs[spare_cache_slot].found = found;
-  glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret;
-  glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap;
-
-  return found;
-}
-
-static gboolean
-should_use_rectangle (void)
-{
-  _COGL_GET_CONTEXT (ctxt, FALSE);
-
-  if (ctxt->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_UNKNOWN)
-    {
-      if (cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE))
-        {
-          const char *rect_env;
-
-          /* Use the rectangle only if it is available and either:
-
-             the COGL_PIXMAP_TEXTURE_RECTANGLE environment variable is
-             set to 'force'
-
-             *or*
-
-             the env var is set to 'allow' or not set and NPOTs textures
-             are not available */
-
-          ctxt->rectangle_state =
-            cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) ?
-            COGL_WINSYS_RECTANGLE_STATE_DISABLE :
-            COGL_WINSYS_RECTANGLE_STATE_ENABLE;
-
-          if ((rect_env = g_getenv ("COGL_PIXMAP_TEXTURE_RECTANGLE")) ||
-              /* For compatibility, we'll also look at the old Clutter
-                 environment variable */
-              (rect_env = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE")))
-            {
-              if (g_ascii_strcasecmp (rect_env, "force") == 0)
-                ctxt->rectangle_state =
-                  COGL_WINSYS_RECTANGLE_STATE_ENABLE;
-              else if (g_ascii_strcasecmp (rect_env, "disable") == 0)
-                ctxt->rectangle_state =
-                  COGL_WINSYS_RECTANGLE_STATE_DISABLE;
-              else if (g_ascii_strcasecmp (rect_env, "allow"))
-                g_warning ("Unknown value for COGL_PIXMAP_TEXTURE_RECTANGLE, "
-                           "should be 'force' or 'disable'");
-            }
-        }
-      else
-        ctxt->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_DISABLE;
-    }
-
-  return ctxt->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_ENABLE;
-}
-
-static void
-try_create_glx_pixmap (CoglTexturePixmapX11 *tex_pixmap,
-                       gboolean mipmap)
-{
-  Display *dpy;
-  /* We have to initialize this *opaque* variable because gcc tries to
-   * be too smart for its own good and warns that the variable may be
-   * used uninitialized otherwise. */
-  GLXFBConfig fb_config = (GLXFBConfig)0;
-  int attribs[7];
-  int i = 0;
-  GLenum target;
-  CoglXlibTrapState trap_state;
-
-  _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
-
-  tex_pixmap->pixmap_bound = FALSE;
-  tex_pixmap->glx_pixmap = None;
-
-  if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP))
-    return;
-
-  dpy = cogl_xlib_get_display ();
-
-  if (!get_fbconfig_for_depth (tex_pixmap->depth, &fb_config,
-                               &tex_pixmap->glx_can_mipmap))
-    {
-      COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i",
-                 tex_pixmap->depth);
-      return;
-    }
-
-  if (should_use_rectangle ())
-    {
-      target = GLX_TEXTURE_RECTANGLE_EXT;
-      tex_pixmap->glx_can_mipmap = FALSE;
-    }
-  else
-    target = GLX_TEXTURE_2D_EXT;
-
-  if (!tex_pixmap->glx_can_mipmap)
-    mipmap = FALSE;
-
-  attribs[i++] = GLX_TEXTURE_FORMAT_EXT;
-
-  if (tex_pixmap->depth == 24)
-    attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT;
-  else if (tex_pixmap->depth == 32)
-    attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT;
-  else
-    return;
-
-  attribs[i++] = GLX_MIPMAP_TEXTURE_EXT;
-  attribs[i++] = mipmap;
-
-  attribs[i++] = GLX_TEXTURE_TARGET_EXT;
-  attribs[i++] = target;
-
-  attribs[i++] = None;
-
-  /* We need to trap errors from glXCreatePixmap because it can
-     sometimes fail during normal usage. For example on NVidia it gets
-     upset if you try to create two GLXPixmaps for the same
-     drawable. */
-
-  _cogl_xlib_trap_errors (&trap_state);
-
-  tex_pixmap->glx_pixmap = glXCreatePixmap (dpy,
-                                            fb_config,
-                                            tex_pixmap->pixmap,
-                                            attribs);
-  tex_pixmap->glx_pixmap_has_mipmap = mipmap;
-
-  XSync (dpy, False);
-
-  if (_cogl_xlib_untrap_errors (&trap_state))
-    {
-      COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap);
-      _cogl_xlib_trap_errors (&trap_state);
-      glXDestroyPixmap (dpy, tex_pixmap->glx_pixmap);
-      XSync (dpy, False);
-      _cogl_xlib_untrap_errors (&trap_state);
-
-      tex_pixmap->glx_pixmap = None;
-    }
-}
-
-#endif /* COGL_HAS_GLX_SUPPORT */
-
 static void
 set_damage_object_internal (CoglTexturePixmapX11 *tex_pixmap,
                             Damage damage,
@@ -589,13 +307,7 @@ cogl_texture_pixmap_x11_new (guint32 pixmap,
   tex_pixmap->damage_rect.y1 = 0;
   tex_pixmap->damage_rect.y2 = tex_pixmap->height;
 
-#ifdef COGL_HAS_GLX_SUPPORT
-  try_create_glx_pixmap (tex_pixmap, FALSE);
-
-  tex_pixmap->glx_tex = COGL_INVALID_HANDLE;
-  tex_pixmap->bind_tex_image_queued = TRUE;
-  tex_pixmap->use_glx_texture = FALSE;
-#endif
+  _cogl_winsys_texture_pixmap_x11_create (tex_pixmap);
 
   return _cogl_texture_pixmap_x11_handle_new (tex_pixmap);
 }
@@ -686,9 +398,7 @@ cogl_texture_pixmap_x11_update_area (CoglHandle handle,
      texture because we can't determine which will be needed until we
      actually render something */
 
-#ifdef COGL_HAS_GLX_SUPPORT
-  tex_pixmap->bind_tex_image_queued = TRUE;
-#endif
+  _cogl_winsys_texture_pixmap_x11_damage_notify (tex_pixmap);
 
   cogl_damage_rectangle_union (&tex_pixmap->damage_rect,
                                x, y, width, height);
@@ -702,11 +412,7 @@ cogl_texture_pixmap_x11_is_using_tfp_extension (CoglHandle handle)
   if (!cogl_is_texture_pixmap_x11 (tex_pixmap))
     return FALSE;
 
-#ifdef COGL_HAS_GLX_SUPPORT
-  return tex_pixmap->glx_pixmap != None;
-#else
-  return FALSE;
-#endif
+  return !!tex_pixmap->winsys;
 }
 
 void
@@ -890,225 +596,37 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
   memset (&tex_pixmap->damage_rect, 0, sizeof (CoglDamageRectangle));
 }
 
-#ifdef COGL_HAS_GLX_SUPPORT
-
-static void
-_cogl_texture_pixmap_x11_free_glx_pixmap (CoglTexturePixmapX11 *tex_pixmap)
-{
-  if (tex_pixmap->glx_pixmap)
-    {
-      CoglXlibTrapState trap_state;
-      CoglRendererGLX *glx_renderer;
-
-      _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-      glx_renderer = ctx->display->renderer->winsys;
-
-      if (tex_pixmap->pixmap_bound)
-        glx_renderer->pf_glXReleaseTexImage (cogl_xlib_get_display (),
-                                             tex_pixmap->glx_pixmap,
-                                             GLX_FRONT_LEFT_EXT);
-
-      /* FIXME - we need to trap errors and synchronize here because
-       * of ordering issues between the XPixmap destruction and the
-       * GLXPixmap destruction.
-       *
-       * If the X pixmap is destroyed, the GLX pixmap is destroyed as
-       * well immediately, and thus, when Cogl calls glXDestroyPixmap()
-       * it'll cause a BadDrawable error.
-       *
-       * this is technically a bug in the X server, which should not
-       * destroy either pixmaps until the call to glXDestroyPixmap(); so
-       * at some point we should revisit this code and remove the
-       * trap+sync after verifying that the destruction is indeed safe.
-       *
-       * for reference, see:
-       *   http://bugzilla.clutter-project.org/show_bug.cgi?id=2324
-       */
-      _cogl_xlib_trap_errors (&trap_state);
-      glXDestroyPixmap (cogl_xlib_get_display (), tex_pixmap->glx_pixmap);
-      XSync (cogl_xlib_get_display (), False);
-      _cogl_xlib_untrap_errors (&trap_state);
-
-      tex_pixmap->glx_pixmap = None;
-      tex_pixmap->pixmap_bound = FALSE;
-    }
-}
-
-static gboolean
-_cogl_texture_pixmap_x11_update_glx_texture (CoglTexturePixmapX11 *tex_pixmap,
-                                             gboolean needs_mipmap)
-{
-  gboolean ret = TRUE;
-  CoglRendererGLX *glx_renderer;
-
-  _COGL_GET_CONTEXT (ctx, FALSE);
-  glx_renderer = ctx->display->renderer->winsys;
-
-  /* If we don't have a GLX pixmap then fallback */
-  if (tex_pixmap->glx_pixmap == None)
-    ret = FALSE;
-  else
-    {
-      /* Lazily create a texture to hold the pixmap */
-      if (tex_pixmap->glx_tex == COGL_INVALID_HANDLE)
-        {
-          CoglPixelFormat texture_format;
-
-          texture_format = (tex_pixmap->depth >= 32 ?
-                            COGL_PIXEL_FORMAT_RGBA_8888_PRE :
-                            COGL_PIXEL_FORMAT_RGB_888);
-
-          if (should_use_rectangle ())
-            {
-              tex_pixmap->glx_tex =
-                _cogl_texture_rectangle_new_with_size (tex_pixmap->width,
-                                                       tex_pixmap->height,
-                                                       COGL_TEXTURE_NO_ATLAS,
-                                                       texture_format);
-
-              if (tex_pixmap->glx_tex)
-                COGL_NOTE (TEXTURE_PIXMAP, "Created a texture rectangle for %p",
-                           tex_pixmap);
-              else
-                {
-                  COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a "
-                             "texture rectangle could not be created",
-                             tex_pixmap);
-                  _cogl_texture_pixmap_x11_free_glx_pixmap (tex_pixmap);
-                  ret = FALSE;
-                }
-            }
-          else
-            {
-              tex_pixmap->glx_tex =
-                _cogl_texture_2d_new_with_size (tex_pixmap->width,
-                                                tex_pixmap->height,
-                                                COGL_TEXTURE_NO_ATLAS,
-                                                texture_format);
-
-              if (tex_pixmap->glx_tex)
-                COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p",
-                           tex_pixmap);
-              else
-                {
-                  COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a "
-                             "texture 2d could not be created",
-                             tex_pixmap);
-                  _cogl_texture_pixmap_x11_free_glx_pixmap (tex_pixmap);
-                  ret = FALSE;
-                }
-            }
-        }
-
-      if (ret && needs_mipmap)
-        {
-          /* If we can't support mipmapping then temporarily fallback */
-          if (!tex_pixmap->glx_can_mipmap)
-            ret = FALSE;
-          /* Recreate the GLXPixmap if it wasn't previously created with a
-             mipmap tree */
-          else if (!tex_pixmap->glx_pixmap_has_mipmap)
-            {
-              _cogl_texture_pixmap_x11_free_glx_pixmap (tex_pixmap);
-
-              COGL_NOTE (TEXTURE_PIXMAP, "Recreating GLXPixmap with mipmap "
-                         "support for %p", tex_pixmap);
-              try_create_glx_pixmap (tex_pixmap, TRUE);
-
-              /* If the pixmap failed then we'll permanently fallback to using
-                 XImage. This shouldn't happen */
-              if (tex_pixmap->glx_pixmap == None)
-                {
-                  COGL_NOTE (TEXTURE_PIXMAP, "Falling back to XGetImage "
-                             "updates for %p because creating the GLXPixmap "
-                             "with mipmap support failed", tex_pixmap);
-
-                  if (tex_pixmap->glx_tex)
-                    cogl_handle_unref (tex_pixmap->glx_tex);
-
-                  ret = FALSE;
-                }
-              else
-                tex_pixmap->bind_tex_image_queued = TRUE;
-            }
-        }
-
-      if (ret && tex_pixmap->bind_tex_image_queued)
-        {
-          GLuint gl_handle, gl_target;
-
-          cogl_texture_get_gl_texture (tex_pixmap->glx_tex,
-                                       &gl_handle, &gl_target);
-
-          COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap);
-
-          GE( _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE) );
-
-          if (tex_pixmap->pixmap_bound)
-            glx_renderer->pf_glXReleaseTexImage (cogl_xlib_get_display (),
-                                                 tex_pixmap->glx_pixmap,
-                                                 GLX_FRONT_LEFT_EXT);
-
-          glx_renderer->pf_glXBindTexImage (cogl_xlib_get_display (),
-                                            tex_pixmap->glx_pixmap,
-                                            GLX_FRONT_LEFT_EXT,
-                                            NULL);
-
-          /* According to the recommended usage in the spec for
-             GLX_EXT_texture_pixmap we should release the texture after
-             we've finished drawing with it and it is undefined what
-             happens if you render to a pixmap that is bound to a
-             texture. However that would require the texture backend to
-             know when Cogl has finished painting and it may be more
-             expensive to keep unbinding the texture. Leaving it bound
-             appears to work on Mesa and NVidia drivers and it is also
-             what Compiz does so it is probably ok */
-
-          tex_pixmap->bind_tex_image_queued = FALSE;
-          tex_pixmap->pixmap_bound = TRUE;
-
-          _cogl_texture_2d_externally_modified (tex_pixmap->glx_tex);
-        }
-    }
-
-  return ret;
-}
-
 static void
-_cogl_texture_pixmap_x11_set_use_glx_texture (CoglTexturePixmapX11 *tex_pixmap,
-                                              gboolean new_value)
+_cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixmap,
+                                                 gboolean new_value)
 {
-  if (tex_pixmap->use_glx_texture != new_value)
+  if (tex_pixmap->use_winsys_texture != new_value)
     {
       /* Notify cogl-pipeline.c that the texture's underlying GL texture
        * storage is changing so it knows it may need to bind a new texture
        * if the CoglTexture is reused with the same texture unit. */
       _cogl_pipeline_texture_storage_change_notify (tex_pixmap);
 
-      tex_pixmap->use_glx_texture = new_value;
+      tex_pixmap->use_winsys_texture = new_value;
     }
 }
 
-#endif /* COGL_HAS_GLX_SUPPORT */
-
 static void
 _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
                                  gboolean needs_mipmap)
 {
-#ifdef COGL_HAS_GLX_SUPPORT
-
-  /* First try updating with GLX TFP */
-  if (_cogl_texture_pixmap_x11_update_glx_texture (tex_pixmap, needs_mipmap))
+  if (tex_pixmap->winsys)
     {
-      _cogl_texture_pixmap_x11_set_use_glx_texture (tex_pixmap, TRUE);
-      return;
+      if (_cogl_winsys_texture_pixmap_x11_update (tex_pixmap, needs_mipmap))
+        {
+          _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE);
+          return;
+        }
     }
 
   /* If it didn't work then fallback to using XGetImage. This may be
      temporary */
-  _cogl_texture_pixmap_x11_set_use_glx_texture (tex_pixmap, FALSE);
-
-#endif /* COGL_HAS_GLX_SUPPORT */
+  _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, FALSE);
 
   _cogl_texture_pixmap_x11_update_image_texture (tex_pixmap);
 }
@@ -1130,11 +648,9 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
 
   for (i = 0; i < 2; i++)
     {
-#ifdef COGL_HAS_GLX_SUPPORT
-      if (tex_pixmap->use_glx_texture)
-        tex = tex_pixmap->glx_tex;
+      if (tex_pixmap->use_winsys_texture)
+        tex = _cogl_winsys_texture_pixmap_x11_get_texture (tex_pixmap);
       else
-#endif
         tex = tex_pixmap->tex;
 
       if (tex)
@@ -1395,12 +911,8 @@ _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
   if (tex_pixmap->tex)
     cogl_handle_unref (tex_pixmap->tex);
 
-#ifdef COGL_HAS_GLX_SUPPORT
-  _cogl_texture_pixmap_x11_free_glx_pixmap (tex_pixmap);
-
-  if (tex_pixmap->glx_tex)
-    cogl_handle_unref (tex_pixmap->glx_tex);
-#endif
+  if (tex_pixmap->winsys)
+    _cogl_winsys_texture_pixmap_x11_free (tex_pixmap);
 
   /* Chain up */
   _cogl_texture_free (COGL_TEXTURE (tex_pixmap));
diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-egl.c b/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
index d5231ba..2c27c1a 100644
--- a/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
+++ b/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
@@ -1085,3 +1085,38 @@ _cogl_winsys_context_egl_get_egl_display (CoglContext *context)
 
   return egl_renderer->edpy;
 }
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+gboolean
+_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
+{
+  /* Unsupported feature */
+  tex_pixmap->winsys = NULL;
+  return FALSE;
+}
+
+void
+_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
+{
+  /* Unsupported feature */
+}
+
+gboolean
+_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                        gboolean needs_mipmap)
+{
+  /* Unsupported feature */
+}
+
+void
+_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
+{
+  /* Unsupported feature */
+}
+
+CoglHandle
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+{
+  /* Unsupported feature */
+}
+#endif
diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-glx.c b/clutter/cogl/cogl/winsys/cogl-winsys-glx.c
index aaa1433..7668a5f 100644
--- a/clutter/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/clutter/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -41,6 +41,9 @@
 #include "cogl-display-xlib-private.h"
 #include "cogl-display-glx-private.h"
 #include "cogl-private.h"
+#include "cogl-texture-2d-private.h"
+#include "cogl-texture-rectangle-private.h"
+#include "cogl-pipeline-opengl-private.h"
 
 #include <stdlib.h>
 #include <sys/types.h>
@@ -87,6 +90,17 @@ typedef struct _CoglSwapBuffersNotifyEntry
   unsigned int id;
 } CoglSwapBuffersNotifyEntry;
 
+typedef struct _CoglTexturePixmapGLX
+{
+  GLXPixmap glx_pixmap;
+  gboolean has_mipmap_space;
+  gboolean can_mipmap;
+
+  CoglHandle glx_tex;
+
+  gboolean bind_tex_image_queued;
+  gboolean pixmap_bound;
+} CoglTexturePixmapGLX;
 
 /* Define a set of arrays containing the functions required from GL
    for each winsys feature */
@@ -1327,3 +1341,538 @@ _cogl_winsys_xlib_get_visual_info (void)
 
   return glXGetVisualFromFBConfig (xlib_renderer->xdpy, glx_display->fbconfig);
 }
+
+static gboolean
+get_fbconfig_for_depth (CoglContext *context,
+                        unsigned int depth,
+                        GLXFBConfig *fbconfig_ret,
+                        gboolean *can_mipmap_ret)
+{
+  CoglRendererXlib *xlib_renderer;
+  CoglDisplayGLX *glx_display;
+  Display *dpy;
+  GLXFBConfig *fbconfigs;
+  int n_elements, i;
+  int db, stencil, alpha, mipmap, rgba, value;
+  int spare_cache_slot = 0;
+  gboolean found = FALSE;
+
+  xlib_renderer = context->display->renderer->winsys;
+  glx_display = context->display->winsys;
+
+  /* Check if we've already got a cached config for this depth */
+  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)
+      {
+        *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config;
+        *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap;
+        return glx_display->glx_cached_configs[i].found;
+      }
+
+  dpy = xlib_renderer->xdpy;
+
+  fbconfigs = glXGetFBConfigs (dpy, DefaultScreen (dpy), &n_elements);
+
+  db = G_MAXSHORT;
+  stencil = G_MAXSHORT;
+  mipmap = 0;
+  rgba = 0;
+
+  for (i = 0; i < n_elements; i++)
+    {
+      XVisualInfo *vi;
+      int visual_depth;
+
+      vi = glXGetVisualFromFBConfig (dpy, fbconfigs[i]);
+      if (vi == NULL)
+        continue;
+
+      visual_depth = vi->depth;
+
+      XFree (vi);
+
+      if (visual_depth != depth)
+        continue;
+
+      glXGetFBConfigAttrib (dpy,
+                            fbconfigs[i],
+                            GLX_ALPHA_SIZE,
+                            &alpha);
+      glXGetFBConfigAttrib (dpy,
+                            fbconfigs[i],
+                            GLX_BUFFER_SIZE,
+                            &value);
+      if (value != depth && (value - alpha) != depth)
+        continue;
+
+      value = 0;
+      if (depth == 32)
+        {
+          glXGetFBConfigAttrib (dpy,
+                                fbconfigs[i],
+                                GLX_BIND_TO_TEXTURE_RGBA_EXT,
+                                &value);
+          if (value)
+            rgba = 1;
+        }
+
+      if (!value)
+        {
+          if (rgba)
+            continue;
+
+          glXGetFBConfigAttrib (dpy,
+                                fbconfigs[i],
+                                GLX_BIND_TO_TEXTURE_RGB_EXT,
+                                &value);
+          if (!value)
+            continue;
+        }
+
+      glXGetFBConfigAttrib (dpy,
+                            fbconfigs[i],
+                            GLX_DOUBLEBUFFER,
+                            &value);
+      if (value > db)
+        continue;
+
+      db = value;
+
+      glXGetFBConfigAttrib (dpy,
+                            fbconfigs[i],
+                            GLX_STENCIL_SIZE,
+                            &value);
+      if (value > stencil)
+        continue;
+
+      stencil = value;
+
+      /* glGenerateMipmap is defined in the offscreen extension */
+      if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
+        {
+          glXGetFBConfigAttrib (dpy,
+                                fbconfigs[i],
+                                GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
+                                &value);
+
+          if (value < mipmap)
+            continue;
+
+          mipmap =  value;
+        }
+
+      *fbconfig_ret = fbconfigs[i];
+      *can_mipmap_ret = mipmap;
+      found = TRUE;
+    }
+
+  if (n_elements)
+    XFree (fbconfigs);
+
+  glx_display->glx_cached_configs[spare_cache_slot].depth = depth;
+  glx_display->glx_cached_configs[spare_cache_slot].found = found;
+  glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret;
+  glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap;
+
+  return found;
+}
+
+static gboolean
+should_use_rectangle (CoglContext *context)
+{
+
+  if (context->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_UNKNOWN)
+    {
+      if (cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE))
+        {
+          const char *rect_env;
+
+          /* Use the rectangle only if it is available and either:
+
+             the COGL_PIXMAP_TEXTURE_RECTANGLE environment variable is
+             set to 'force'
+
+             *or*
+
+             the env var is set to 'allow' or not set and NPOTs textures
+             are not available */
+
+          context->rectangle_state =
+            cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) ?
+            COGL_WINSYS_RECTANGLE_STATE_DISABLE :
+            COGL_WINSYS_RECTANGLE_STATE_ENABLE;
+
+          if ((rect_env = g_getenv ("COGL_PIXMAP_TEXTURE_RECTANGLE")) ||
+              /* For compatibility, we'll also look at the old Clutter
+                 environment variable */
+              (rect_env = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE")))
+            {
+              if (g_ascii_strcasecmp (rect_env, "force") == 0)
+                context->rectangle_state =
+                  COGL_WINSYS_RECTANGLE_STATE_ENABLE;
+              else if (g_ascii_strcasecmp (rect_env, "disable") == 0)
+                context->rectangle_state =
+                  COGL_WINSYS_RECTANGLE_STATE_DISABLE;
+              else if (g_ascii_strcasecmp (rect_env, "allow"))
+                g_warning ("Unknown value for COGL_PIXMAP_TEXTURE_RECTANGLE, "
+                           "should be 'force' or 'disable'");
+            }
+        }
+      else
+        context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_DISABLE;
+    }
+
+  return context->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_ENABLE;
+}
+
+static gboolean
+try_create_glx_pixmap (CoglContext *context,
+                       CoglTexturePixmapX11 *tex_pixmap,
+                       gboolean mipmap)
+{
+  CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
+  CoglRenderer *renderer;
+  CoglRendererXlib *xlib_renderer;
+  Display *dpy;
+  /* We have to initialize this *opaque* variable because gcc tries to
+   * be too smart for its own good and warns that the variable may be
+   * used uninitialized otherwise. */
+  GLXFBConfig fb_config = (GLXFBConfig)0;
+  int attribs[7];
+  int i = 0;
+  GLenum target;
+  CoglXlibTrapState trap_state;
+
+  renderer = context->display->renderer;
+  xlib_renderer = renderer->winsys;
+  dpy = xlib_renderer->xdpy;
+
+  if (!get_fbconfig_for_depth (context,
+                               tex_pixmap->depth, &fb_config,
+                               &glx_tex_pixmap->can_mipmap))
+    {
+      COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i",
+                 tex_pixmap->depth);
+      return FALSE;
+    }
+
+  if (should_use_rectangle (context))
+    {
+      target = GLX_TEXTURE_RECTANGLE_EXT;
+      glx_tex_pixmap->can_mipmap = FALSE;
+    }
+  else
+    target = GLX_TEXTURE_2D_EXT;
+
+  if (!glx_tex_pixmap->can_mipmap)
+    mipmap = FALSE;
+
+  attribs[i++] = GLX_TEXTURE_FORMAT_EXT;
+
+  if (tex_pixmap->depth == 24)
+    attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT;
+  else if (tex_pixmap->depth == 32)
+    attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT;
+  else
+    return FALSE;
+
+  attribs[i++] = GLX_MIPMAP_TEXTURE_EXT;
+  attribs[i++] = mipmap;
+
+  attribs[i++] = GLX_TEXTURE_TARGET_EXT;
+  attribs[i++] = target;
+
+  attribs[i++] = None;
+
+  /* We need to trap errors from glXCreatePixmap because it can
+   * sometimes fail during normal usage. For example on NVidia it gets
+   * upset if you try to create two GLXPixmaps for the same drawable.
+   */
+
+  _cogl_renderer_xlib_trap_errors (renderer, &trap_state);
+
+  glx_tex_pixmap->glx_pixmap = glXCreatePixmap (dpy,
+                                                fb_config,
+                                                tex_pixmap->pixmap,
+                                                attribs);
+  glx_tex_pixmap->has_mipmap_space = mipmap;
+
+  XSync (dpy, False);
+
+  if (_cogl_renderer_xlib_untrap_errors (renderer, &trap_state))
+    {
+      COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap);
+      _cogl_renderer_xlib_trap_errors (renderer, &trap_state);
+      glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap);
+      XSync (dpy, False);
+      _cogl_renderer_xlib_untrap_errors (renderer, &trap_state);
+
+      glx_tex_pixmap->glx_pixmap = None;
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
+{
+  CoglTexturePixmapGLX *glx_tex_pixmap;
+
+  /* FIXME: It should be possible to get to a CoglContext from any
+   * CoglTexture pointer. */
+  _COGL_GET_CONTEXT (ctx, FALSE);
+
+  if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP))
+    {
+      tex_pixmap->winsys = NULL;
+      return FALSE;
+    }
+
+  glx_tex_pixmap = g_new0 (CoglTexturePixmapGLX, 1);
+
+  glx_tex_pixmap->glx_pixmap = None;
+  glx_tex_pixmap->can_mipmap = FALSE;
+  glx_tex_pixmap->has_mipmap_space = FALSE;
+
+  glx_tex_pixmap->glx_tex = COGL_INVALID_HANDLE;
+
+  glx_tex_pixmap->bind_tex_image_queued = TRUE;
+  glx_tex_pixmap->pixmap_bound = FALSE;
+
+  tex_pixmap->winsys = glx_tex_pixmap;
+
+  if (!try_create_glx_pixmap (ctx, tex_pixmap, FALSE))
+    {
+      tex_pixmap->winsys = NULL;
+      g_free (glx_tex_pixmap);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+free_glx_pixmap (CoglContext *context,
+                 CoglTexturePixmapGLX *glx_tex_pixmap)
+{
+  CoglXlibTrapState trap_state;
+  CoglRenderer *renderer;
+  CoglRendererXlib *xlib_renderer;
+  CoglRendererGLX *glx_renderer;
+
+  renderer = context->display->renderer;
+  xlib_renderer = renderer->winsys;
+  glx_renderer = renderer->winsys;
+
+  if (glx_tex_pixmap->pixmap_bound)
+    glx_renderer->pf_glXReleaseTexImage (xlib_renderer->xdpy,
+                                         glx_tex_pixmap->glx_pixmap,
+                                         GLX_FRONT_LEFT_EXT);
+
+  /* FIXME - we need to trap errors and synchronize here because
+   * of ordering issues between the XPixmap destruction and the
+   * GLXPixmap destruction.
+   *
+   * If the X pixmap is destroyed, the GLX pixmap is destroyed as
+   * well immediately, and thus, when Cogl calls glXDestroyPixmap()
+   * it'll cause a BadDrawable error.
+   *
+   * this is technically a bug in the X server, which should not
+   * destroy either pixmaps until the call to glXDestroyPixmap(); so
+   * at some point we should revisit this code and remove the
+   * trap+sync after verifying that the destruction is indeed safe.
+   *
+   * for reference, see:
+   *   http://bugzilla.clutter-project.org/show_bug.cgi?id=2324
+   */
+  _cogl_renderer_xlib_trap_errors (renderer, &trap_state);
+  glXDestroyPixmap (xlib_renderer->xdpy, glx_tex_pixmap->glx_pixmap);
+  XSync (xlib_renderer->xdpy, False);
+  _cogl_renderer_xlib_untrap_errors (renderer, &trap_state);
+
+  glx_tex_pixmap->glx_pixmap = None;
+  glx_tex_pixmap->pixmap_bound = FALSE;
+}
+
+void
+_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
+{
+  CoglTexturePixmapGLX *glx_tex_pixmap;
+
+  /* FIXME: It should be possible to get to a CoglContext from any
+   * CoglTexture pointer. */
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  if (!tex_pixmap->winsys)
+    return;
+
+  glx_tex_pixmap = tex_pixmap->winsys;
+
+  free_glx_pixmap (ctx, glx_tex_pixmap);
+
+  if (glx_tex_pixmap->glx_tex)
+    cogl_handle_unref (glx_tex_pixmap->glx_tex);
+
+  tex_pixmap->winsys = NULL;
+  g_free (glx_tex_pixmap);
+}
+
+gboolean
+_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                        gboolean needs_mipmap)
+{
+  CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
+  CoglRendererGLX *glx_renderer;
+
+  /* FIXME: It should be possible to get to a CoglContext from any CoglTexture
+   * pointer. */
+  _COGL_GET_CONTEXT (ctx, FALSE);
+
+  /* If we don't have a GLX pixmap then fallback */
+  if (glx_tex_pixmap->glx_pixmap == None)
+    return FALSE;
+
+  glx_renderer = ctx->display->renderer->winsys;
+
+  /* Lazily create a texture to hold the pixmap */
+  if (glx_tex_pixmap->glx_tex == COGL_INVALID_HANDLE)
+    {
+      CoglPixelFormat texture_format;
+
+      texture_format = (tex_pixmap->depth >= 32 ?
+                        COGL_PIXEL_FORMAT_RGBA_8888_PRE :
+                        COGL_PIXEL_FORMAT_RGB_888);
+
+      if (should_use_rectangle (ctx))
+        {
+          glx_tex_pixmap->glx_tex =
+            _cogl_texture_rectangle_new_with_size (tex_pixmap->width,
+                                                   tex_pixmap->height,
+                                                   COGL_TEXTURE_NO_ATLAS,
+                                                   texture_format);
+
+          if (glx_tex_pixmap->glx_tex)
+            COGL_NOTE (TEXTURE_PIXMAP, "Created a texture rectangle for %p",
+                       tex_pixmap);
+          else
+            {
+              COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a "
+                         "texture rectangle could not be created",
+                         tex_pixmap);
+              free_glx_pixmap (ctx, glx_tex_pixmap);
+              return FALSE;
+            }
+        }
+      else
+        {
+          glx_tex_pixmap->glx_tex =
+            _cogl_texture_2d_new_with_size (tex_pixmap->width,
+                                            tex_pixmap->height,
+                                            COGL_TEXTURE_NO_ATLAS,
+                                            texture_format);
+
+          if (glx_tex_pixmap->glx_tex)
+            COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p",
+                       tex_pixmap);
+          else
+            {
+              COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a "
+                         "texture 2d could not be created",
+                         tex_pixmap);
+              free_glx_pixmap (ctx, glx_tex_pixmap);
+              return FALSE;
+            }
+        }
+    }
+
+  if (needs_mipmap)
+    {
+      /* If we can't support mipmapping then temporarily fallback */
+      if (!glx_tex_pixmap->can_mipmap)
+        return FALSE;
+
+      /* Recreate the GLXPixmap if it wasn't previously created with a
+       * mipmap tree */
+      if (!glx_tex_pixmap->has_mipmap_space)
+        {
+          free_glx_pixmap (ctx, glx_tex_pixmap);
+
+          COGL_NOTE (TEXTURE_PIXMAP, "Recreating GLXPixmap with mipmap "
+                     "support for %p", tex_pixmap);
+          if (!try_create_glx_pixmap (ctx, tex_pixmap, TRUE))
+
+            {
+              /* If the pixmap failed then we'll permanently fallback
+               * to using XImage. This shouldn't happen. */
+              COGL_NOTE (TEXTURE_PIXMAP, "Falling back to XGetImage "
+                         "updates for %p because creating the GLXPixmap "
+                         "with mipmap support failed", tex_pixmap);
+
+              if (glx_tex_pixmap->glx_tex)
+                cogl_handle_unref (glx_tex_pixmap->glx_tex);
+              return FALSE;
+            }
+
+          glx_tex_pixmap->bind_tex_image_queued = TRUE;
+        }
+    }
+
+  if (glx_tex_pixmap->bind_tex_image_queued)
+    {
+      GLuint gl_handle, gl_target;
+      CoglRendererXlib *xlib_renderer = ctx->display->renderer->winsys;
+
+      cogl_texture_get_gl_texture (glx_tex_pixmap->glx_tex,
+                                   &gl_handle, &gl_target);
+
+      COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap);
+
+      GE( _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE) );
+
+      if (glx_tex_pixmap->pixmap_bound)
+        glx_renderer->pf_glXReleaseTexImage (xlib_renderer->xdpy,
+                                             glx_tex_pixmap->glx_pixmap,
+                                             GLX_FRONT_LEFT_EXT);
+
+      glx_renderer->pf_glXBindTexImage (xlib_renderer->xdpy,
+                                        glx_tex_pixmap->glx_pixmap,
+                                        GLX_FRONT_LEFT_EXT,
+                                        NULL);
+
+      /* According to the recommended usage in the spec for
+       * GLX_EXT_texture_pixmap we should release the texture after
+       * we've finished drawing with it and it is undefined what
+       * happens if you render to a pixmap that is bound to a texture.
+       * However that would require the texture backend to know when
+       * Cogl has finished painting and it may be more expensive to
+       * keep unbinding the texture. Leaving it bound appears to work
+       * 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;
+
+      _cogl_texture_2d_externally_modified (glx_tex_pixmap->glx_tex);
+    }
+
+  return TRUE;
+}
+
+void
+_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;
+}
+
+CoglHandle
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+{
+  CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
+
+  return glx_tex_pixmap->glx_tex;
+}
diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-private.h b/clutter/cogl/cogl/winsys/cogl-winsys-private.h
index 4f3d494..150f2dc 100644
--- a/clutter/cogl/cogl/winsys/cogl-winsys-private.h
+++ b/clutter/cogl/cogl/winsys/cogl-winsys-private.h
@@ -25,6 +25,9 @@
 #define __COGL_WINSYS_PRIVATE_H
 
 #include "cogl-framebuffer-private.h"
+#ifdef COGL_HAS_XLIB_SUPPORT
+#include "cogl-texture-pixmap-x11-private.h"
+#endif
 
 #ifdef COGL_HAS_XLIB_SUPPORT
 #include <X11/Xutil.h>
@@ -120,4 +123,23 @@ void
 _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
                                                     unsigned int id);
 
+#ifdef COGL_HAS_XLIB_SUPPORT
+gboolean
+_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap);
+
+void
+_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap);
+
+gboolean
+_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                        gboolean needs_mipmap);
+
+void
+_cogl_winsys_texture_pixmap_x11_damage_notify (
+                                            CoglTexturePixmapX11 *tex_pixmap);
+
+CoglHandle
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap);
+#endif
+
 #endif /* __COGL_WINSYS_PRIVATE_H */



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