[cogl] Adds _cogl_wayland_texture_2d_new_from_buffer API



commit a29a76dbabf8e68febc50288465fccdfd8d1313f
Author: Robert Bragg <robert linux intel com>
Date:   Wed May 25 01:37:56 2011 +0100

    Adds  _cogl_wayland_texture_2d_new_from_buffer API
    
    This adds internal API to be able to wrap a wayland buffer as a
    CoglTexture2D. There is a --enable-wayland-egl-server option to decide
    if Cogl should support this feature and potentially any EGL based winsys
    could support this through the EGL_KHR_image_base and
    EGL_WL_bind_display extensions.

 cogl/cogl-display-private.h                     |    7 ++
 cogl/cogl-display.c                             |   10 +++
 cogl/cogl-display.h                             |    6 ++
 cogl/cogl-internal.h                            |    5 +-
 cogl/cogl-texture-2d.c                          |   69 +++++++++++++++++++++++
 cogl/cogl-texture-2d.h                          |   35 ++++++++++++
 cogl/winsys/cogl-winsys-egl-feature-functions.h |   11 ++++
 cogl/winsys/cogl-winsys-egl.c                   |   12 ++++
 configure.ac                                    |   16 +++++
 9 files changed, 169 insertions(+), 2 deletions(-)
---
diff --git a/cogl/cogl-display-private.h b/cogl/cogl-display-private.h
index 964dfb6..2411855 100644
--- a/cogl/cogl-display-private.h
+++ b/cogl/cogl-display-private.h
@@ -29,6 +29,9 @@
 #include "cogl-display.h"
 #include "cogl-renderer.h"
 #include "cogl-onscreen-template.h"
+#if COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+#include <wayland-server.h>
+#endif
 
 struct _CoglDisplay
 {
@@ -38,6 +41,10 @@ struct _CoglDisplay
   CoglRenderer *renderer;
   CoglOnscreenTemplate *onscreen_template;
 
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+  struct wl_display *wayland_compositor_display;
+#endif
+
 #ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
   struct gdl_plane *gdl_plane;
 #endif
diff --git a/cogl/cogl-display.c b/cogl/cogl-display.c
index 967c070..aea9d8d 100644
--- a/cogl/cogl-display.c
+++ b/cogl/cogl-display.c
@@ -129,3 +129,13 @@ cogl_gdl_display_set_plane (CoglDisplay *display,
 }
 #endif
 
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+void
+cogl_wayland_display_set_compositor_display (CoglDisplay *display,
+                                             struct wl_display *wayland_display)
+{
+  g_return_if_fail (display->setup == FALSE);
+
+  display->wayland_compositor_display = wayland_display;
+}
+#endif
diff --git a/cogl/cogl-display.h b/cogl/cogl-display.h
index 720b86b..b12041b 100644
--- a/cogl/cogl-display.h
+++ b/cogl/cogl-display.h
@@ -94,6 +94,12 @@ cogl_gdl_display_set_plane (CoglDisplay *display,
                             struct gdl_plane *plane);
 #endif
 
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+void
+cogl_wayland_display_set_compositor_display (CoglDisplay *display,
+                                          struct wl_display *wayland_display);
+#endif
+
 G_END_DECLS
 
 #endif /* __COGL_DISPLAY_H__ */
diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h
index d9619e1..a1bb400 100644
--- a/cogl/cogl-internal.h
+++ b/cogl/cogl-internal.h
@@ -128,8 +128,9 @@ typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
 
 typedef enum
 {
-  COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0,
-  COGL_PRIVATE_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP = 1L<<1
+  COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE     = 1L<<0,
+  COGL_PRIVATE_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP     = 1L<<1,
+  COGL_PRIVATE_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER = 1L<<2
 } CoglPrivateFeatureFlags;
 
 gboolean
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 9f2e550..57a193a 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -44,6 +44,10 @@
 #include <string.h>
 #include <math.h>
 
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+#include <wayland-server.h>
+#endif
+
 static void _cogl_texture_2d_free (CoglTexture2D *tex_2d);
 
 COGL_TEXTURE_DEFINE (Texture2D, texture_2d);
@@ -541,6 +545,71 @@ _cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
 }
 #endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */
 
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+static CoglPixelFormat
+get_buffer_format (struct wl_buffer *buffer)
+{
+  struct wl_compositor *compositor = buffer->compositor;
+  struct wl_visual *visual = buffer->visual;
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+  if (visual == &compositor->premultiplied_argb_visual)
+    return COGL_PIXEL_FORMAT_ARGB_8888_PRE;
+  else if (visual == &compositor->argb_visual)
+    return COGL_PIXEL_FORMAT_ARGB_8888;
+  else if (visual == &compositor->rgb_visual)
+    return COGL_PIXEL_FORMAT_RGB_888;
+#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
+  if (visual == &compositor->premultiplied_argb_visual)
+    return COGL_PIXEL_FORMAT_BGRA_8888_PRE;
+  else if (visual == &compositor->argb_visual)
+    return COGL_PIXEL_FORMAT_BGRA_8888;
+  else if (visual == &compositor->rgb_visual)
+    return COGL_PIXEL_FORMAT_BGR_888;
+#endif
+  else
+    g_return_val_if_reached (COGL_PIXEL_FORMAT_ANY);
+}
+
+CoglTexture2D *
+cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
+                                         struct wl_buffer *buffer,
+                                         GError **error)
+{
+  CoglPixelFormat format = get_buffer_format (buffer);
+
+  if (wl_buffer_is_shm (buffer))
+    {
+      int stride = wl_shm_buffer_get_stride (buffer);
+      return cogl_texture_2d_new_from_data (ctx,
+                                            buffer->width,
+                                            buffer->height,
+                                            format,
+                                            COGL_PIXEL_FORMAT_ANY,
+                                            stride,
+                                            wl_shm_buffer_get_data (buffer),
+                                            error);
+    }
+  else
+    {
+      EGLImageKHR image;
+
+      g_return_val_if_fail (_cogl_context_get_winsys (ctx) ==
+                            _cogl_winsys_egl_get_vtable (),
+                            NULL);
+      image = _cogl_egl_create_image (ctx,
+                                      EGL_WAYLAND_BUFFER_WL,
+                                      buffer,
+                                      NULL);
+      return _cogl_egl_texture_2d_new_from_image (ctx,
+                                                  buffer->width,
+                                                  buffer->height,
+                                                  format,
+                                                  image,
+                                                  error);
+    }
+}
+#endif /* COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT */
+
 void
 _cogl_texture_2d_externally_modified (CoglHandle handle)
 {
diff --git a/cogl/cogl-texture-2d.h b/cogl/cogl-texture-2d.h
index 1883cad..be9a08c 100644
--- a/cogl/cogl-texture-2d.h
+++ b/cogl/cogl-texture-2d.h
@@ -27,6 +27,10 @@
 #ifndef __COGL_TEXURE_2D_H
 #define __COGL_TEXURE_2D_H
 
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+#include <wayland-server.h>
+#endif
+
 #include <glib.h>
 
 G_BEGIN_DECLS
@@ -179,6 +183,37 @@ cogl_texture_2d_new_from_foreign (CoglContext *ctx,
                                   CoglPixelFormat format,
                                   GError **error);
 
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+/**
+ * cogl_wayland_texture_2d_new_from_buffer:
+ * @ctx: A #CoglContext
+ * @buffer: A Wayland buffer
+ * @error: A #GError for exceptions
+ *
+ * Uploads the given Wayland @buffer to a #CoglTexture2D.
+ *
+ * <note>The results are undefined for passing an invalid @buffer
+ * pointer</note>
+ * <note>It is undefined if future updates to @buffer outside the
+ * control of Cogl will affect the allocated #CoglTexture2D. In some
+ * cases the contents of the buffer are copied (such as shm buffers),
+ * and in other cases the underlying storage is re-used directly (such
+ * as drm buffers)</note>
+ *
+ * Returns: A newly allocated #CoglTexture2D, or if Cogl could not
+ *          validate the @buffer in some way (perhaps because of
+ *          an unsupported format) it will return %NULL and set
+ *          @error.
+ * Since: 2.0
+ */
+#define cogl_wayland_texture_2d_new_from_buffer \
+  cogl_wayland_texture_2d_new_from_buffer_EXP
+CoglTexture2D *
+cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
+                                         struct wl_buffer *buffer,
+                                         GError **error);
+#endif /* COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT */
+
 G_END_DECLS
 
 #endif /* __COGL_TEXURE_2D_H */
diff --git a/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/winsys/cogl-winsys-egl-feature-functions.h
index 0a7bae0..7967563 100644
--- a/cogl/winsys/cogl-winsys-egl-feature-functions.h
+++ b/cogl/winsys/cogl-winsys-egl-feature-functions.h
@@ -73,3 +73,14 @@ COGL_WINSYS_FEATURE_BEGIN (image_pixmap,
                            "image_pixmap\0",
                            COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP)
 COGL_WINSYS_FEATURE_END ()
+COGL_WINSYS_FEATURE_BEGIN (bind_wayland_display,
+                           "WL\0",
+                           "bind_wayland_display\0",
+                           COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER)
+COGL_WINSYS_FEATURE_FUNCTION (EGLImageKHR, eglBindWaylandDisplay,
+                              (EGLDisplay dpy,
+                               struct wl_display *wayland_display))
+COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglUnbindWaylandDisplay,
+                              (EGLDisplay dpy,
+                               struct wl_display *wayland_display))
+COGL_WINSYS_FEATURE_END ()
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index 857a55a..86a560b 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -1065,6 +1065,9 @@ _cogl_winsys_display_setup (CoglDisplay *display,
                             GError **error)
 {
   CoglDisplayEGL *egl_display;
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+  CoglRendererEGL *egl_renderer = display->renderer->winsys;
+#endif
 
   g_return_val_if_fail (display->winsys == NULL, FALSE);
 
@@ -1076,6 +1079,15 @@ _cogl_winsys_display_setup (CoglDisplay *display,
     goto error;
 #endif
 
+#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
+  if (display->wayland_compositor_display)
+    {
+      struct wl_display *wayland_display = display->wayland_compositor_display;
+      egl_renderer->pf_eglBindWaylandDisplay (egl_renderer->edpy,
+                                              wayland_display);
+    }
+#endif
+
   if (!create_context (display, error))
     goto error;
 
diff --git a/configure.ac b/configure.ac
index 4a201d2..ad27450 100644
--- a/configure.ac
+++ b/configure.ac
@@ -614,6 +614,21 @@ AS_IF([test "x$enable_wayland_egl_platform" == "xyes"],
 AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_WAYLAND,
                [test "x$enable_wayland_egl_platform" = "xyes"])
 
+AC_ARG_ENABLE(
+  [wayland-egl-server],
+  [AC_HELP_STRING([--enable-wayland-egl-server=@<:@no/yes@:>@], [Enable server side wayland support @<:@default=no@:>@])],
+  [],
+  enable_wayland_egl_server=no
+)
+AS_IF([test "x$enable_wayland_egl_server" == "xyes"],
+      [
+        NEED_EGL=yes
+        COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES wayland-server"
+        COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT"
+      ])
+AM_CONDITIONAL(SUPPORT_WAYLAND_EGL_SERVER,
+               [test "x$enable_wayland_egl_server" = "xyes"])
+
 dnl Android EGL platform
 AC_ARG_ENABLE(
   [android-egl-platform],
@@ -875,6 +890,7 @@ echo "        Driver: ${COGL_DRIVER} ${glesversion}"
 echo "        GL Window System APIs:${GL_WINSYS_APIS}"
 if test "x$SUPPORT_EGL" = "xyes"; then
 echo "        EGL Platforms:${EGL_PLATFORMS}"
+echo "        Wayland compositor support: ${enable_wayland_egl_server}"
 fi
 echo "        Image backend: ${COGL_IMAGE_BACKEND}"
 echo "        Cogl Pango: ${enable_cogl_pango}"



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