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.
This commit is contained in:
Robert Bragg 2011-05-25 01:37:56 +01:00
parent 8714d99300
commit a29a76dbab
9 changed files with 169 additions and 2 deletions

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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

View File

@ -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)
{

View File

@ -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 */

View File

@ -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 ()

View File

@ -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;

View File

@ -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}"