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.
This commit is contained in:
Emmanuele Bassi 2011-11-04 17:44:55 +00:00
parent 5c9cafb411
commit 89e26497de
6 changed files with 422 additions and 98 deletions

2
.gitignore vendored
View File

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

View File

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

View File

@ -0,0 +1,264 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010,2011 Intel Corporation.
* 2011 Giovanni Campagna <scampa.giovanni@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
* Authors:
* Matthew Allum
* Emmanuele Bassi
* Robert Bragg
* Neil Roberts
*/
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#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).
*
* <note>This function has to be called before clutter_init()</note>
*
* 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.
*
* <note>This function has to be called before clutter_init()</note>
*
* 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
}

View File

@ -0,0 +1,74 @@
/* Clutter.
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2006, 2007 OpenedHand
* Copyright (C) 2010 Intel Corp
* 2011 Giovanni Campagna <scampa.giovanni@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
* Authors:
* Matthew Allum
* Robert Bragg
*/
#ifndef __CLUTTER_BACKEND_CEX100_H__
#define __CLUTTER_BACKEND_CEX100_H__
#include <glib-object.h>
#include <clutter/clutter-event.h>
#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
#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__ */

View File

@ -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).
*
* <note>This function has to be called before clutter_init()</note>
*/
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.
*
* <note>This function has to be called before clutter_init()</note>
*/
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

View File

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