diff --git a/clutter/cogl/cogl/Makefile.am b/clutter/cogl/cogl/Makefile.am
index 696f3a4f7..9ba4e4f2c 100644
--- a/clutter/cogl/cogl/Makefile.am
+++ b/clutter/cogl/cogl/Makefile.am
@@ -206,6 +206,10 @@ if SUPPORT_EGL_PLATFORM_POWERVR_NULL
libclutter_cogl_la_SOURCES += \
$(srcdir)/winsys/cogl-egl.c
endif
+if SUPPORT_EGL_PLATFORM_POWERVR_GDL
+libclutter_cogl_la_SOURCES += \
+ $(srcdir)/winsys/cogl-egl.c
+endif
if SUPPORT_EGL_PLATFORM_FRUITY
libclutter_cogl_la_SOURCES += \
$(srcdir)/winsys/cogl-fruity.c
diff --git a/clutter/egl/Makefile.am b/clutter/egl/Makefile.am
index c3c78422e..0559cc9ca 100644
--- a/clutter/egl/Makefile.am
+++ b/clutter/egl/Makefile.am
@@ -40,3 +40,6 @@ if USE_TSLIB
libclutter_egl_la_SOURCES += clutter-event-tslib.c
endif
+if SUPPORT_CEX100
+libclutter_egl_la_SOURCES += clutter-backend-cex100.c clutter-backend-cex100.h
+endif
diff --git a/clutter/egl/clutter-backend-cex100.c b/clutter/egl/clutter-backend-cex100.c
new file mode 100644
index 000000000..aee9b02b1
--- /dev/null
+++ b/clutter/egl/clutter-backend-cex100.c
@@ -0,0 +1,332 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Authors:
+ * Tao Zhao
+ * Damien Lespiau
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+
+#include "clutter-debug.h"
+#include "clutter-main.h"
+
+#include "clutter-backend-cex100.h"
+
+static gdl_plane_id_t gdl_plane = GDL_PLANE_ID_UPP_C;
+
+G_DEFINE_TYPE (ClutterBackendCex100,
+ clutter_backend_cex100,
+ CLUTTER_TYPE_BACKEND_EGL)
+
+static gboolean
+gdl_plane_init (gdl_display_id_t dpy,
+ gdl_plane_id_t plane,
+ gdl_pixel_format_t pixfmt)
+{
+ gboolean ret = TRUE;
+
+ gdl_color_space_t colorSpace = GDL_COLOR_SPACE_RGB;
+ gdl_rectangle_t dstRect;
+ gdl_display_info_t display_info;
+ gdl_ret_t rc = GDL_SUCCESS;
+
+ if (GDL_DISPLAY_ID_0 != dpy && GDL_DISPLAY_ID_1 != dpy)
+ {
+ g_warning ("Invalid display ID, must be GDL_DISPLAY_ID_0 or "
+ "GDL_DISPLAY_ID_1.");
+ return FALSE;
+ }
+
+ /* Init GDL library */
+ rc = gdl_init (NULL);
+ if (rc != GDL_SUCCESS)
+ {
+ g_warning ("GDL initialize failed. %s", gdl_get_error_string (rc));
+ return FALSE;
+ }
+
+ rc = gdl_get_display_info (dpy, &display_info);
+ if (rc != GDL_SUCCESS)
+ {
+ g_warning ("GDL failed to get display infomation: %s",
+ gdl_get_error_string (rc));
+ gdl_close ();
+ return FALSE;
+ }
+
+ dstRect.origin.x = 0;
+ dstRect.origin.y = 0;
+ dstRect.width = display_info.tvmode.width;
+ dstRect.height = display_info.tvmode.height;
+
+ /* Configure the plane attribute. */
+ rc = gdl_plane_reset (plane);
+ if (rc == GDL_SUCCESS)
+ rc = gdl_plane_config_begin (plane);
+
+ if (rc == GDL_SUCCESS)
+ rc = gdl_plane_set_attr (GDL_PLANE_SRC_COLOR_SPACE, &colorSpace);
+
+ if (rc == GDL_SUCCESS)
+ rc = gdl_plane_set_attr (GDL_PLANE_PIXEL_FORMAT, &pixfmt);
+
+ if (rc == GDL_SUCCESS)
+ rc = gdl_plane_set_attr (GDL_PLANE_DST_RECT, &dstRect);
+
+#if 0
+ /*
+ * Change the number of back buffers for the eglWindowSurface, Default
+ * value is 3, could be changed to 2, means one front buffer and one back
+ * buffer.
+ *
+ * TODO: Make a new API to tune that;
+ */
+ if (rc == GDL_SUCCESS)
+ rc = gdl_plane_set_uint (GDL_PLANE_NUM_GFX_SURFACES, 2);
+#endif
+
+ if (rc == GDL_SUCCESS)
+ rc = gdl_plane_config_end (GDL_FALSE);
+ else
+ gdl_plane_config_end (GDL_TRUE);
+
+ if (rc != GDL_SUCCESS)
+ {
+ g_warning ("GDL configuration failed: %s.", gdl_get_error_string (rc));
+ ret = FALSE;
+ }
+
+ gdl_close ();
+
+ return ret;
+}
+
+/*
+ * ClutterBackendEGL implementation
+ */
+
+static gboolean
+clutter_backend_cex100_create_context (ClutterBackend *backend,
+ GError **error)
+{
+ ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
+ EGLConfig configs[2];
+ EGLint config_count;
+ EGLBoolean status;
+
+ if (backend_egl->egl_context != EGL_NO_CONTEXT)
+ return TRUE;
+
+ /* Start by initializing the GDL plane */
+ if (!gdl_plane_init (GDL_DISPLAY_ID_0, gdl_plane, GDL_PF_ARGB_32))
+ {
+ g_set_error (error, CLUTTER_INIT_ERROR,
+ CLUTTER_INIT_ERROR_BACKEND,
+ "Could not initialize the GDL plane");
+ return FALSE;
+ }
+
+ NativeWindowType window = (NativeWindowType) gdl_plane;
+ EGLint cfg_attribs[] = {
+ EGL_BUFFER_SIZE, EGL_DONT_CARE,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_DEPTH_SIZE, 16,
+ EGL_ALPHA_SIZE, 8,
+ EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
+ EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE,
+#ifdef HAVE_COGL_GLES2
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#else /* HAVE_COGL_GLES2 */
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+#endif /* HAVE_COGL_GLES2 */
+ EGL_NONE
+ };
+
+ status = eglGetConfigs (backend_egl->edpy,
+ configs,
+ 2,
+ &config_count);
+
+ if (status != EGL_TRUE)
+ {
+ g_set_error (error, CLUTTER_INIT_ERROR,
+ CLUTTER_INIT_ERROR_BACKEND,
+ "No EGL configurations found");
+ return FALSE;
+ }
+
+ status = eglChooseConfig (backend_egl->edpy,
+ cfg_attribs,
+ configs,
+ G_N_ELEMENTS (configs),
+ &config_count);
+
+ if (status != EGL_TRUE)
+ {
+ g_set_error (error, CLUTTER_INIT_ERROR,
+ CLUTTER_INIT_ERROR_BACKEND,
+ "Unable to select a valid EGL configuration");
+ return FALSE;
+ }
+
+ CLUTTER_NOTE (BACKEND, "Got %i configs", config_count);
+
+ if (status != EGL_TRUE)
+ {
+ g_set_error (error, CLUTTER_INIT_ERROR,
+ CLUTTER_INIT_ERROR_BACKEND,
+ "Unable to Make Current Context for NULL");
+ return FALSE;
+ }
+
+ if (G_UNLIKELY (backend_egl->egl_surface != EGL_NO_SURFACE))
+ {
+ eglDestroySurface (backend_egl->edpy, backend_egl->egl_surface);
+ backend_egl->egl_surface = EGL_NO_SURFACE;
+ }
+
+ if (G_UNLIKELY (backend_egl->egl_context != NULL))
+ {
+ eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
+ backend_egl->egl_context = NULL;
+ }
+
+ backend_egl->egl_surface = eglCreateWindowSurface (backend_egl->edpy,
+ configs[0],
+ window,
+ NULL);
+
+ if (backend_egl->egl_surface == EGL_NO_SURFACE)
+ {
+ g_set_error (error, CLUTTER_INIT_ERROR,
+ CLUTTER_INIT_ERROR_BACKEND,
+ "Unable to create EGL window surface");
+
+ return FALSE;
+ }
+
+#ifdef HAVE_COGL_GLES2
+ {
+ static const EGLint attribs[3] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
+ configs[0],
+ EGL_NO_CONTEXT,
+ attribs);
+ }
+#else
+ /* Seems some GLES implementations 1.x do not like attribs... */
+ backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
+ configs[0],
+ EGL_NO_CONTEXT,
+ NULL);
+#endif
+
+ if (backend_egl->egl_context == EGL_NO_CONTEXT)
+ {
+ g_set_error (error, CLUTTER_INIT_ERROR,
+ CLUTTER_INIT_ERROR_BACKEND,
+ "Unable to create a suitable EGL context");
+ return FALSE;
+ }
+
+ CLUTTER_NOTE (GL, "Created EGL Context");
+
+ CLUTTER_NOTE (BACKEND, "Setting context");
+
+ /*
+ * eglnative can have only one stage, so we store the EGL surface in the
+ * backend itself, instead of the StageWindow implementation, and we make it
+ * current immediately to make sure the Cogl and Clutter can query the EGL
+ * context for features.
+ */
+ status = eglMakeCurrent (backend_egl->edpy,
+ backend_egl->egl_surface,
+ backend_egl->egl_surface,
+ backend_egl->egl_context);
+
+ eglQuerySurface (backend_egl->edpy,
+ backend_egl->egl_surface,
+ EGL_WIDTH,
+ &backend_egl->surface_width);
+
+ eglQuerySurface (backend_egl->edpy,
+ backend_egl->egl_surface,
+ EGL_HEIGHT,
+ &backend_egl->surface_height);
+
+ CLUTTER_NOTE (BACKEND, "EGL surface is %ix%i",
+ backend_egl->surface_width,
+ backend_egl->surface_height);
+
+ /*
+ * For EGL backend, it needs to clear all the back buffers of the window
+ * surface before drawing anything, otherwise the image will be blinking
+ * heavily. The default eglWindowSurface has 3 gdl surfaces as the back
+ * buffer, that's why glClear should be called 3 times.
+ */
+ glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
+ glClear (GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers (backend_egl->edpy, backend_egl->egl_surface);
+
+ glClear (GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers (backend_egl->edpy, backend_egl->egl_surface);
+
+ glClear (GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers (backend_egl->edpy, backend_egl->egl_surface);
+
+ return TRUE;
+}
+
+/*
+ * GObject implementation
+ */
+
+static void
+clutter_backend_cex100_class_init (ClutterBackendCex100Class *klass)
+{
+ ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
+
+ backend_class->create_context = clutter_backend_cex100_create_context;
+}
+
+static void
+clutter_backend_cex100_init (ClutterBackendCex100 *self)
+{
+}
+
+/* every backend must implement this function */
+GType
+_clutter_backend_impl_get_type (void)
+{
+ return clutter_backend_cex100_get_type ();
+}
diff --git a/clutter/egl/clutter-backend-cex100.h b/clutter/egl/clutter-backend-cex100.h
new file mode 100644
index 000000000..79e03d0e5
--- /dev/null
+++ b/clutter/egl/clutter-backend-cex100.h
@@ -0,0 +1,60 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Author:
+ * Damien Lespiau
+ */
+
+#ifndef __CLUTTER_BACKEND_CEX100_H__
+#define __CLUTTER_BACKEND_CEX100_H__
+
+#include
+
+#include
+
+#include
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_BACKEND_CEX100 (clutter_backend_cex100_get_type())
+#define CLUTTER_BACKEND_CEX100(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND_CEX100, ClutterBackendCex100))
+#define CLUTTER_BACKEND_CEX100_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND_CEX100, ClutterBackendCex100Class))
+#define CLUTTER_IS_BACKEND_CEX100(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND_CEX100))
+#define CLUTTER_IS_BACKEND_CEX100_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND_CEX100))
+#define CLUTTER_BACKEND_CEX100_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND_CEX100, ClutterBackendCex100Class))
+
+typedef struct _ClutterBackendCex100 ClutterBackendCex100;
+typedef struct _ClutterBackendCex100Class ClutterBackendCex100Class;
+
+struct _ClutterBackendCex100
+{
+ ClutterBackendEGL parent;
+};
+
+struct _ClutterBackendCex100Class
+{
+ ClutterBackendEGLClass parent_class;
+};
+
+GType clutter_backend_cex100_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __CLUTTER_BACKEND_CEX100_H__ */
diff --git a/clutter/egl/clutter-backend-egl.c b/clutter/egl/clutter-backend-egl.c
index d5e8ad542..dafa6851d 100644
--- a/clutter/egl/clutter-backend-egl.c
+++ b/clutter/egl/clutter-backend-egl.c
@@ -780,11 +780,13 @@ _clutter_backend_egl_init (ClutterBackendEGL *backend_egl)
#endif
}
+#ifdef CLUTTER_EGL_BACKEND_GENERIC
GType
_clutter_backend_impl_get_type (void)
{
return _clutter_backend_egl_get_type ();
}
+#endif
#ifdef COGL_HAS_XLIB_SUPPORT
EGLDisplay
diff --git a/configure.ac b/configure.ac
index 6465596e2..5b241a583 100644
--- a/configure.ac
+++ b/configure.ac
@@ -138,7 +138,7 @@ experimental_backend=no
experimental_image=no
AC_ARG_WITH([flavour],
- [AC_HELP_STRING([--with-flavour=@<:@glx/opengl-egl-xlib/eglx/eglnative/osx/win32/fruity@:>@],
+ [AC_HELP_STRING([--with-flavour=@<:@glx/opengl-egl-xlib/eglx/eglnative/osx/win32/fruity/cex100@:>@],
[Select the Clutter window system backend])],
[CLUTTER_FLAVOUR=$with_flavour])
@@ -194,6 +194,7 @@ AS_CASE([$CLUTTER_FLAVOUR],
[
cogl_gl_headers="GL/gl.h"
CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGL"
+ CLUTTER_EGL_BACKEND="generic"
SUPPORT_X11=1
SUPPORT_XLIB=1
@@ -217,6 +218,7 @@ AS_CASE([$CLUTTER_FLAVOUR],
[
# the GL header is defined in the COGL checks above
CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGL"
+ CLUTTER_EGL_BACKEND="generic"
SUPPORT_X11=1
SUPPORT_XLIB=1
@@ -235,6 +237,7 @@ AS_CASE([$CLUTTER_FLAVOUR],
[
# the GL header is defined in the COGL checks above
CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGLNATIVE"
+ CLUTTER_EGL_BACKEND="cex100"
SUPPORT_EGL=1
SUPPORT_EGL_PLATFORM_POWERVR_NULL=1
@@ -253,6 +256,35 @@ AS_CASE([$CLUTTER_FLAVOUR],
CLUTTER_SONAME_INFIX=eglnative
],
+ [cex100],
+ [
+ CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGL"
+
+ SUPPORT_EGL=1
+ SUPPORT_EGL_PLATFORM_POWERVR_GDL=1
+
+ COGL_DRIVER="gles"
+
+ # The cex100 is a small specialization of the EGL backend
+ CLUTTER_WINSYS=egl
+ CLUTTER_SONAME_INFIX=cex100
+
+ found_gdl=no
+ AC_CHECK_HEADERS([libgdl.h], found_gdl=yes)
+ AS_IF([test x"$found_gdl" = "xno"],
+ AC_CHECK_HEADERS([CE4100/libgdl.h],
+ [
+ FLAVOUR_CFLAGS="-I/usr/include/CE4100"
+ found_gdl=yes
+ ])
+ )
+
+ AS_IF([test x"$found_gdl" = "xno"],
+ AC_MSG_ERROR([libgdl.h not found]))
+
+ FLAVOUR_LIBS="$FLAVOUR_LIBS -lgdl"
+ ],
+
[fruity],
[
experimental_backend="yes"
@@ -343,6 +375,12 @@ AS_IF([test "x$SUPPORT_EGL" = "x1"],
AC_DEFINE([COGL_HAS_EGL_SUPPORT], [1], [Cogl supports GLES using the EGL API])
])
+AS_IF([test "x$CLUTTER_EGL_BACKEND" = "xgeneric"],
+ AC_DEFINE([CLUTTER_EGL_BACKEND_GENERIC], [1], [Use Generic EGL backend]))
+
+AS_IF([test "x$CLUTTER_EGL_BACKEND" = "xcex100"],
+ AC_DEFINE([CLUTTER_EGL_BACKEND_CEX100], [1], [Use CEX100 EGL backend]))
+
AS_IF([test "x$SUPPORT_EGL_POWERVR_X11" = "x1"],
[
AC_DEFINE([COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT], [1],
@@ -355,6 +393,13 @@ AS_IF([test "x$SUPPORT_EGL_POWERVR_NULL" = "x1"],
[Cogl supports OpenGLES using the EGL API with PowerVR NULL platform typedefs])
])
+AS_IF([test "x$SUPPORT_EGL_POWERVR_GDL" = "x1"],
+ [
+ AC_DEFINE([COGL_HAS_EGL_PLATFORM_POWERVR_GDL_SUPPORT], [1],
+ [Cogl supports OpenGLES using the EGL API with PowerVR GDL platform typedefs])
+ ])
+
+
# winsys conditionals for use in automake files...
AM_CONDITIONAL(SUPPORT_GLX, [test "x$SUPPORT_GLX" = "x1"])
AM_CONDITIONAL(SUPPORT_X11, [test "x$SUPPORT_X11" = "x1"])
@@ -362,9 +407,11 @@ AM_CONDITIONAL(SUPPORT_XLIB, [test "x$SUPPORT_XLIB" = "x1"])
AM_CONDITIONAL(SUPPORT_EGL, [test "x$SUPPORT_EGL" = "x1"])
AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_POWERVR_X11, [test "x$SUPPORT_EGL_PLATFORM_POWERVR_X11" = "x1"])
AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_POWERVR_NULL, [test "x$SUPPORT_EGL_PLATFORM_POWERVR_NULL" = "x1"])
+AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_POWERVR_GDL, [test "x$SUPPORT_EGL_PLATFORM_POWERVR_GDL" = "x1"])
AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_FRUITY, [test "x$CLUTTER_WINSYS" = "xfruity"])
AM_CONDITIONAL(SUPPORT_OSX, [test "x$CLUTTER_WINSYS" = "xosx"])
AM_CONDITIONAL(SUPPORT_WIN32, [test "x$CLUTTER_WINSYS" = "xwin32"])
+AM_CONDITIONAL(SUPPORT_CEX100, [test "x$SUPPORT_EGL_PLATFORM_POWERVR_GDL" = "x1"])
dnl === COGL driver backend =====================================================