[cogl/wip/wayland-compositor: 9/18] egl: Add x11 texture-from-pixmap support



commit 567bf666ac48d45934b3c84658ad91e4c3917b87
Author: Robert Bragg <robert linux intel com>
Date:   Tue May 24 23:15:37 2011 +0100

    egl: Add x11 texture-from-pixmap support
    
    By using the EGL_KHR_image_base/pixmap extensions this adds support for
    wrapping X11 pixmaps as CoglTexture2D textures. Clutter will
    automatically take advantage of this if using the
    ClutterX11TexturePixmap actor.

 cogl/cogl-internal.h                            |    3 +-
 cogl/winsys/cogl-winsys-egl-feature-functions.h |    5 +
 cogl/winsys/cogl-winsys-egl.c                   |  127 +++++++++++++++++++++++
 3 files changed, 134 insertions(+), 1 deletions(-)
---
diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h
index 9f197e0..d9619e1 100644
--- a/cogl/cogl-internal.h
+++ b/cogl/cogl-internal.h
@@ -128,7 +128,8 @@ typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
 
 typedef enum
 {
-  COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0
+  COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0,
+  COGL_PRIVATE_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP = 1L<<1
 } CoglPrivateFeatureFlags;
 
 gboolean
diff --git a/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/winsys/cogl-winsys-egl-feature-functions.h
index 410f845..0a7bae0 100644
--- a/cogl/winsys/cogl-winsys-egl-feature-functions.h
+++ b/cogl/winsys/cogl-winsys-egl-feature-functions.h
@@ -68,3 +68,8 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroyImage,
                               (EGLDisplay dpy,
                                EGLImageKHR image))
 COGL_WINSYS_FEATURE_END ()
+COGL_WINSYS_FEATURE_BEGIN (image_pixmap,
+                           "KHR\0",
+                           "image_pixmap\0",
+                           COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP)
+COGL_WINSYS_FEATURE_END ()
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index d2fa23d..857a55a 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -30,6 +30,7 @@
 
 #include "cogl.h"
 
+#include "cogl-winsys-egl-private.h"
 #include "cogl-winsys-private.h"
 #include "cogl-feature-private.h"
 #include "cogl-context-private.h"
@@ -41,6 +42,12 @@
 #include "cogl-renderer-xlib-private.h"
 #include "cogl-display-xlib-private.h"
 #endif
+
+#ifdef COGL_HAS_XLIB_SUPPORT
+#include "cogl-texture-pixmap-x11-private.h"
+#include "cogl-texture-2d-private.h"
+#endif
+
 #include "cogl-private.h"
 
 #ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
@@ -165,6 +172,14 @@ typedef struct _CoglOnscreenEGL
   EGLSurface egl_surface;
 } CoglOnscreenEGL;
 
+#ifdef EGL_KHR_image_pixmap
+typedef struct _CoglTexturePixmapEGL
+{
+  EGLImageKHR image;
+  CoglHandle texture;
+} CoglTexturePixmapEGL;
+#endif
+
 /* Define a set of arrays containing the functions required from GL
    for each winsys feature */
 #define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names,    \
@@ -1517,6 +1532,103 @@ _cogl_winsys_context_egl_get_egl_display (CoglContext *context)
   return egl_renderer->edpy;
 }
 
+#if defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap)
+static gboolean
+_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
+{
+  CoglTexturePixmapEGL *egl_tex_pixmap;
+  EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
+  CoglPixelFormat texture_format;
+
+  /* FIXME: It should be possible to get to a CoglContext from any
+   * CoglTexture pointer. */
+  _COGL_GET_CONTEXT (ctx, FALSE);
+
+  if (!(ctx->private_feature_flags &
+        COGL_PRIVATE_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) ||
+      !(ctx->private_feature_flags &
+        COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE))
+    {
+      tex_pixmap->winsys = NULL;
+      return FALSE;
+    }
+
+  egl_tex_pixmap = g_new0 (CoglTexturePixmapEGL, 1);
+
+  egl_tex_pixmap->image =
+    _cogl_egl_create_image (ctx,
+                            EGL_NATIVE_PIXMAP_KHR,
+                            (EGLClientBuffer)tex_pixmap->pixmap,
+                            attribs);
+  if (egl_tex_pixmap->image == EGL_NO_IMAGE_KHR)
+    return FALSE;
+
+  texture_format = (tex_pixmap->depth >= 32 ?
+                    COGL_PIXEL_FORMAT_RGBA_8888_PRE :
+                    COGL_PIXEL_FORMAT_RGB_888);
+
+  egl_tex_pixmap->texture =
+    _cogl_egl_texture_2d_new_from_image (ctx,
+                                         tex_pixmap->width,
+                                         tex_pixmap->height,
+                                         texture_format,
+                                         egl_tex_pixmap->image,
+                                         NULL);
+
+  tex_pixmap->winsys = egl_tex_pixmap;
+
+  return TRUE;
+}
+
+static void
+_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
+{
+  CoglTexturePixmapEGL *egl_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;
+
+  egl_tex_pixmap = tex_pixmap->winsys;
+
+  if (egl_tex_pixmap->texture)
+    cogl_handle_unref (egl_tex_pixmap->texture);
+
+  if (egl_tex_pixmap->image != EGL_NO_IMAGE_KHR)
+    _cogl_egl_destroy_image (ctx, egl_tex_pixmap->image);
+
+  tex_pixmap->winsys = NULL;
+  g_free (egl_tex_pixmap);
+}
+
+static gboolean
+_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+                                        gboolean needs_mipmap)
+{
+  if (needs_mipmap)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
+{
+}
+
+static CoglHandle
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+{
+  CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys;
+
+  return egl_tex_pixmap->texture;
+}
+#endif /* defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap) */
+
+
 static CoglWinsysVtable _cogl_winsys_vtable =
   {
     .name = "EGL",
@@ -1546,6 +1658,21 @@ static CoglWinsysVtable _cogl_winsys_vtable =
     .onscreen_x11_get_window_xid =
       _cogl_winsys_onscreen_x11_get_window_xid,
 #endif
+#if defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap)
+    /* X11 tfp support... */
+    /* XXX: instead of having a rather monolithic winsys vtable we could
+     * perhaps look for a way to separate these... */
+    .texture_pixmap_x11_create =
+      _cogl_winsys_texture_pixmap_x11_create,
+    .texture_pixmap_x11_free =
+      _cogl_winsys_texture_pixmap_x11_free,
+    .texture_pixmap_x11_update =
+      _cogl_winsys_texture_pixmap_x11_update,
+    .texture_pixmap_x11_damage_notify =
+      _cogl_winsys_texture_pixmap_x11_damage_notify,
+    .texture_pixmap_x11_get_texture =
+      _cogl_winsys_texture_pixmap_x11_get_texture,
+#endif /* defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap) */
   };
 
 /* XXX: we use a function because no doubt someone will complain



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