From 89e26497de8f3f05fbaf409436c4ee92f5d3669c Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 4 Nov 2011 17:44:55 +0000 Subject: [PATCH] Add a CEx100-specific backend Instead of piggybacking on the EGL backend, let's create a small ClutterBackend for the CEx100 platforms. This allows us to handle the CEx100-specific details in a much cleaner way. --- .gitignore | 2 +- clutter/Makefile.am | 11 +- clutter/cex100/clutter-backend-cex100.c | 264 ++++++++++++++++++++ clutter/cex100/clutter-backend-cex100.h | 74 ++++++ clutter/{egl => cex100}/clutter-cex100.h.in | 35 +-- configure.ac | 134 +++++----- 6 files changed, 422 insertions(+), 98 deletions(-) create mode 100644 clutter/cex100/clutter-backend-cex100.c create mode 100644 clutter/cex100/clutter-backend-cex100.h rename clutter/{egl => cex100}/clutter-cex100.h.in (63%) diff --git a/.gitignore b/.gitignore index a9bec3094..8278da8e8 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,7 @@ stamp-marshal /clutter/clutter-version.h /clutter/gcov-report.txt /clutter/clutter-json.h -/clutter/egl/clutter-cex100.h +/clutter/cex100/clutter-cex100.h /build/autotools/*.m4 !/build/autotools/introspection.m4 !/build/autotools/as-linguas.m4 diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 69e8e2e62..86f07f01a 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -547,7 +547,9 @@ evdev_h_priv = \ $(srcdir)/evdev/clutter-input-device-evdev.h \ $(NULL) -cex_h = egl/clutter-cex100.h +cex_source_h_priv = $(srcdir)/cex100/clutter-backend-cex100.h +cex_source_c = $(srcdir)/cex100/clutter-backend-cex100.c +cex_h = cex100/clutter-cex100.h BUILT_SOURCES += $(cex_h) EXTRA_DIST += $(srcdir)/$(cex_h).in @@ -562,7 +564,12 @@ egl_source_h_priv += $(evdev_h_priv) endif # SUPPORT_EVDEV if SUPPORT_CEX100 -egl_source_h += $(cex_h) +backend_source_h += $(cex_h) +backend_source_c += $(cex_source_c) +backend_source_h_priv += $(cex_source_h_priv) + +cluttercex100_includedir = $(clutter_includedir)/cex100 +cluttercex100_include_HEADERS = $(cex_h) clutter-cex100-$(CLUTTER_API_VERSION).pc: clutter-$(CLUTTER_API_VERSION).pc $(QUIET_GEN)cp -f $< $(@F) diff --git a/clutter/cex100/clutter-backend-cex100.c b/clutter/cex100/clutter-backend-cex100.c new file mode 100644 index 000000000..093fb1f54 --- /dev/null +++ b/clutter/cex100/clutter-backend-cex100.c @@ -0,0 +1,264 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2010,2011 Intel Corporation. + * 2011 Giovanni Campagna + * + * 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: + * Matthew Allum + * Emmanuele Bassi + * Robert Bragg + * Neil Roberts + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#include "clutter-backend-eglnative.h" + +/* This is a Cogl based backend */ +#include "cogl/clutter-stage-cogl.h" + +#ifdef HAVE_EVDEV +#include "clutter-device-manager-evdev.h" +#endif + +#include "clutter-debug.h" +#include "clutter-private.h" +#include "clutter-main.h" +#include "clutter-stage-private.h" + +#ifdef COGL_HAS_EGL_SUPPORT +#include "clutter-egl.h" +#endif + +#include "clutter-cex100.h" + +static gdl_plane_id_t gdl_plane = GDL_PLANE_ID_UPP_C; +static guint gdl_n_buffers = CLUTTER_CEX100_TRIPLE_BUFFERING; + +#define clutter_backend_cex100_get_type _clutter_backend_cex100_get_type + +G_DEFINE_TYPE (ClutterBackendCex100, clutter_backend_cex100, CLUTTER_TYPE_BACKEND); + +static ClutterDeviceManager * +clutter_backend_cex100_get_device_manager (ClutterBackend *backend) +{ + ClutterBackendCex100 *backend_cex100 = CLUTTER_BACKEND_CEX100 (backend); + +#ifdef HAVE_EVDEV + if (G_UNLIKELY (backend_cex100->device_manager == NULL)) + { + backend_cex100->device_manager = + g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, + "backend", backend_cex100, + NULL); + } +#endif /* HAVE_EVDEV */ + + return backend_cex100->device_manager; +} + +static void +clutter_backend_cex100_dispose (GObject *gobject) +{ + ClutterBackendCex100 *backend_cex100 = CLUTTER_BACKEND_CEX100 (gobject); + + if (backend_cex100->event_timer != NULL) + { + g_timer_destroy (backend_cex100->event_timer); + backend_cex100->event_timer = NULL; + } + + if (backend_cex100->device_manager != NULL) + { + g_object_unref (backend_cex100->device_manager); + backend_cex100->device_manager = NULL; + } + + G_OBJECT_CLASS (clutter_backend_cex100_parent_class)->dispose (gobject); +} + +static ClutterStageWindow * +clutter_backend_cex100_create_stage (ClutterBackend *backend, + ClutterStage *wrapper, + GError **error) +{ + ClutterBackendCex100 *backend_cex100 = CLUTTER_BACKEND_CEX100 (backend); + ClutterStageWindow *stage; + + if (G_UNLIKELY (backend_cex100->stage != NULL)) + { + g_set_error (error, CLUTTER_INIT_ERROR, + CLUTTER_INIT_ERROR_BACKEND, + "The Cex100 backend does not support multiple " + "onscreen windows"); + return backend_cex100->stage; + } + + stage = g_object_new (CLUTTER_TYPE_STAGE_COGL, + "backend", backend, + "wrapper", wrapper, + NULL); + backend_cex100->stage = stage; + + return stage; +} + +static CoglDisplay * +clutter_backend_cex100_get_display (ClutterBackend *backend, + CoglRenderer *renderer, + CoglSwapChain *swap_chain, + GError **error) +{ + CoglOnscreenTemplate *onscreen_template = NULL; + CoglDisplay *display; + + swap_chain = cogl_swap_chain_new (); + +#if defined(COGL_HAS_GDL_SUPPORT) + cogl_swap_chain_set_length (swap_chain, gdl_n_buffers); +#endif + + onscreen_template = cogl_onscreen_template_new (swap_chain); + + /* XXX: I have some doubts that this is a good design. + * Conceptually should we be able to check an onscreen_template + * without more details about the CoglDisplay configuration? + */ + if (!cogl_renderer_check_onscreen_template (renderer, + onscreen_template, + error)) + goto error; + + display = cogl_display_new (renderer, onscreen_template); + +#if defined(COGL_HAS_GDL_SUPPORT) + cogl_gdl_display_set_plane (cogl_display, gdl_plane); +#endif + + return display; +} + +static void +clutter_backend_cex100_class_init (ClutterBackendCex100Class *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass); + + gobject_class->dispose = clutter_backend_cex100_dispose; + + backend_class->get_device_manager = clutter_backend_cex100_get_device_manager; + backend_class->create_stage = clutter_backend_cex100_create_stage; + backend_class->get_display = clutter_backend_cex100_get_display; +} + +static void +clutter_backend_cex100_init (ClutterBackendCex100 *backend_cex100) +{ + backend_cex100->event_timer = g_timer_new (); +} + +/** + * clutter_cex100_set_plane: + * @plane: a GDL plane + * + * Intel CE3100 and CE4100 have several planes (frame buffers) and a + * hardware blender to blend the planes togeteher and produce the final + * image. + * + * clutter_cex100_set_plane() let's you configure the GDL plane where + * the stage will be drawn. By default Clutter will pick UPP_C + * (GDL_PLANE_ID_UPP_C). + * + * This function has to be called before clutter_init() + * + * Since: 1.6 + */ +void +clutter_cex100_set_plane (gdl_plane_id_t plane) +{ + g_return_if_fail (plane >= GDL_PLANE_ID_UPP_A && plane <= GDL_PLANE_ID_UPP_E); + + gdl_plane = plane; +} + +/** + * clutter_cex100_set_buffering_mode: + * @mode: a #ClutterCex100BufferingMode + * + * Configure the buffering mode of the underlying GDL plane. The GDL + * surface used by Clutter to draw can be backed up by either one or two + * back buffers thus being double or triple buffered, respectively. + * + * Clutter defaults to %CLUTTER_CEX100_TRIPLE_BUFFERING. + * + * This function has to be called before clutter_init() + * + * Since: 1.6 + */ +void +clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode) +{ + g_return_if_fail (mode == CLUTTER_CEX100_DOUBLE_BUFFERING || + mode == CLUTTER_CEX100_TRIPLE_BUFFERING); + + gdl_n_buffers = mode; +} + +/** + * clutter_cex100_get_egl_display: + * + * Retrieves the EGL display used by Clutter, if it supports the + * EGL windowing system and if it is running using an EGL backend. + * + * Return value: the EGL display used by Clutter, or 0 + * + * Since: 1.10 + */ +EGLDisplay +clutter_cex100_get_egl_display (void) +{ + ClutterBackend *backend; + + if (!_clutter_context_is_initialized ()) + { + g_critical ("The Clutter backend has not been initialized yet"); + return 0; + } + + backend = clutter_get_default_backend (); + + if (!CLUTTER_IS_BACKEND_CEX100 (backend)) + { + g_critical ("The Clutter backend is not a CEX100 backend"); + return 0; + } + +#if COGL_HAS_EGL_SUPPORT + return cogl_egl_context_get_egl_display (backend->cogl_context); +#else + return 0; +#endif +} diff --git a/clutter/cex100/clutter-backend-cex100.h b/clutter/cex100/clutter-backend-cex100.h new file mode 100644 index 000000000..b55b89aee --- /dev/null +++ b/clutter/cex100/clutter-backend-cex100.h @@ -0,0 +1,74 @@ +/* Clutter. + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2006, 2007 OpenedHand + * Copyright (C) 2010 Intel Corp + * 2011 Giovanni Campagna + * + * 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: + * Matthew Allum + * Robert Bragg + */ + +#ifndef __CLUTTER_BACKEND_CEX100_H__ +#define __CLUTTER_BACKEND_CEX100_H__ + +#include +#include +#include +#include + +#include "clutter-backend-private.h" + +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_IS_BACKEND_CEX100(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND_CEX100)) +#define CLUTTER_BACKEND_CEX100_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND_CEX100, ClutterBackendCex100Class)) +#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 +{ + ClutterBackend parent_instance; + + /* main stage singleton */ + ClutterStageWindow *stage; + + /* device manager (ie evdev) */ + ClutterDeviceManager *device_manager; + + /* event source */ + GSource *event_source; + + /* event timer */ + GTimer *event_timer; +}; + +struct _ClutterBackendCex100Class +{ + ClutterBackendClass 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-cex100.h.in b/clutter/cex100/clutter-cex100.h.in similarity index 63% rename from clutter/egl/clutter-cex100.h.in rename to clutter/cex100/clutter-cex100.h.in index d6d976da9..cbf7cef16 100644 --- a/clutter/egl/clutter-cex100.h.in +++ b/clutter/cex100/clutter-cex100.h.in @@ -43,28 +43,14 @@ G_BEGIN_DECLS -/** - * clutter_cex100_set_plane: - * @plane: a GDL plane - * - * Intel CE3100 and CE4100 have several planes (frame buffers) and a - * hardware blender to blend the planes togeteher and produce the final - * image. - * - * clutter_cex100_set_plane() let's you configure the GDL plane where - * the stage will be drawn. By default Clutter will pick UPP_C - * (GDL_PLANE_ID_UPP_C). - * - * This function has to be called before clutter_init() - */ -void clutter_cex100_set_plane (gdl_plane_id_t plane); - /** * ClutterCex100BufferingMode: * @CLUTTER_CEX100_DOUBLE_BUFFERING: The GDL plane will be double buffered * @CLUTTER_CEX100_TRIPLE_BUFFERING: The GDL plane will be triple buffered * * Enum passed to clutter_cex100_set_buffering_mode(). + * + * Since: 1.6 */ typedef enum /*< prefix=CLUTTER_CEX100 >*/ { @@ -72,19 +58,10 @@ typedef enum /*< prefix=CLUTTER_CEX100 >*/ CLUTTER_CEX100_TRIPLE_BUFFERING = 3 } ClutterCex100BufferingMode; -/** - * clutter_cex100_set_buffering_mode: - * @mode: a #ClutterCex100BufferingMode - * - * Configure the buffering mode of the underlying GDL plane. The GDL - * surface used by Clutter to draw can be backed up by either one or two - * back buffers thus being double or triple buffered, respectively. - * - * Clutter defaults to %CLUTTER_CEX100_TRIPLE_BUFFERING. - * - * This function has to be called before clutter_init() - */ -void clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode); +void clutter_cex100_set_plane (gdl_plane_id_t plane); +void clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode); + +EGLDisplay clutter_cex100_get_egl_display (void); G_END_DECLS diff --git a/configure.ac b/configure.ac index ea1ad40c7..7ff01ff8b 100644 --- a/configure.ac +++ b/configure.ac @@ -227,6 +227,10 @@ AC_ARG_ENABLE([egl-backend], [AS_HELP_STRING([--enable-egl-backend=@<:@yes/no@:>@], [Enable the EGL framebuffer backend (default=no)])], [enable_egl=$enableval], [enable_egl=no]) +AC_ARG_ENABLE([cex100-backend], + [AS_HELP_STRING([--enable-cex100-backend=@<:@yes/no@:>@], [Enable the CEx100 backend (default=no)])], + [enable_cex100=$enableval], + [enable_cex100=no]) dnl Define default values AS_IF([test "x$enable_x11" = "xcheck"], @@ -313,6 +317,38 @@ AS_IF([test "x$enable_wayland" = "xyes"], AC_DEFINE([HAVE_CLUTTER_WAYLAND], [1], [Have the Wayland backend]) ]) +AS_IF([test "x$enable_cex100" = "xyes"], + [ + CLUTTER_BACKENDS="$CLUTTER_BACKENDS cex100" + + SUPPORT_COGL=1 + SUPPORT_EGL_PLATFORM_GDL=1 + + have_gdl=no + AC_CHECK_HEADERS([libgdl.h], [have_gdl=yes]) + + AS_IF([test "x$have_gdl" = "xno"], + [ + AC_CHECK_HEADERS([CE4100/libgdl.h], + [ + FLAVOUR_CFLAGS="-I/usr/include/CE4100" + have_gdl=yes + CLUTTER_CEX100_LIBGDL_PREFIX=CE4100/ + ]) + ]) + + AS_IF([test "x$have_gdl" = "xno"], + [AC_MSG_ERROR([libgdl.h not found but the CEx100 backend has been explicitly enabled])]) + + AC_SUBST(CLUTTER_CEX100_LIBGDL_PREFIX) + + FLAVOUR_LIBS="$FLAVOUR_LIBS -lgdl" + + AC_DEFINE([CLUTTER_EGL_BACKEND_CEX100], [1], [Use CEX100 EGL backend]) + AC_DEFINE([CLUTTER_EGL_BACKEND_GENERIC], [1], [Use Generic EGL backend]) + AC_DEFINE([HAVE_CLUTTER_EGL], [1], [Have the EGL backend]) + ]) + AS_IF([test "x$enable_egl" = "xyes"], [ CLUTTER_BACKENDS="$CLUTTER_BACKENDS egl" @@ -327,71 +363,6 @@ AS_IF([test "x$enable_egl" = "xyes"], ], []) - AC_ARG_WITH([tslib], - [AS_HELP_STRING([--with-tslib=@<:@yes/no@:>@], [Use TSLib for events (default=no)])], - [], - [with_tslib=no]) - - AC_ARG_WITH([evdev], - [AS_HELP_STRING([--with-evdev=@<:@yes/no@:>@], [Use evdev for events (default=yes)])], - [], - [with_evdev=yes]) - - AC_ARG_WITH([gdl], - [AS_HELP_STRING([--with-gdl=@<:@yes/no@:>@], [Use libgdl for CE3100/CE4100 support (default=no)])], - [], - [with_gdl=no]) - - AS_IF([test "x$with_tslib" = "xyes"], - [ - PKG_CHECK_MODULES(TSLIB, [tslib-1.0], [have_tslib=yes], [have_tslib=no]) - AS_IF([test "x$have_tslib" = "xyes"], - [ - AC_DEFINE([HAVE_TSLIB], [1], [Have tslib for touchscreen handling]) - SUPPORT_TSLIB=1 - ]) - ], - [have_tslib=no]) - - AS_IF([test "x$with_evdev" = "xyes"], - [ - PKG_CHECK_MODULES(EVDEV, [gudev-1.0 xkbcommon], [have_evdev=yes], [have_evdev=no]) - AS_IF([test "x$have_evdev" = "xyes"], - [ - AC_DEFINE([HAVE_EVDEV], [1], [Have evdev support for input handling]) - SUPPORT_EVDEV=1 - ]) - ], - [have_evdev=no]) - - AS_IF([test "x$with_gdl" = "xyes"], - [ - have_gdl=no - - AC_CHECK_HEADERS([libgdl.h], [have_gdl=yes]) - - AS_IF([test "x$have_gdl" = "xno"], - [ - AC_CHECK_HEADERS([CE4100/libgdl.h], - [ - FLAVOUR_CFLAGS="-I/usr/include/CE4100" - have_gdl=yes - CLUTTER_CEX100_LIBGDL_PREFIX=CE4100/ - ]) - ]) - - AC_SUBST(CLUTTER_CEX100_LIBGDL_PREFIX) - - AS_IF([test "x$have_gdl" = "xno"], [AC_MSG_ERROR([libgdl.h not found])]) - - FLAVOUR_LIBS="$FLAVOUR_LIBS -lgdl" - - SUPPORT_EGL_PLATFORM_GDL=1 - - AC_DEFINE([CLUTTER_EGL_BACKEND_CEX100], [1], [Use CEX100 EGL backend]) - ], - [have_gdl=no]) - FLAVOUR_LIBS="$FLAVOUR_LIBS $TSLIB_LIBS $EVDEV_LIBS" FLAVOUR_CFLAGS="$FLAVOUR_CFLAGS $TSLIB_CFLAGS $EVDEV_CFLAGS" @@ -430,6 +401,37 @@ AS_IF([test "x$CLUTTER_BACKENDS" = "x"], AC_MSG_ERROR([No backend enabled. You need to enable at least one backend.]) ]) +# additional input backends + +AC_ARG_ENABLE([tslib-input], + [AS_HELP_STRING([--enable-tslib-input=@<:@yes/no@:>@], [Enable TSLib for input events (default=no)])], + [enable_tslib=$enableval], + [enable_tslib=no]) +AC_ARG_ENABLE([evdev-input], + [AS_HELP_STRING([--with-evdev=@<:@yes/no@:>@], [Enable evdev for input events (default=yes)])], + [enable_evdev=$enableval], + [enable_evdev=yes]) + +AS_IF([test "x$enable_tslib" = "xyes"], + [ + PKG_CHECK_MODULES(TSLIB, [tslib-1.0], [have_tslib=yes], [have_tslib=no]) + AS_IF([test "x$have_tslib" = "xyes"], + [ + AC_DEFINE([HAVE_TSLIB], [1], [Have tslib for touchscreen handling]) + SUPPORT_TSLIB=1 + ]) + ]) + +AS_IF([test "x$enable_evdev" = "xyes"], + [ + PKG_CHECK_MODULES(EVDEV, [gudev-1.0 xkbcommon], [have_evdev=yes], [have_evdev=no]) + AS_IF([test "x$have_evdev" = "xyes"], + [ + AC_DEFINE([HAVE_EVDEV], [1], [Have evdev support for input handling]) + SUPPORT_EVDEV=1 + ]) + ]) + # conditionals for use in automake files... AM_CONDITIONAL(SUPPORT_GLX, [test "x$SUPPORT_GLX" = "x1"]) AM_CONDITIONAL(SUPPORT_X11, [test "x$SUPPORT_X11" = "x1"]) @@ -1001,7 +1003,7 @@ AC_CONFIG_FILES([ clutter/cally/cally-$CLUTTER_API_VERSION.pc:clutter/cally/cally.pc.in - clutter/egl/clutter-cex100.h + clutter/cex100/clutter-cex100.h tests/Makefile tests/accessibility/Makefile