Moves all EGL code down from Clutter to Cogl
authorRobert Bragg <robert@linux.intel.com>
Fri, 25 Feb 2011 00:31:41 +0000 (00:31 +0000)
committerRobert Bragg <robert@linux.intel.com>
Thu, 5 May 2011 13:46:01 +0000 (14:46 +0100)
As was recently done for the GLX window system code, this commit moves
the EGL window system code down from the Clutter backend code into a
Cogl winsys.

Note: currently the cogl/configure.ac is hard coded to only build the GLX
winsys so currently this is only available when building Cogl as part
of Clutter.

17 files changed:
clutter/Makefile.am
clutter/cogl/cogl/Makefile.am
clutter/cogl/cogl/cogl-context.c
clutter/cogl/cogl/cogl-context.h
clutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h [new file with mode: 0644]
clutter/cogl/cogl/winsys/cogl-winsys-egl.c
clutter/cogl/cogl/winsys/cogl-winsys-private.h
clutter/egl/clutter-backend-cex100.c [deleted file]
clutter/egl/clutter-backend-cex100.h [deleted file]
clutter/egl/clutter-backend-egl.c
clutter/egl/clutter-backend-egl.h
clutter/egl/clutter-stage-egl.c
clutter/egl/clutter-stage-egl.h
clutter/glx/clutter-backend-glx.h
clutter/x11/clutter-stage-x11.c
clutter/x11/clutter-stage-x11.h
configure.ac

index 480474d..d171178 100644 (file)
@@ -471,8 +471,6 @@ evdev_h_priv = \
        $(srcdir)/evdev/clutter-input-device-evdev.h    \
        $(NULL)
 
-egl_cex_c_priv = $(srcdir)/egl/clutter-backend-cex100.c
-egl_cex_h_priv = $(srcdir)/egl/clutter-backend-cex100.h
 egl_cex_h = $(srcdir)/egl/clutter-cex100.h
 
 if SUPPORT_EGL
@@ -487,8 +485,6 @@ egl_source_h_priv += $(evdev_h_priv)
 endif # SUPPORT_EVDEV
 
 if SUPPORT_CEX100
-egl_source_c_priv += $(egl_cex_c_priv)
-egl_source_h_priv += $(egl_cex_h_priv)
 egl_source_h += $(egl_cex_h)
 endif # SUPPORT_CEX100
 
index 426b59a..335f21d 100644 (file)
@@ -332,18 +332,15 @@ cogl_sources_c += \
 endif
 if SUPPORT_EGL_PLATFORM_POWERVR_X11
 cogl_sources_c += \
-       $(srcdir)/winsys/cogl-winsys-egl.c \
-       $(srcdir)/winsys/cogl-winsys-stub.c
+       $(srcdir)/winsys/cogl-winsys-egl.c
 endif
 if SUPPORT_EGL_PLATFORM_POWERVR_NULL
 cogl_sources_c += \
-       $(srcdir)/winsys/cogl-winsys-egl.c \
-       $(srcdir)/winsys/cogl-winsys-stub.c
+       $(srcdir)/winsys/cogl-winsys-egl.c
 endif
 if SUPPORT_EGL_PLATFORM_POWERVR_GDL
 cogl_sources_c += \
-       $(srcdir)/winsys/cogl-winsys-egl.c \
-       $(srcdir)/winsys/cogl-winsys-stub.c
+       $(srcdir)/winsys/cogl-winsys-egl.c
 endif
 if SUPPORT_WIN32
 cogl_sources_c += \
index ac76d4f..e1b18f6 100644 (file)
@@ -475,3 +475,12 @@ cogl_set_default_context (CoglContext *context)
     cogl_object_unref (_context);
   _context = context;
 }
+
+#ifdef COGL_HAS_EGL_SUPPORT
+EGLDisplay
+cogl_context_egl_get_egl_display (CoglContext *context)
+{
+  return _cogl_winsys_context_egl_get_egl_display (context);
+}
+#endif
+
index 9394fbf..7cd0785 100644 (file)
 
 #include <cogl/cogl-display.h>
 
+#ifdef COGL_HAS_EGL_SUPPORT
+#ifdef COGL_HAS_GLES1
+#include <GLES/gl.h>
+#include <GLES/egl.h>
+#else
+#include <EGL/egl.h>
+#define NativeDisplayType EGLNativeDisplayType
+#define NativeWindowType EGLNativeWindowType
+#endif
+#endif
+
 G_BEGIN_DECLS
 
 /**
@@ -61,6 +72,12 @@ cogl_context_new (CoglDisplay *display,
 void
 cogl_set_default_context (CoglContext *context);
 
+#ifdef COGL_HAS_EGL_SUPPORT
+#define cogl_context_egl_get_egl_display cogl_context_egl_get_egl_display_EXP
+EGLDisplay
+cogl_context_egl_get_egl_display (CoglContext *context);
+#endif
+
 G_END_DECLS
 
 #endif /* __COGL_CONTEXT_H__ */
diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h b/clutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h
new file mode 100644 (file)
index 0000000..58c0734
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * 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
+ * <http://www.gnu.org/licenses/>.
+ *
+ *
+ */
+
+/* This can be included multiple times with different definitions for
+ * the COGL_WINSYS_FEATURE_* functions.
+ */
+
+/* Macro prototypes:
+ * COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names,
+ *                            implied_public_feature_flags,
+ *                            implied_private_feature_flags,
+ *                            implied_winsys_feature)
+ * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name,
+ *                               (arguments))
+ * ...
+ * COGL_WINSYS_FEATURE_END ()
+ *
+ * Note: You can list multiple namespace and extension names if the
+ * corresponding _FEATURE_FUNCTIONS have the same semantics accross
+ * the different extension variants.
+ *
+ * XXX: NB: Don't add a trailing semicolon when using these macros
+ */
+
+COGL_WINSYS_FEATURE_BEGIN (swap_region,
+                           "NOK\0",
+                           "swap_region\0",
+                           0,
+                           0,
+                           COGL_WINSYS_FEATURE_SWAP_REGION)
+COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersRegion,
+                              (EGLDisplay dpy,
+                               EGLSurface surface,
+                               EGLint numRects,
+                               const EGLint *rects))
+COGL_WINSYS_FEATURE_END ()
index bafafc0..b6446dc 100644 (file)
@@ -3,7 +3,7 @@
  *
  * An object oriented GL/GLES Abstraction/Utility Layer
  *
- * Copyright (C) 2007,2008,2009 Intel Corporation.
+ * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * 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/>.
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
  *
  *
+ * Authors:
+ *   Robert Bragg <robert@linux.intel.com>
  */
 
 #ifdef HAVE_CONFIG_H
 
 #include "cogl.h"
 
-#ifdef HAVE_STANDALONE_EGL
+#include "cogl-winsys-private.h"
+#include "cogl-feature-private.h"
+#include "cogl-context-private.h"
+#include "cogl-framebuffer.h"
+#include "cogl-swap-chain-private.h"
+#include "cogl-renderer-private.h"
+#include "cogl-onscreen-template-private.h"
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+#include "cogl-renderer-xlib-private.h"
+#include "cogl-display-xlib-private.h"
+#endif
+#include "cogl-private.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <glib/gi18n-lib.h>
+
+#ifdef COGL_HAS_GLES1
+
+#include <GLES/gl.h>
+#include <GLES/egl.h>
+
+#else
+
 #include <EGL/egl.h>
-#include <EGL/eglext.h>
 #define NativeDisplayType EGLNativeDisplayType
 #define NativeWindowType EGLNativeWindowType
+
+#endif
+
+
+#include <EGL/egl.h>
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+#include <X11/Xlib.h>
+#endif
+
+typedef struct _CoglRendererEGL
+{
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  CoglRendererXlib _parent;
+#endif
+
+  EGLDisplay edpy;
+
+  EGLint egl_version_major;
+  EGLint egl_version_minor;
+
+  /* Function pointers for GLX specific extensions */
+#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f)
+
+#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
+  ret (APIENTRY * pf_ ## name) args;
+
+#define COGL_WINSYS_FEATURE_END()
+
+#include "cogl-winsys-egl-feature-functions.h"
+
+#undef COGL_WINSYS_FEATURE_BEGIN
+#undef COGL_WINSYS_FEATURE_FUNCTION
+#undef COGL_WINSYS_FEATURE_END
+} CoglRendererEGL;
+
+typedef struct _CoglDisplayEGL
+{
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  CoglDisplayXlib _parent;
+#endif
+
+  EGLContext egl_context;
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  EGLSurface dummy_surface;
+#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
+  EGLSurface egl_surface;
+  int egl_surface_width;
+  int egl_surface_height;
+  gboolean have_onscreen;
 #else
-#include <GLES/egl.h>
-#include <GLES/eglext.h>
+#error "Unknown EGL platform"
 #endif
 
+  EGLConfig egl_config;
+  gboolean found_egl_config;
+} CoglDisplayEGL;
+
+typedef struct _CoglContextEGL
+{
+  EGLSurface current_surface;
+} CoglContextEGL;
+
+typedef struct _CoglOnscreenXlib
+{
+  Window xwin;
+  gboolean is_foreign_xwin;
+} CoglOnscreenXlib;
+
+typedef struct _CoglOnscreenEGL
+{
+  CoglOnscreenXlib _parent;
+  EGLSurface egl_surface;
+} CoglOnscreenEGL;
+
+/* Define a set of arrays containing the functions required from GL
+   for each winsys feature */
+#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names,    \
+                                  feature_flags, feature_flags_private, \
+                                  winsys_feature)                       \
+  static const CoglFeatureFunction                                      \
+  cogl_egl_feature_ ## name ## _funcs[] = {
+#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args)                   \
+  { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglRendererEGL, pf_ ## name) },
+#define COGL_WINSYS_FEATURE_END()               \
+  { NULL, 0 },                                  \
+    };
+#include "cogl-winsys-egl-feature-functions.h"
+
+/* Define an array of features */
+#undef COGL_WINSYS_FEATURE_BEGIN
+#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names,    \
+                                  feature_flags, feature_flags_private, \
+                                  winsys_feature)                       \
+  { 255, 255, namespaces, extension_names,                              \
+      feature_flags, feature_flags_private,                             \
+      winsys_feature, \
+      cogl_egl_feature_ ## name ## _funcs },
+#undef COGL_WINSYS_FEATURE_FUNCTION
+#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args)
+#undef COGL_WINSYS_FEATURE_END
+#define COGL_WINSYS_FEATURE_END()
+
+static const CoglFeatureData winsys_feature_data[] =
+  {
+#include "cogl-winsys-egl-feature-functions.h"
+  };
+
 CoglFuncPtr
 _cogl_winsys_get_proc_address (const char *name)
 {
   return (CoglFuncPtr) eglGetProcAddress (name);
 }
 
+#undef COGL_WINSYS_FEATURE_BEGIN
+#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f)
+#undef COGL_WINSYS_FEATURE_FUNCTION
+#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
+  egl_renderer->pf_ ## name = NULL;
+#undef COGL_WINSYS_FEATURE_END
+#define COGL_WINSYS_FEATURE_END()
+
+static void
+initialize_function_table (CoglRenderer *renderer)
+{
+  CoglRendererEGL *egl_renderer = renderer->winsys;
+
+#include "cogl-winsys-egl-feature-functions.h"
+}
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+static CoglOnscreen *
+find_onscreen_for_xid (CoglContext *context, guint32 xid)
+{
+  GList *l;
+
+  for (l = context->framebuffers; l; l = l->next)
+    {
+      CoglFramebuffer *framebuffer = l->data;
+      CoglOnscreenXlib *xlib_onscreen;
+
+      if (!framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+        continue;
+
+      xlib_onscreen = COGL_ONSCREEN (framebuffer)->winsys;
+      if (xlib_onscreen->xwin == (Window)xid)
+        return COGL_ONSCREEN (framebuffer);
+    }
+
+  return NULL;
+}
+
+static CoglFilterReturn
+event_filter_cb (void *event, void *data)
+{
+  XEvent *xevent = event;
+  CoglContext *context = data;
+
+  if (xevent->type == ConfigureNotify)
+    {
+      CoglOnscreen *onscreen =
+        find_onscreen_for_xid (context, xevent->xconfigure.window);
+
+      if (onscreen)
+        {
+          CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+
+          /* XXX: consider adding an abstraction for this... */
+          framebuffer->width = xevent->xconfigure.width;
+          framebuffer->height = xevent->xconfigure.height;
+        }
+    }
+
+  return COGL_FILTER_CONTINUE;
+}
+#endif /* COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT */
+
+gboolean
+_cogl_winsys_renderer_connect (CoglRenderer *renderer,
+                               GError **error)
+{
+  CoglRendererEGL *egl_renderer;
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  CoglRendererXlib *xlib_renderer;
+#endif
+  EGLBoolean status;
+
+  renderer->winsys = g_slice_new0 (CoglRendererEGL);
+
+  egl_renderer = renderer->winsys;
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  xlib_renderer = renderer->winsys;
+
+  if (!_cogl_renderer_xlib_connect (renderer, error))
+    goto error;
+
+  egl_renderer->edpy =
+    eglGetDisplay ((NativeDisplayType) xlib_renderer->xdpy);
+
+  status = eglInitialize (egl_renderer->edpy,
+                          &egl_renderer->egl_version_major,
+                          &egl_renderer->egl_version_minor);
+#else
+  egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
+
+  status = eglInitialize (egl_renderer->edpy,
+                         &egl_renderer->egl_version_major,
+                         &egl_renderer->egl_version_minor);
+
+  if (status != EGL_TRUE)
+    {
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_INIT,
+                   "Failed to initialize EGL");
+      goto error;
+    }
+#endif
+
+  return TRUE;
+
+error:
+  _cogl_winsys_renderer_disconnect (renderer);
+  return FALSE;
+}
+
+void
+_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
+{
+  CoglRendererEGL *egl_renderer = renderer->winsys;
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  _cogl_renderer_xlib_disconnect (renderer);
+#endif
+
+  eglTerminate (egl_renderer->edpy);
+
+  g_slice_free (CoglRendererEGL, egl_renderer);
+}
+
+void
+update_winsys_features (CoglContext *context)
+{
+  CoglDisplayEGL *egl_display = context->display->winsys;
+  CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
+  const char *egl_extensions;
+  int i;
+
+  g_return_if_fail (egl_display->egl_context);
+
+  _cogl_gl_update_features (context);
+
+  memset (context->winsys_features, 0, sizeof (context->winsys_features));
+
+  egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS);
+
+  COGL_NOTE (WINSYS, "  EGL Extensions: %s", egl_extensions);
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
+  COGL_FLAGS_SET (context->winsys_features,
+                  COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
+                  TRUE);
+#endif
+
+  initialize_function_table (context->display->renderer);
+
+  for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
+    if (_cogl_feature_check ("EGL", winsys_feature_data + i, 0, 0,
+                             egl_extensions,
+                             egl_renderer))
+      {
+        context->feature_flags |= winsys_feature_data[i].feature_flags;
+        if (winsys_feature_data[i].winsys_feature)
+          COGL_FLAGS_SET (context->winsys_features,
+                          winsys_feature_data[i].winsys_feature,
+                          TRUE);
+      }
+
+  /* FIXME: the winsys_feature_data can currently only have one
+   * winsys feature per extension... */
+  if (egl_renderer->pf_eglSwapBuffersRegion)
+    {
+      COGL_FLAGS_SET (context->winsys_features,
+                      COGL_WINSYS_FEATURE_SWAP_REGION, TRUE);
+      COGL_FLAGS_SET (context->winsys_features,
+                      COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
+    }
+}
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+static XVisualInfo *
+get_visual_info (CoglDisplay *display, EGLConfig egl_config)
+{
+  CoglRendererXlib *xlib_renderer = display->renderer->winsys;
+  CoglRendererEGL *egl_renderer = display->renderer->winsys;
+  XVisualInfo visinfo_template;
+  int template_mask = 0;
+  XVisualInfo *visinfo = NULL;
+  int visinfos_count;
+  EGLint visualid, red_size, green_size, blue_size, alpha_size;
+
+  eglGetConfigAttrib (egl_renderer->edpy, egl_config,
+                      EGL_NATIVE_VISUAL_ID, &visualid);
+
+  if (visualid != 0)
+    {
+      visinfo_template.visualid = visualid;
+      template_mask |= VisualIDMask;
+    }
+  else
+    {
+      /* some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID
+       * attribute, so attempt to find the closest match. */
+
+      eglGetConfigAttrib (egl_renderer->edpy, egl_config,
+                          EGL_RED_SIZE, &red_size);
+      eglGetConfigAttrib (egl_renderer->edpy, egl_config,
+                          EGL_GREEN_SIZE, &green_size);
+      eglGetConfigAttrib (egl_renderer->edpy, egl_config,
+                          EGL_BLUE_SIZE, &blue_size);
+      eglGetConfigAttrib (egl_renderer->edpy, egl_config,
+                          EGL_ALPHA_SIZE, &alpha_size);
+
+      visinfo_template.depth = red_size + green_size + blue_size + alpha_size;
+      template_mask |= VisualDepthMask;
+
+      visinfo_template.screen = DefaultScreen (xlib_renderer->xdpy);
+      template_mask |= VisualScreenMask;
+    }
+
+  visinfo = XGetVisualInfo (xlib_renderer->xdpy,
+                            template_mask,
+                            &visinfo_template,
+                            &visinfos_count);
+
+  return visinfo;
+}
+#endif
+
+static gboolean
+try_create_context (CoglDisplay *display,
+                    int retry_cookie,
+                    gboolean *try_fallback,
+                    GError **error)
+{
+  CoglDisplayEGL *egl_display = display->winsys;
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  CoglDisplayXlib *xlib_display = display->winsys;
+  CoglRendererXlib *xlib_renderer = display->renderer->winsys;
+#endif
+  CoglRendererEGL *egl_renderer = display->renderer->winsys;
+  EGLDisplay edpy;
+  EGLConfig config;
+  EGLint config_count = 0;
+  EGLBoolean status;
+  EGLint cfg_attribs[] = {
+    /* NB: This must be the first attribute, since we may
+     * try and fallback to no stencil buffer */
+    EGL_STENCIL_SIZE,    2,
+
+    EGL_RED_SIZE,        1,
+    EGL_GREEN_SIZE,      1,
+    EGL_BLUE_SIZE,       1,
+    EGL_ALPHA_SIZE,      EGL_DONT_CARE,
+
+    EGL_DEPTH_SIZE,      1,
+
+    EGL_BUFFER_SIZE,     EGL_DONT_CARE,
+
+#if defined (HAVE_COGL_GL)
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+#elif defined (HAVE_COGL_GLES2)
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#else
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+#endif
+
+    EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
+
+    EGL_NONE
+  };
+#if defined (HAVE_COGL_GLES2)
+  EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+#else
+  EGLint *attribs = NULL;
+#endif
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  XVisualInfo *xvisinfo;
+  XSetWindowAttributes attrs;
+#endif
+  const char *error_message;
+
+  edpy = egl_renderer->edpy;
+
+#ifdef HAVE_COGL_GL
+  eglBindAPI (EGL_OPENGL_API);
+#endif
+
+  /* Some GLES hardware can't support a stencil buffer: */
+  if (retry_cookie == 1)
+    {
+      g_warning ("Trying with stencil buffer disabled...");
+      cfg_attribs[1 /* EGL_STENCIL_SIZE */] = 0;
+    }
+  /* XXX: at this point we only have one fallback */
+
+  status = eglChooseConfig (edpy,
+                            cfg_attribs,
+                            &config, 1,
+                            &config_count);
+  if (status != EGL_TRUE || config_count == 0)
+    {
+      error_message = "Unable to find a usable EGL configuration";
+      goto fail;
+    }
+
+  egl_display->egl_config = config;
+
+  egl_display->egl_context = eglCreateContext (edpy,
+                                               config,
+                                               EGL_NO_CONTEXT,
+                                               attribs);
+  if (egl_display->egl_context == EGL_NO_CONTEXT)
+    {
+      error_message = "Unable to create a suitable EGL context";
+      goto fail;
+    }
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+
+  xvisinfo = get_visual_info (display, config);
+  if (xvisinfo == NULL)
+    {
+      error_message = "Unable to find suitable X visual";
+      goto fail;
+    }
+
+  attrs.override_redirect = True;
+  attrs.colormap = XCreateColormap (xlib_renderer->xdpy,
+                                    DefaultRootWindow (xlib_renderer->xdpy),
+                                    xvisinfo->visual,
+                                    AllocNone);
+  attrs.border_pixel = 0;
+
+  xlib_display->dummy_xwin =
+    XCreateWindow (xlib_renderer->xdpy,
+                   DefaultRootWindow (xlib_renderer->xdpy),
+                   -100, -100, 1, 1,
+                   0,
+                   xvisinfo->depth,
+                   CopyFromParent,
+                   xvisinfo->visual,
+                   CWOverrideRedirect |
+                   CWColormap |
+                   CWBorderPixel,
+                   &attrs);
+
+  XFree (xvisinfo);
+
+  egl_display->dummy_surface =
+    eglCreateWindowSurface (edpy,
+                            egl_display->egl_config,
+                            (NativeWindowType) xlib_display->dummy_xwin,
+                            NULL);
+
+  if (egl_display->dummy_surface == EGL_NO_SURFACE)
+    {
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_CONTEXT,
+                   "Unable to create an EGL surface");
+      goto fail;
+    }
+
+  if (!eglMakeCurrent (edpy,
+                       egl_display->dummy_surface,
+                       egl_display->dummy_surface,
+                       egl_display->egl_context))
+    {
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_CONTEXT,
+                   "Unable to eglMakeCurrent with dummy surface");
+      goto fail;
+    }
+
+#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
+
+  egl_display->egl_surface =
+    eglCreateWindowSurface (edpy,
+                            config,
+                            (NativeWindowType) NULL,
+                            NULL);
+  if (egl_display->egl_surface == EGL_NO_SURFACE)
+    {
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_CONTEXT,
+                   "Unable to create EGL window surface");
+      goto fail;
+    }
+
+  if (!eglMakeCurrent (egl_renderer->edpy,
+                       egl_display->egl_surface,
+                       egl_display->egl_surface,
+                       egl_display->egl_context))
+    {
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_CONTEXT,
+                   "Unable to eglMakeCurrent with egl surface");
+      goto fail;
+    }
+
+  eglQuerySurface (egl_renderer->edpy,
+                   egl_display->egl_surface,
+                   EGL_WIDTH,
+                   &egl_display->egl_surface_width);
+
+  eglQuerySurface (egl_renderer->edpy,
+                   egl_display->egl_surface,
+                   EGL_HEIGHT,
+                   &egl_display->egl_surface_height);
+
+#else
+#error "Unknown EGL platform"
+#endif
+
+  return TRUE;
+
+fail:
+
+  /* Currently we only have one fallback path... */
+  if (retry_cookie == 0)
+    {
+      *try_fallback = TRUE;
+      return FALSE;
+    }
+  else
+    {
+      *try_fallback = FALSE;
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_CONTEXT,
+                   "%s", error_message);
+      return FALSE;
+    }
+}
+
+static void
+cleanup_context (CoglDisplay *display)
+{
+  CoglDisplayEGL *egl_display = display->winsys;
+  CoglRendererEGL *egl_renderer = display->renderer->winsys;
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  CoglDisplayXlib *xlib_display = display->winsys;
+  CoglRendererXlib *xlib_renderer = display->renderer->winsys;
+#endif
+
+  if (egl_display->egl_context != EGL_NO_CONTEXT)
+    {
+      eglMakeCurrent (egl_renderer->edpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                      EGL_NO_CONTEXT);
+      eglDestroyContext (egl_renderer->edpy, egl_display->egl_context);
+      egl_display->egl_context = EGL_NO_CONTEXT;
+    }
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  if (egl_display->dummy_surface != EGL_NO_SURFACE)
+    {
+      eglDestroySurface (egl_renderer->edpy, egl_display->dummy_surface);
+      egl_display->dummy_surface = EGL_NO_SURFACE;
+    }
+
+  if (xlib_display->dummy_xwin)
+    {
+      XDestroyWindow (xlib_renderer->xdpy, xlib_display->dummy_xwin);
+      xlib_display->dummy_xwin = None;
+    }
+#endif
+}
+
+static gboolean
+create_context (CoglDisplay *display, GError **error)
+{
+  CoglDisplayEGL *egl_display = display->winsys;
+  gboolean support_transparent_windows;
+  int retry_cookie = 0;
+  gboolean status;
+  gboolean try_fallback;
+  GError *try_error = NULL;
+
+  g_return_val_if_fail (egl_display->egl_context == NULL, TRUE);
+
+  if (display->onscreen_template &&
+      display->onscreen_template->swap_chain &&
+      display->onscreen_template->swap_chain->has_alpha)
+    support_transparent_windows = TRUE;
+  else
+    support_transparent_windows = FALSE;
+
+  retry_cookie = 0;
+  while (!(status = try_create_context (display,
+                                        retry_cookie,
+                                        &try_fallback,
+                                        &try_error)) &&
+         try_fallback)
+    {
+      g_error_free (try_error);
+      cleanup_context (display);
+      try_error = NULL;
+      retry_cookie++;
+    }
+  if (!status)
+    g_propagate_error (error, try_error);
+
+  return status;
+}
+
+gboolean
+_cogl_winsys_display_setup (CoglDisplay *display,
+                            GError **error)
+{
+  CoglDisplayEGL *egl_display;
+
+  g_return_val_if_fail (display->winsys == NULL, FALSE);
+
+  egl_display = g_slice_new0 (CoglDisplayEGL);
+  display->winsys = egl_display;
+
+  if (!create_context (display, error))
+    goto error;
+
+  egl_display->found_egl_config = TRUE;
+
+  return TRUE;
+
+error:
+  _cogl_winsys_display_destroy (display);
+  return FALSE;
+}
+
+void
+_cogl_winsys_display_destroy (CoglDisplay *display)
+{
+  CoglDisplayEGL *egl_display = display->winsys;
+
+  g_return_if_fail (egl_display != NULL);
+
+  cleanup_context (display);
+
+  g_slice_free (CoglDisplayEGL, display->winsys);
+  display->winsys = NULL;
+}
+
+gboolean
+_cogl_winsys_context_init (CoglContext *context, GError **error)
+{
+  context->winsys = g_new0 (CoglContextEGL, 1);
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  cogl_renderer_add_native_filter (context->display->renderer,
+                                   event_filter_cb,
+                                   context);
+#endif
+  update_winsys_features (context);
+
+  return TRUE;
+}
+
+void
+_cogl_winsys_context_deinit (CoglContext *context)
+{
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  cogl_renderer_remove_native_filter (context->display->renderer,
+                                      event_filter_cb,
+                                      context);
+#endif
+  g_free (context->winsys);
+}
+
+gboolean
+_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
+                            GError **error)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = framebuffer->context;
+  CoglDisplay *display = context->display;
+  CoglDisplayEGL *egl_display = display->winsys;
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  CoglRendererEGL *egl_renderer = display->renderer->winsys;
+  CoglRendererXlib *xlib_renderer = display->renderer->winsys;
+  CoglOnscreenXlib *xlib_onscreen;
+  Window xwin;
+#endif
+  CoglOnscreenEGL *egl_onscreen;
+
+  g_return_val_if_fail (egl_display->egl_context, FALSE);
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+
+  /* FIXME: We need to explicitly Select for ConfigureNotify events.
+   * For foreign windows we need to be careful not to mess up any
+   * existing event mask.
+   * We need to document that for windows we create then toolkits
+   * must be careful not to clear event mask bits that we select.
+   */
+
+  /* XXX: Note we ignore the user's original width/height when
+   * given a foreign X window. */
+  if (onscreen->foreign_xid)
+    {
+      Status status;
+      CoglXlibTrapState state;
+      XWindowAttributes attr;
+      int xerror;
+
+      xwin = onscreen->foreign_xid;
+
+      _cogl_renderer_xlib_trap_errors (display->renderer, &state);
+
+      status = XGetWindowAttributes (xlib_renderer->xdpy, xwin, &attr);
+      xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state);
+      if (status == 0 || xerror)
+        {
+          char message[1000];
+          XGetErrorText (xlib_renderer->xdpy, xerror,
+                         message, sizeof (message));
+          g_set_error (error, COGL_WINSYS_ERROR,
+                       COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+                       "Unable to query geometry of foreign xid 0x%08lX: %s",
+                       xwin, message);
+          return FALSE;
+        }
+
+      _cogl_framebuffer_winsys_update_size (framebuffer,
+                                            attr.width, attr.height);
+    }
+  else
+    {
+      int width;
+      int height;
+      CoglXlibTrapState state;
+      XVisualInfo *xvisinfo;
+      XSetWindowAttributes xattr;
+      unsigned long mask;
+      int xerror;
+
+      width = cogl_framebuffer_get_width (framebuffer);
+      height = cogl_framebuffer_get_height (framebuffer);
+
+      _cogl_renderer_xlib_trap_errors (display->renderer, &state);
+
+      xvisinfo = get_visual_info (display, egl_display->egl_config);
+      if (xvisinfo == NULL)
+        {
+          g_set_error (error, COGL_WINSYS_ERROR,
+                       COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+                       "Unable to retrieve the X11 visual of context's "
+                       "fbconfig");
+          return FALSE;
+        }
+
+      /* window attributes */
+      xattr.background_pixel = WhitePixel (xlib_renderer->xdpy,
+                                           DefaultScreen (xlib_renderer->xdpy));
+      xattr.border_pixel = 0;
+      /* XXX: is this an X resource that we are leaking‽... */
+      xattr.colormap = XCreateColormap (xlib_renderer->xdpy,
+                                        DefaultRootWindow (xlib_renderer->xdpy),
+                                        xvisinfo->visual,
+                                        AllocNone);
+      mask = CWBorderPixel | CWColormap;
+
+      xwin = XCreateWindow (xlib_renderer->xdpy,
+                            DefaultRootWindow (xlib_renderer->xdpy),
+                            0, 0,
+                            width, height,
+                            0,
+                            xvisinfo->depth,
+                            InputOutput,
+                            xvisinfo->visual,
+                            mask, &xattr);
+
+      XFree (xvisinfo);
+
+      XMapWindow (xlib_renderer->xdpy, xwin);
+
+      XSync (xlib_renderer->xdpy, False);
+      xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state);
+      if (xerror)
+        {
+          char message[1000];
+          XGetErrorText (xlib_renderer->xdpy, xerror,
+                         message, sizeof (message));
+          g_set_error (error, COGL_WINSYS_ERROR,
+                       COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+                       "X error while creating Window for CoglOnscreen: %s",
+                       message);
+          return FALSE;
+        }
+    }
+#endif
+
+  onscreen->winsys = g_slice_new0 (CoglOnscreenEGL);
+  egl_onscreen = onscreen->winsys;
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  xlib_onscreen = onscreen->winsys;
+
+  xlib_onscreen->xwin = xwin;
+  xlib_onscreen->is_foreign_xwin = onscreen->foreign_xid ? TRUE : FALSE;
+
+  egl_onscreen->egl_surface =
+    eglCreateWindowSurface (egl_renderer->edpy,
+                            egl_display->egl_config,
+                            (NativeWindowType) xlib_onscreen->xwin,
+                            NULL);
+#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
+  if (egl_display->have_onscreen)
+    {
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+                   "EGL platform only supports a single onscreen window");
+      return FALSE;
+    }
+
+  egl_onscreen->egl_surface = egl_display->egl_surface;
+
+  _cogl_framebuffer_winsys_update_size (framebuffer,
+                                        egl_display->egl_surface_width,
+                                        egl_display->egl_surface_height);
+  egl_display->have_onscreen = TRUE;
+#else
+#error "Unknown EGL platform"
+#endif
+
+  return TRUE;
+}
+
+void
+_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = framebuffer->context;
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  CoglRendererXlib *xlib_renderer = context->display->renderer->winsys;
+  CoglXlibTrapState old_state;
+  CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
+#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
+  CoglDisplayEGL *egl_display = context->display->winsys;
+#endif
+  CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+
+  if (egl_onscreen->egl_surface != EGL_NO_SURFACE)
+    {
+      if (eglDestroySurface (egl_renderer->edpy, egl_onscreen->egl_surface)
+          == EGL_FALSE)
+        g_warning ("Failed to destroy EGL surface");
+      egl_onscreen->egl_surface = EGL_NO_SURFACE;
+    }
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT
+  egl_display->have_onscreen = FALSE;
+#endif
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  _cogl_xlib_trap_errors (&old_state);
+
+  if (!xlib_onscreen->is_foreign_xwin && xlib_onscreen->xwin != None)
+    {
+      XDestroyWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
+      xlib_onscreen->xwin = None;
+    }
+  else
+    xlib_onscreen->xwin = None;
+
+  XSync (xlib_renderer->xdpy, False);
+
+  if (_cogl_xlib_untrap_errors (&old_state) != Success)
+    g_warning ("X Error while destroying X window");
+#endif
+}
+
+void
+_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
+{
+  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglContextEGL *egl_context = context->winsys;
+  CoglDisplayEGL *egl_display = context->display->winsys;
+  CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+
+  if (egl_context->current_surface == egl_onscreen->egl_surface)
+    return;
+
+  if (G_UNLIKELY (!onscreen))
+    {
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+      eglMakeCurrent (egl_renderer->edpy,
+                      egl_display->dummy_surface,
+                      egl_display->dummy_surface,
+                      egl_display->egl_context);
+      egl_context->current_surface = egl_display->dummy_surface;
+#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
+      return;
+#else
+#error "Unknown EGL platform"
+#endif
+    }
+  else
+    {
+      eglMakeCurrent (egl_renderer->edpy,
+                      egl_onscreen->egl_surface,
+                      egl_onscreen->egl_surface,
+                      egl_display->egl_context);
+      egl_context->current_surface = egl_onscreen->egl_surface;
+    }
+
+  if (onscreen->swap_throttled)
+    eglSwapInterval (egl_renderer->edpy, 1);
+  else
+    eglSwapInterval (egl_renderer->edpy, 0);
+}
+
+void
+_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
+                                   int *rectangles,
+                                   int n_rectangles)
+{
+  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+
+  if (egl_renderer->pf_eglSwapBuffersRegion (egl_renderer->edpy,
+                                             egl_onscreen->egl_surface,
+                                             n_rectangles,
+                                             rectangles) == EGL_FALSE)
+    g_warning ("Error reported by eglSwapBuffersRegion");
+}
+
+guint32
+_cogl_winsys_get_vsync_counter (void)
+{
+  /* Unsupported feature */
+  return 0;
+}
+
+void
+_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
+{
+  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+
+  eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface);
+}
+
+guint32
+_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
+{
+  CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
+  return xlib_onscreen->xwin;
+}
+
+unsigned int
+_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
+                                                 CoglSwapBuffersNotify callback,
+                                                 void *user_data)
+{
+  /* Unsupported feature */
+  return 0;
+}
+
+void
+_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
+                                                    unsigned int id)
+{
+  /* Unsupported feature */
+}
+
+void
+_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
+{
+  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglContextEGL *egl_context = context->winsys;
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+
+  if (egl_context->current_surface != egl_onscreen->egl_surface)
+    return;
+
+  egl_context->current_surface = EGL_NO_SURFACE;
+  _cogl_winsys_onscreen_bind (onscreen);
+}
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+/* XXX: This is a particularly hacky _cogl_winsys interface... */
+XVisualInfo *
+_cogl_winsys_xlib_get_visual_info (void)
+{
+  CoglDisplayEGL *egl_display;
+
+  _COGL_GET_CONTEXT (ctx, NULL);
+
+  g_return_val_if_fail (ctx->display->winsys, FALSE);
+
+  egl_display = ctx->display->winsys;
+
+  if (!egl_display->found_egl_config)
+    return NULL;
+
+  return get_visual_info (ctx->display, egl_display->egl_config);
+}
+#endif
+
+EGLDisplay
+_cogl_winsys_context_egl_get_egl_display (CoglContext *context)
+{
+  CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
+
+  return egl_renderer->edpy;
+}
index 8d56bea..4f3d494 100644 (file)
@@ -71,6 +71,11 @@ _cogl_winsys_context_init (CoglContext *context, GError **error);
 void
 _cogl_winsys_context_deinit (CoglContext *context);
 
+#ifdef COGL_HAS_EGL_SUPPORT
+EGLDisplay
+_cogl_winsys_context_egl_get_egl_display (CoglContext *context);
+#endif
+
 gboolean
 _cogl_winsys_has_feature (CoglWinsysFeature feature);
 
diff --git a/clutter/egl/clutter-backend-cex100.c b/clutter/egl/clutter-backend-cex100.c
deleted file mode 100644 (file)
index f5d6403..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- *   Tao Zhao <tao.zhao@intel.com>
- *   Damien Lespiau <damien.lespiau@intel.com>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "clutter-debug.h"
-#include "clutter-main.h"
-
-#include "clutter-backend-cex100.h"
-#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;
-
-G_DEFINE_TYPE (ClutterBackendCex100,
-               clutter_backend_cex100,
-               CLUTTER_TYPE_BACKEND_EGL)
-
-#ifdef CLUTTER_ENABLE_DEBUG
-static const gchar *
-gdl_get_plane_name (gdl_plane_id_t plane)
-{
-  switch (plane)
-    {
-    case GDL_PLANE_ID_UPP_A:
-      return "UPP_A";
-    case GDL_PLANE_ID_UPP_B:
-      return "UPP_B";
-    case GDL_PLANE_ID_UPP_C:
-      return "UPP_C";
-    case GDL_PLANE_ID_UPP_D:
-      return "UPP_D";
-    case GDL_PLANE_ID_UPP_E:
-      return "UPP_E";
-    default:
-      g_assert_not_reached ();
-    }
-
-  return NULL; /* never reached */
-}
-#endif
-
-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 (rc == GDL_SUCCESS)
-    rc = gdl_plane_set_uint (GDL_PLANE_NUM_GFX_SURFACES, gdl_n_buffers);
-
-  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;
-  NativeWindowType window;
-  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
-  };
-
-  if (backend_egl->egl_context != EGL_NO_CONTEXT)
-    return TRUE;
-
-  CLUTTER_NOTE (BACKEND, "Using the %s plane", gdl_get_plane_name (gdl_plane));
-
-  /* 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;
-    }
-
-  window = (NativeWindowType) gdl_plane;
-
-  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 ();
-}
-
-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;
-}
-
-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;
-}
diff --git a/clutter/egl/clutter-backend-cex100.h b/clutter/egl/clutter-backend-cex100.h
deleted file mode 100644 (file)
index 79e03d0..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- * Author:
- *   Damien Lespiau <damien.lespiau@intel.com>
- */
-
-#ifndef __CLUTTER_BACKEND_CEX100_H__
-#define __CLUTTER_BACKEND_CEX100_H__
-
-#include <libgdl.h>
-
-#include <glib-object.h>
-
-#include <clutter/egl/clutter-backend-egl.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_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__ */
index 2af37de..ec2d781 100644 (file)
 #include "clutter-private.h"
 #include "clutter-main.h"
 #include "clutter-stage-private.h"
+/* FIXME: We should have CLUTTER_ define for this... */
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_GDL_SUPPORT
+#include "clutter-cex100.h"
+#endif
 
 static ClutterBackendEGL *backend_singleton = NULL;
 
-static const gchar *clutter_fb_device = NULL;
+static gchar *clutter_vblank = NULL;
 
-static gchar *clutter_vblank_name = NULL;
+/* FIXME: We should have CLUTTER_ define for this... */
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_GDL_SUPPORT
+static gdl_plane_id_t gdl_plane = GDL_PLANE_ID_UPP_C;
+static guint gdl_n_buffers = CLUTTER_CEX100_TRIPLE_BUFFERING;
+#endif
 
 #ifdef COGL_HAS_X11_SUPPORT
 G_DEFINE_TYPE (ClutterBackendEGL, _clutter_backend_egl, CLUTTER_TYPE_BACKEND_X11);
@@ -68,30 +76,35 @@ clutter_backend_at_exit (void)
     g_object_run_dispose (G_OBJECT (backend_singleton));
 }
 
+G_CONST_RETURN gchar*
+_clutter_backend_egl_get_vblank (void)
+{
+  if (clutter_vblank && strcmp (clutter_vblank, "0") == 0)
+    return "none";
+  else
+    return clutter_vblank;
+}
+
 static gboolean
 clutter_backend_egl_pre_parse (ClutterBackend  *backend,
                                GError         **error)
 {
   const gchar *env_string;
 #ifdef COGL_HAS_X11_SUPPORT
-  ClutterBackendClass *backend_x11_class =
+  ClutterBackendClass *parent_class =
     CLUTTER_BACKEND_CLASS (_clutter_backend_egl_parent_class);
 
-  if (!backend_x11_class->pre_parse (backend, error))
+  if (!parent_class->pre_parse (backend, error))
     return FALSE;
 #endif
 
   env_string = g_getenv ("CLUTTER_VBLANK");
   if (env_string)
     {
-      clutter_vblank_name = g_strdup (env_string);
+      clutter_vblank = g_strdup (env_string);
       env_string = NULL;
     }
 
-  env_string = g_getenv ("CLUTTER_FB_DEVICE");
-  if (env_string != NULL && env_string[0] != '\0')
-    clutter_fb_device = g_strdup (env_string);
-
   return TRUE;
 }
 
@@ -99,409 +112,19 @@ static gboolean
 clutter_backend_egl_post_parse (ClutterBackend  *backend,
                                 GError         **error)
 {
-  ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
 #ifdef COGL_HAS_X11_SUPPORT
-  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
-  ClutterBackendClass *backend_x11_class =
+  ClutterBackendClass *parent_class =
     CLUTTER_BACKEND_CLASS (_clutter_backend_egl_parent_class);
-#endif
-  EGLBoolean status;
 
-#ifdef COGL_HAS_X11_SUPPORT
-  if (!backend_x11_class->post_parse (backend, error))
+  if (!parent_class->post_parse (backend, error))
     return FALSE;
 
-#ifndef COGL_HAS_XLIB_SUPPORT
-#error "Clutter's EGL on X11 support currently only works with xlib Displays"
-#endif
-  backend_egl->edpy =
-    eglGetDisplay ((NativeDisplayType) backend_x11->xdpy);
-
-  status = eglInitialize (backend_egl->edpy,
-                          &backend_egl->egl_version_major,
-                          &backend_egl->egl_version_minor);
-#else
-  backend_egl->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
-
-  status = eglInitialize (backend_egl->edpy,
-                         &backend_egl->egl_version_major,
-                         &backend_egl->egl_version_minor);
-#endif
-
-  g_atexit (clutter_backend_at_exit);
-
-  if (status != EGL_TRUE)
-    {
-      g_set_error (error, CLUTTER_INIT_ERROR,
-                  CLUTTER_INIT_ERROR_BACKEND,
-                  "Unable to Initialize EGL");
-      return FALSE;
-    }
-
-  CLUTTER_NOTE (BACKEND, "EGL Reports version %i.%i",
-               backend_egl->egl_version_major,
-               backend_egl->egl_version_minor);
-
   return TRUE;
-}
-
-void
-_clutter_backend_egl_blit_sub_buffer (ClutterBackendEGL *backend_egl,
-                                      EGLSurface drawable,
-                                      int x, int y, int width, int height)
-{
-  if (backend_egl->swap_buffers_region)
-    {
-      EGLint rect[4] = {
-          x, y, width, height
-      };
-      backend_egl->swap_buffers_region (backend_egl->edpy,
-                                        drawable,
-                                        1,
-                                        rect);
-    }
-#if 0 /* XXX need GL_ARB_draw_buffers */
-  else if (backend_egl->blit_framebuffer)
-    {
-      glDrawBuffer (GL_FRONT);
-      backend_egl->blit_framebuffer (x, y, x + width, y + height,
-                                     x, y, x + width, y + height,
-                                     GL_COLOR_BUFFER_BIT, GL_NEAREST);
-      glDrawBuffer (GL_BACK);
-      glFlush();
-    }
-#endif
-}
-
-static gboolean
-clutter_backend_egl_create_context (ClutterBackend  *backend,
-                                    GError         **error)
-{
-  ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
-#ifdef COGL_HAS_X11_SUPPORT
-  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
-#endif
-  EGLConfig          config;
-  EGLint             config_count = 0;
-  EGLBoolean         status;
-  EGLint             cfg_attribs[] = {
-    /* NB: This must be the first attribute, since we may
-     * try and fallback to no stencil buffer */
-    EGL_STENCIL_SIZE,    2,
-
-    EGL_RED_SIZE,        1,
-    EGL_GREEN_SIZE,      1,
-    EGL_BLUE_SIZE,       1,
-    EGL_ALPHA_SIZE,      EGL_DONT_CARE,
-
-    EGL_DEPTH_SIZE,      1,
-
-    EGL_BUFFER_SIZE,     EGL_DONT_CARE,
-
-#if defined (HAVE_COGL_GL)
-    EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
-#elif defined (HAVE_COGL_GLES2)
-    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#else
-    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
-#endif
-
-    EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
-
-    EGL_NONE
-  };
-  EGLDisplay edpy;
-  gint retry_cookie = 0;
-  const char *error_message = NULL;
-#ifdef COGL_HAS_XLIB_SUPPORT
-  XVisualInfo *xvisinfo;
-  XSetWindowAttributes attrs;
-#endif
-
-  if (backend_egl->egl_context != EGL_NO_CONTEXT)
-    return TRUE;
-
-  edpy = clutter_egl_get_egl_display ();
-
-/* XXX: we should get rid of this goto yukkyness, there is a fail:
- * goto at the end and this retry: goto at the top, but we should just
- * have a try_create_context() function and call it in a loop that
- * tries a different fallback each iteration */
-retry:
-  /* Here we can change the attributes depending on the fallback count... */
-
-  /* Some GLES hardware can't support a stencil buffer: */
-  if (retry_cookie == 1)
-    {
-      g_warning ("Trying with stencil buffer disabled...");
-      cfg_attribs[1 /* EGL_STENCIL_SIZE */] = 0;
-    }
-
-  /* XXX: at this point we only have one fallback */
-
-  status = eglChooseConfig (edpy,
-                            cfg_attribs,
-                            &config, 1,
-                            &config_count);
-  if (status != EGL_TRUE || config_count == 0)
-    {
-      error_message = "Unable to select a valid EGL configuration";
-      goto fail;
-    }
-
-#ifdef HAVE_COGL_GL
-  eglBindAPI (EGL_OPENGL_API);
-#endif
-
-  if (backend_egl->egl_context == EGL_NO_CONTEXT)
-    {
-#ifdef HAVE_COGL_GLES2
-      static const EGLint attribs[] =
-        { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-
-      backend_egl->egl_context = eglCreateContext (edpy,
-                                                   config,
-                                                   EGL_NO_CONTEXT,
-                                                   attribs);
-
-#else
-      backend_egl->egl_context = eglCreateContext (edpy,
-                                                   config,
-                                                   EGL_NO_CONTEXT,
-                                                   NULL);
-
 #endif
-      if (backend_egl->egl_context == EGL_NO_CONTEXT)
-        {
-          error_message = "Unable to create a suitable EGL context";
-          goto fail;
-        }
-
-#ifdef COGL_HAS_XLIB_SUPPORT
-      backend_egl->egl_config = config;
-#endif
-      CLUTTER_NOTE (GL, "Created EGL Context");
-    }
-
-#ifdef COGL_HAS_XLIB_SUPPORT
-  /* COGL assumes that there is always a GL context selected; in order
-   * to make sure that an EGL context exists and is made current, we use
-   * a dummy, offscreen override-redirect window to which we can always
-   * fall back if no stage is available */
-
-  xvisinfo = _clutter_backend_x11_get_visual_info (backend_x11);
-  if (xvisinfo == NULL)
-    {
-      g_critical ("Unable to find suitable GL visual.");
-      return FALSE;
-    }
-
-  attrs.override_redirect = True;
-  attrs.colormap = XCreateColormap (backend_x11->xdpy,
-                                    backend_x11->xwin_root,
-                                    xvisinfo->visual,
-                                    AllocNone);
-  attrs.border_pixel = 0;
-
-  backend_egl->dummy_xwin = XCreateWindow (backend_x11->xdpy,
-                                           backend_x11->xwin_root,
-                                           -100, -100, 1, 1,
-                                           0,
-                                           xvisinfo->depth,
-                                           CopyFromParent,
-                                           xvisinfo->visual,
-                                           CWOverrideRedirect |
-                                           CWColormap |
-                                           CWBorderPixel,
-                                           &attrs);
-
-  XFree (xvisinfo);
-
-  backend_egl->dummy_surface =
-    eglCreateWindowSurface (edpy,
-                            backend_egl->egl_config,
-                            (NativeWindowType) backend_egl->dummy_xwin,
-                            NULL);
-
-  if (backend_egl->dummy_surface == EGL_NO_SURFACE)
-    {
-      g_critical ("Unable to create an EGL surface");
-      return FALSE;
-    }
-
-  eglMakeCurrent (edpy,
-                  backend_egl->dummy_surface,
-                  backend_egl->dummy_surface,
-                  backend_egl->egl_context);
-
-#else /* COGL_HAS_XLIB_SUPPORT */
-
-  if (clutter_fb_device != NULL)
-    {
-      int fd = open (clutter_fb_device, O_RDWR);
-
-      if (fd < 0)
-        {
-          int errno_save = errno;
-
-          g_set_error (error, CLUTTER_INIT_ERROR,
-                       CLUTTER_INIT_ERROR_BACKEND,
-                       "Unable to open the framebuffer device '%s': %s",
-                       clutter_fb_device,
-                       g_strerror (errno_save));
-
-          return FALSE;
-        }
-      else
-        backend_egl->fb_device_id = fd;
-
-      backend_egl->egl_surface =
-        eglCreateWindowSurface (edpy,
-                                config,
-                                (NativeWindowType) backend_egl->fb_device_id,
-                                NULL);
-    }
-  else
-    {
-      backend_egl->egl_surface =
-        eglCreateWindowSurface (edpy,
-                                config,
-                                (NativeWindowType) NULL,
-                                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;
-    }
-
-  CLUTTER_NOTE (BACKEND, "Setting context");
-
-  /* Without X we assume we 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);
-
-#endif /* COGL_HAS_XLIB_SUPPORT */
+  g_atexit (clutter_backend_at_exit);
 
   return TRUE;
-
-fail:
-
-  /* NB: We currently only support a single fallback option */
-  if (retry_cookie == 0)
-    {
-      retry_cookie = 1;
-      goto retry;
-    }
-
-  g_set_error (error, CLUTTER_INIT_ERROR,
-               CLUTTER_INIT_ERROR_BACKEND,
-               "%s", error_message);
-
-  return FALSE;
-}
-
-static void
-clutter_backend_egl_ensure_context (ClutterBackend *backend,
-                                    ClutterStage   *stage)
-{
-#ifndef COGL_HAS_XLIB_SUPPORT
-  /* Without X we only have one EGL surface to worry about
-   * so we can assume it is permanently made current and
-   * don't have to do anything here. */
-#else
-  ClutterBackendEGL  *backend_egl = CLUTTER_BACKEND_EGL (backend);
-  ClutterStageWindow *impl;
-
-  if (stage == NULL ||
-      CLUTTER_ACTOR_IN_DESTRUCTION (stage) ||
-      ((impl = _clutter_stage_get_window (stage)) == NULL))
-    {
-      CLUTTER_NOTE (BACKEND, "Clearing EGL context");
-      eglMakeCurrent (backend_egl->edpy,
-                      EGL_NO_SURFACE,
-                      EGL_NO_SURFACE,
-                      EGL_NO_CONTEXT);
-    }
-  else
-    {
-      ClutterStageEGL    *stage_egl;
-      ClutterStageX11    *stage_x11;
-
-      g_assert (impl != NULL);
-
-      CLUTTER_NOTE (MULTISTAGE, "Setting context for stage of type %s [%p]",
-                    g_type_name (G_OBJECT_TYPE (impl)),
-                    impl);
-
-      stage_egl = CLUTTER_STAGE_EGL (impl);
-      stage_x11 = CLUTTER_STAGE_X11 (impl);
-
-      if (backend_egl->egl_context == EGL_NO_CONTEXT)
-        return;
-
-      clutter_x11_trap_x_errors ();
-
-      /* we might get here inside the final dispose cycle, so we
-       * need to handle this gracefully
-       */
-      if (stage_x11->xwin == None ||
-          stage_egl->egl_surface == EGL_NO_SURFACE)
-        {
-          CLUTTER_NOTE (MULTISTAGE,
-                        "Received a stale stage, clearing all context");
-
-          if (backend_egl->dummy_surface == EGL_NO_SURFACE)
-            eglMakeCurrent (backend_egl->edpy,
-                            EGL_NO_SURFACE,
-                            EGL_NO_SURFACE,
-                            EGL_NO_CONTEXT);
-          else
-            eglMakeCurrent (backend_egl->edpy,
-                            backend_egl->dummy_surface,
-                            backend_egl->dummy_surface,
-                            backend_egl->egl_context);
-        }
-      else
-        {
-          CLUTTER_NOTE (MULTISTAGE, "Setting real surface current");
-          eglMakeCurrent (backend_egl->edpy,
-                          stage_egl->egl_surface,
-                          stage_egl->egl_surface,
-                          backend_egl->egl_context);
-        }
-
-      if (clutter_x11_untrap_x_errors ())
-        g_critical ("Unable to make the stage window 0x%x the current "
-                    "EGLX drawable",
-                    (int) stage_x11->xwin);
-    }
-#endif /* COGL_HAS_XLIB_SUPPORT */
 }
 
 #ifndef COGL_HAS_XLIB_SUPPORT
@@ -553,72 +176,26 @@ clutter_backend_egl_finalize (GObject *gobject)
 static void
 clutter_backend_egl_dispose (GObject *gobject)
 {
+  ClutterBackend *backend = CLUTTER_BACKEND (gobject);
+#ifdef HAVE_TSLIB
   ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (gobject);
-#ifdef COGL_HAS_X11_SUPPORT
-  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (gobject);
-#else
-  ClutterStageEGL   *stage_egl = CLUTTER_STAGE_EGL (backend_egl->stage);
 #endif
 
-  /* We chain up before disposing our own resources so that
-     ClutterBackendX11 will destroy all of the stages before we
-     destroy the egl context. Otherwise the actors may try to make GL
-     calls during destruction which causes a crash */
+  /* We chain up before disposing our CoglContext so that we will
+   * destroy all of the stages first. Otherwise the actors may try to
+   * make Cogl calls during destruction which would cause a crash */
   G_OBJECT_CLASS (_clutter_backend_egl_parent_class)->dispose (gobject);
 
-#ifdef HAVE_TSLIB
-  /* XXX: This should be renamed to _clutter_events_tslib_uninit */
-  _clutter_events_egl_uninit (backend_egl);
-#endif
-
-#ifdef COGL_HAS_XLIB_SUPPORT
-  if (backend_egl->dummy_surface != EGL_NO_SURFACE)
-    {
-      eglDestroySurface (backend_egl->edpy, backend_egl->dummy_surface);
-      backend_egl->dummy_surface = EGL_NO_SURFACE;
-    }
-
-  if (backend_egl->dummy_xwin)
-    {
-      XDestroyWindow (backend_x11->xdpy, backend_egl->dummy_xwin);
-      backend_egl->dummy_xwin = None;
-    }
-
-#else /* COGL_HAS_XLIB_SUPPORT */
-
-  if (backend_egl->egl_surface != EGL_NO_SURFACE)
-    {
-      eglDestroySurface (backend_egl->edpy, backend_egl->egl_surface);
-      backend_egl->egl_surface = EGL_NO_SURFACE;
-    }
-
-  if (backend_egl->stage != NULL)
-    {
-      clutter_actor_destroy (CLUTTER_ACTOR (stage_egl->wrapper));
-      backend_egl->stage = NULL;
-    }
-
-  if (backend_egl->fb_device_id != -1)
+  if (backend->cogl_context)
     {
-      close (backend_egl->fb_device_id);
-      backend_egl->fb_device_id = -1;
-    }
-
-#endif /* COGL_HAS_XLIB_SUPPORT */
-
-  if (backend_egl->egl_context)
-    {
-      eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
-      backend_egl->egl_context = NULL;
-    }
-
-  if (backend_egl->edpy)
-    {
-      eglTerminate (backend_egl->edpy);
-      backend_egl->edpy = 0;
+      cogl_object_unref (backend->cogl_context);
+      backend->cogl_context = NULL;
     }
 
 #ifdef HAVE_TSLIB
+  /* XXX: This should be renamed to _clutter_events_tslib_uninit */
+  _clutter_events_egl_uninit (backend_egl);
+
   if (backend_egl->event_timer != NULL)
     {
       g_timer_destroy (backend_egl->event_timer);
@@ -651,85 +228,147 @@ clutter_backend_egl_constructor (GType                  gtype,
   return g_object_ref (backend_singleton);
 }
 
-static gboolean
-check_vblank_env (const char *name)
-{
-  if (clutter_vblank_name && !g_ascii_strcasecmp (clutter_vblank_name, name))
-    return TRUE;
-
-  return FALSE;
-}
-
 static ClutterFeatureFlags
 clutter_backend_egl_get_features (ClutterBackend *backend)
 {
   ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
-  const gchar *egl_extensions = NULL;
-  const gchar *gl_extensions = NULL;
-  ClutterFeatureFlags flags;
-
-  g_assert (backend_egl->egl_context != NULL);
+#ifdef COGL_HAS_XLIB_SUPPORT
+  ClutterBackendClass *parent_class;
+#endif
+  ClutterFeatureFlags flags = 0;
 
 #ifdef COGL_HAS_XLIB_SUPPORT
-  {
-    ClutterBackendClass *parent_class;
+  parent_class = CLUTTER_BACKEND_CLASS (_clutter_backend_egl_parent_class);
 
-    parent_class = CLUTTER_BACKEND_CLASS (_clutter_backend_egl_parent_class);
-    flags = parent_class->get_features (backend);
-    flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
-  }
-#else
-  flags = CLUTTER_FEATURE_STAGE_STATIC;
+  flags = parent_class->get_features (backend);
 #endif
 
-  /* First check for explicit disabling or it set elsewhere (eg NVIDIA) */
-  if (check_vblank_env ("none"))
-    backend_egl->vblank_type = CLUTTER_VBLANK_NONE;
+  if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
+    {
+      CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
+      flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
+    }
   else
-    backend_egl->vblank_type = CLUTTER_VBLANK_SWAP_INTERVAL;
-
-  egl_extensions = eglQueryString (backend_egl->edpy, EGL_EXTENSIONS);
+    {
+      CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
+      flags |= CLUTTER_FEATURE_STAGE_STATIC;
+    }
 
-  if (cogl_clutter_check_extension ("EGL_NOK_swap_region", egl_extensions))
+  if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
     {
-      CLUTTER_NOTE (BACKEND,
-                    "Using EGL_NOK_swap_region for sub_buffer copies");
-      backend_egl->swap_buffers_region =
-        (void *)cogl_get_proc_address ("eglSwapBuffersRegionNOK");
-      backend_egl->can_blit_sub_buffer = TRUE;
-      backend_egl->blit_sub_buffer_is_synchronized = TRUE;
+      CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
+      flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
     }
+  else
+    CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
 
-  gl_extensions = (const gchar *)glGetString (GL_EXTENSIONS);
+  if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
+    {
+      CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events");
+      flags |= CLUTTER_FEATURE_SWAP_EVENTS;
+    }
 
-#if 0 /* XXX need GL_ARB_draw_buffers */
-  if (!backend_egl->swap_buffers_region &&
-      cogl_clutter_check_extension ("GL_EXT_framebuffer_blit", gl_extensions))
+  if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION))
     {
-      CLUTTER_NOTE (BACKEND,
-                    "Using glBlitFramebuffer fallback for sub_buffer copies");
-      backend_egl->blit_framebuffer =
-        (BlitFramebufferProc) cogl_get_proc_address ("glBlitFramebuffer");
+      CLUTTER_NOTE (BACKEND, "Cogl supports swapping buffer regions");
       backend_egl->can_blit_sub_buffer = TRUE;
-      backend_egl->blit_sub_buffer_is_synchronized = FALSE;
     }
+
+  return flags;
+}
+
+#ifdef COGL_HAS_XLIB_SUPPORT
+static XVisualInfo *
+clutter_backend_egl_get_visual_info (ClutterBackendX11 *backend_x11)
+{
+  return cogl_clutter_winsys_xlib_get_visual_info ();
+}
 #endif
 
-  CLUTTER_NOTE (BACKEND, "Checking features\n"
-                "GL_VENDOR: %s\n"
-                "GL_RENDERER: %s\n"
-                "GL_VERSION: %s\n"
-                "EGL_VENDOR: %s\n"
-                "EGL_VERSION: %s\n"
-                "EGL_EXTENSIONS: %s\n",
-                glGetString (GL_VENDOR),
-                glGetString (GL_RENDERER),
-                glGetString (GL_VERSION),
-                eglQueryString (backend_egl->edpy, EGL_VENDOR),
-                eglQueryString (backend_egl->edpy, EGL_VERSION),
-                eglQueryString (backend_egl->edpy, EGL_EXTENSIONS));
+static gboolean
+clutter_backend_egl_create_context (ClutterBackend  *backend,
+                                    GError         **error)
+{
+#ifdef COGL_HAS_XLIB_SUPPORT
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
+#endif
+  CoglSwapChain *swap_chain = NULL;
+  CoglOnscreenTemplate *onscreen_template = NULL;
 
-  return flags;
+  if (backend->cogl_context)
+    return TRUE;
+
+  backend->cogl_renderer = cogl_renderer_new ();
+#ifdef COGL_HAS_XLIB_SUPPORT
+  cogl_renderer_xlib_set_foreign_display (backend->cogl_renderer,
+                                          backend_x11->xdpy);
+#endif
+  if (!cogl_renderer_connect (backend->cogl_renderer, error))
+    goto error;
+
+  swap_chain = cogl_swap_chain_new ();
+#ifdef COGL_HAS_XLIB_SUPPORT
+  cogl_swap_chain_set_has_alpha (swap_chain,
+                                 clutter_x11_get_use_argb_visual ());
+#endif
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_GDL_SUPPORT
+  cogl_swap_chain_set_length (swap_chain, gdl_n_buffers);
+#endif
+
+  onscreen_template = cogl_onscreen_template_new (swap_chain);
+  cogl_object_unref (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 (backend->cogl_renderer,
+                                              onscreen_template,
+                                              error))
+    goto error;
+
+  backend->cogl_display = cogl_display_new (backend->cogl_renderer,
+                                            onscreen_template);
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_GDL_SUPPORT
+  cogl_display_cex100_set_gdl_plane (backend->cogl_display, gdl_plane);
+#endif
+
+  cogl_object_unref (backend->cogl_renderer);
+  cogl_object_unref (onscreen_template);
+
+  if (!cogl_display_setup (backend->cogl_display, error))
+    goto error;
+
+  backend->cogl_context = cogl_context_new (backend->cogl_display, error);
+  if (!backend->cogl_context)
+    goto error;
+
+  /* XXX: eventually this should go away but a lot of Cogl code still
+   * depends on a global default context. */
+  cogl_set_default_context (backend->cogl_context);
+
+  return TRUE;
+
+error:
+  if (backend->cogl_display)
+    {
+      cogl_object_unref (backend->cogl_display);
+      backend->cogl_display = NULL;
+    }
+
+  if (onscreen_template)
+    cogl_object_unref (onscreen_template);
+  if (swap_chain)
+    cogl_object_unref (swap_chain);
+
+  if (backend->cogl_renderer)
+    {
+      cogl_object_unref (backend->cogl_renderer);
+      backend->cogl_renderer = NULL;
+    }
+  return FALSE;
 }
 
 static ClutterStageWindow *
@@ -768,7 +407,8 @@ clutter_backend_egl_create_stage (ClutterBackend  *backend,
     {
       g_set_error (error, CLUTTER_INIT_ERROR,
                    CLUTTER_INIT_ERROR_BACKEND,
-                   "The EGL native backend does not support multiple stages");
+                   "The Cogl backend does not support multiple "
+                   "onscreen windows");
       return backend_egl->stage;
     }
 
@@ -785,57 +425,15 @@ clutter_backend_egl_create_stage (ClutterBackend  *backend,
   return stage;
 }
 
-#ifdef COGL_HAS_XLIB_SUPPORT
-static XVisualInfo *
-clutter_backend_egl_get_visual_info (ClutterBackendX11 *backend_x11)
+static void
+clutter_backend_egl_ensure_context (ClutterBackend *backend,
+                                    ClutterStage   *stage)
 {
-  ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend_x11);
-  XVisualInfo visinfo_template;
-  int template_mask = 0;
-  XVisualInfo *visinfo = NULL;
-  int visinfos_count;
-  EGLint visualid, red_size, green_size, blue_size, alpha_size;
-
-  if (!clutter_backend_egl_create_context (CLUTTER_BACKEND (backend_x11), NULL))
-    return NULL;
-
-  visinfo_template.screen = backend_x11->xscreen_num;
-  template_mask |= VisualScreenMask;
-
-  eglGetConfigAttrib (backend_egl->edpy, backend_egl->egl_config,
-                      EGL_NATIVE_VISUAL_ID, &visualid);
-
-  if (visualid != 0)
-    {
-      visinfo_template.visualid = visualid;
-      template_mask |= VisualIDMask;
-    }
-  else
-    {
-      /* some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID
-       * attribute, so attempt to find the closest match. */
-
-      eglGetConfigAttrib (backend_egl->edpy, backend_egl->egl_config,
-                          EGL_RED_SIZE, &red_size);
-      eglGetConfigAttrib (backend_egl->edpy, backend_egl->egl_config,
-                          EGL_GREEN_SIZE, &green_size);
-      eglGetConfigAttrib (backend_egl->edpy, backend_egl->egl_config,
-                          EGL_BLUE_SIZE, &blue_size);
-      eglGetConfigAttrib (backend_egl->edpy, backend_egl->egl_config,
-                          EGL_ALPHA_SIZE, &alpha_size);
-
-      visinfo_template.depth = red_size + green_size + blue_size + alpha_size;
-      template_mask |= VisualDepthMask;
-    }
+  ClutterStageEGL *stage_egl =
+    CLUTTER_STAGE_EGL (_clutter_stage_get_window (stage));
 
-  visinfo = XGetVisualInfo (backend_x11->xdpy,
-                            template_mask,
-                            &visinfo_template,
-                            &visinfos_count);
-
-  return visinfo;
+  cogl_set_framebuffer (COGL_FRAMEBUFFER (stage_egl->onscreen));
 }
-#endif
 
 static void
 _clutter_backend_egl_class_init (ClutterBackendEGLClass *klass)
@@ -869,29 +467,16 @@ _clutter_backend_egl_class_init (ClutterBackendEGLClass *klass)
 static void
 _clutter_backend_egl_init (ClutterBackendEGL *backend_egl)
 {
-#ifndef COGL_HAS_XLIB_SUPPORT
-
 #ifdef HAVE_TSLIB
   backend_egl->event_timer = g_timer_new ();
 #endif
-
-  backend_egl->fb_device_id = -1;
-
-#else
-
-  backend_egl->egl_context = EGL_NO_CONTEXT;
-  backend_egl->dummy_surface = EGL_NO_SURFACE;
-
-#endif
 }
 
-#ifdef CLUTTER_EGL_BACKEND_GENERIC
 GType
 _clutter_backend_impl_get_type (void)
 {
   return _clutter_backend_egl_get_type ();
 }
-#endif
 
 EGLDisplay
 clutter_eglx_display (void)
@@ -914,5 +499,25 @@ clutter_egl_get_egl_display (void)
       return 0;
     }
 
-  return backend_singleton->edpy;
+  return cogl_context_egl_get_egl_display (backend_singleton->cogl_context);
+}
+
+/* FIXME we should have a CLUTTER_ define for this */
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_GDL_SUPPORT
+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;
+}
+
+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;
 }
+#endif
index c946380..e1b082d 100644 (file)
@@ -57,52 +57,14 @@ G_BEGIN_DECLS
 typedef struct _ClutterBackendEGL       ClutterBackendEGL;
 typedef struct _ClutterBackendEGLClass  ClutterBackendEGLClass;
 
-typedef enum ClutterEGLVBlankType {
-  CLUTTER_VBLANK_NONE = 0,
-  CLUTTER_VBLANK_SWAP_INTERVAL
-} ClutterEGLVBlankType;
-
-typedef void (*BlitFramebufferProc) (GLint      srcX0,
-                                     GLint      srcY0,
-                                     GLint      srcX1,
-                                     GLint      srcY1,
-                                     GLint      dstX0,
-                                     GLint      dstY0,
-                                     GLint      dstX1,
-                                     GLint      dstY1,
-                                     GLbitfield mask,
-                                     GLenum     filter);
-
-typedef EGLBoolean (*SwapBuffersRegionProc) (EGLDisplay dpy,
-                                             EGLSurface surface,
-                                             EGLint numRects,
-                                             const EGLint *rects);
 struct _ClutterBackendEGL
 {
 #ifdef COGL_HAS_XLIB_SUPPORT
   ClutterBackendX11 parent_instance;
 
-  /* EGL Specific */
-  EGLDisplay edpy;
-  EGLContext egl_context;
-  EGLConfig  egl_config;
-
-  Window     dummy_xwin;
-  EGLSurface dummy_surface;
-
 #else /* COGL_HAS_X11_SUPPORT */
-
   ClutterBackend parent_instance;
 
-  /* EGL Specific */
-  EGLDisplay edpy;
-  EGLSurface egl_surface;
-  EGLContext egl_context;
-
-  /* from the backend */
-  gint surface_width;
-  gint surface_height;
-
   /* main stage singleton */
   ClutterStageWindow *stage;
 
@@ -115,20 +77,11 @@ struct _ClutterBackendEGL
   /* event timer */
   GTimer *event_timer;
 
-  /* FB device */
-  gint fb_device_id;
-
 #endif /* COGL_HAS_X11_SUPPORT */
 
-  gint egl_version_major;
-  gint egl_version_minor;
-
-  ClutterEGLVBlankType vblank_type;
+  CoglContext *cogl_context;
 
-  gboolean              can_blit_sub_buffer;
-  BlitFramebufferProc   blit_framebuffer;
-  SwapBuffersRegionProc swap_buffers_region;
-  gboolean              blit_sub_buffer_is_synchronized;
+  gboolean can_blit_sub_buffer;
 };
 
 struct _ClutterBackendEGLClass
@@ -145,10 +98,8 @@ GType _clutter_backend_egl_get_type (void) G_GNUC_CONST;
 void _clutter_events_egl_init   (ClutterBackendEGL *backend);
 void _clutter_events_egl_uninit (ClutterBackendEGL *backend);
 
-void
-_clutter_backend_egl_blit_sub_buffer (ClutterBackendEGL *backend_egl,
-                                      EGLSurface drawable,
-                                      int x, int y, int width, int height);
+G_CONST_RETURN gchar*
+_clutter_backend_egl_get_vblank (void);
 
 G_END_DECLS
 
index 276c479..887494e 100644 (file)
@@ -32,41 +32,36 @@ G_DEFINE_TYPE_WITH_CODE (ClutterStageEGL,
                          G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
                                                 clutter_stage_window_iface_init));
 
-#ifdef COGL_HAS_XLIB_SUPPORT
-
 static void
 clutter_stage_egl_unrealize (ClutterStageWindow *stage_window)
 {
-  ClutterBackend *backend = clutter_get_default_backend ();
-  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
   ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
-  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
 
   CLUTTER_NOTE (BACKEND, "Unrealizing EGL stage [%p]", stage_egl);
 
-  clutter_x11_trap_x_errors ();
-
-  if (stage_egl->egl_surface != EGL_NO_SURFACE)
-    {
-      eglDestroySurface (clutter_egl_get_egl_display (), stage_egl->egl_surface);
-      stage_egl->egl_surface = EGL_NO_SURFACE;
-    }
-
-  _clutter_stage_x11_destroy_window_untrapped (stage_x11);
-
-  XSync (backend_x11->xdpy, False);
+#ifdef COGL_HAS_XLIB_SUPPORT
+  /* chain up to the StageX11 implementation */
+  clutter_stage_window_parent_iface->unrealize (stage_window);
+#endif
 
-  clutter_x11_untrap_x_errors ();
+  cogl_object_unref (stage_egl->onscreen);
+  stage_egl->onscreen = NULL;
 }
 
 static gboolean
 clutter_stage_egl_realize (ClutterStageWindow *stage_window)
 {
-  ClutterStageEGL   *stage_egl = CLUTTER_STAGE_EGL (stage_window);
-  ClutterStageX11   *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-  ClutterBackend    *backend;
+  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
+#ifdef COGL_HAS_XLIB_SUPPORT
+  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
+#endif
+  ClutterBackend *backend;
   ClutterBackendEGL *backend_egl;
-  EGLDisplay         edpy;
+  CoglFramebuffer *framebuffer;
+  GError *error = NULL;
+  gfloat width = 800;
+  gfloat height = 600;
+  const char *clutter_vblank;
 
   CLUTTER_NOTE (BACKEND, "Realizing stage '%s' [%p]",
                 G_OBJECT_TYPE_NAME (stage_egl),
@@ -75,39 +70,48 @@ clutter_stage_egl_realize (ClutterStageWindow *stage_window)
   backend     = clutter_get_default_backend ();
   backend_egl = CLUTTER_BACKEND_EGL (backend);
 
-  edpy = clutter_egl_get_egl_display ();
+#ifdef COGL_HAS_XLIB_SUPPORT
+  clutter_actor_get_size (CLUTTER_ACTOR (stage_x11->wrapper), &width, &height);
+#endif
 
-  if (!_clutter_stage_x11_create_window (stage_x11))
-    return FALSE;
+  stage_egl->onscreen = cogl_onscreen_new (backend->cogl_context,
+                                           width, height);
+#ifdef COGL_HAS_XLIB_SUPPORT
+  if (stage_x11->xwin != None)
+    cogl_onscreen_x11_set_foreign_window_xid (stage_egl->onscreen,
+                                              stage_x11->xwin);
+#endif
+
+  clutter_vblank = _clutter_backend_egl_get_vblank ();
+  if (clutter_vblank && strcmp (clutter_vblank, "none") == 0)
+    cogl_onscreen_set_swap_throttled (stage_egl->onscreen, FALSE);
 
-  if (stage_egl->egl_surface == EGL_NO_SURFACE)
+  framebuffer = COGL_FRAMEBUFFER (stage_egl->onscreen);
+  if (!cogl_framebuffer_allocate (framebuffer, &error))
     {
-      stage_egl->egl_surface =
-        eglCreateWindowSurface (edpy,
-                                backend_egl->egl_config,
-                                (NativeWindowType) stage_x11->xwin,
-                                NULL);
+      g_warning ("Failed to allocate stage: %s", error->message);
+      g_error_free (error);
+      cogl_object_unref (stage_egl->onscreen);
+      stage_egl->onscreen = NULL;
+      return FALSE;
     }
+  /* FIXME: for fullscreen EGL platforms then the size we gave above
+   * will be ignored, so we need to make sure the stage size is
+   * updated to this size. */
 
-  if (stage_egl->egl_surface == EGL_NO_SURFACE)
-    g_warning ("Unable to create an EGL surface");
+#ifdef COGL_HAS_XLIB_SUPPORT
+  if (stage_x11->xwin == None)
+    stage_x11->xwin = cogl_onscreen_x11_get_window_xid (stage_egl->onscreen);
 
   return clutter_stage_egl_parent_iface->realize (stage_window);
+#else
+  return TRUE;
+#endif
 }
 
-#else /* COGL_HAS_XLIB_SUPPORT */
+#ifndef COGL_HAS_XLIB_SUPPORT
 
-static void
-clutter_stage_egl_unrealize (ClutterStageWindow *stage_window)
-{
-}
-
-static gboolean
-clutter_stage_egl_realize (ClutterStageWindow *stage_window)
-{
-  /* the EGL surface is created by the backend */
-  return TRUE;
-}
+/* FIXME: Move this warnings up into clutter-stage.c */
 
 static void
 clutter_stage_egl_set_fullscreen (ClutterStageWindow *stage_window,
@@ -161,14 +165,25 @@ clutter_stage_egl_get_geometry (ClutterStageWindow *stage_window,
                                 ClutterGeometry    *geometry)
 {
   ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
-  ClutterBackendEGL *backend_egl = stage_egl->backend;
 
   if (geometry)
     {
-      geometry->x = geometry->y = 0;
+      if (stage_egl->onscreen)
+        {
+          CoglFramebuffer *framebuffer =
+            COGL_FRAMEBUFFER (stage_egl->onscreen);
+
+          geometry->x = geometry->y = 0;
 
-      geometry->width = backend_egl->surface_width;
-      geometry->height = backend_egl->surface_height;
+          geometry->width = cogl_framebuffer_get_width (framebuffer);
+          geometry->height = cogl_framebuffer_get_height (framebuffer);
+        }
+      else
+        {
+          geometry->x = geometry->y = 0;
+          geometry->width = 800;
+          geometry->height = 600;
+        }
     }
 }
 
@@ -268,30 +283,51 @@ clutter_stage_egl_add_redraw_clip (ClutterStageWindow *stage_window,
   stage_egl->initialized_redraw_clip = TRUE;
 }
 
+/* XXX: This is basically identical to clutter_stage_glx_redraw */
 static void
 clutter_stage_egl_redraw (ClutterStageWindow *stage_window)
 {
   ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
-  ClutterBackend *backend = clutter_get_default_backend ();
-  ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
   ClutterActor *wrapper;
-  EGLSurface egl_surface;
+  ClutterBackend *backend;
+  ClutterBackendEGL *backend_egl;
   gboolean may_use_clipped_redraw;
   gboolean use_clipped_redraw;
+
+  CLUTTER_STATIC_TIMER (painting_timer,
+                        "Redrawing", /* parent */
+                        "Painting actors",
+                        "The time spent painting actors",
+                        0 /* no application private data */);
+  CLUTTER_STATIC_TIMER (swapbuffers_timer,
+                        "Redrawing", /* parent */
+                        "eglSwapBuffers",
+                        "The time spent blocked by eglSwapBuffers",
+                        0 /* no application private data */);
+  CLUTTER_STATIC_TIMER (blit_sub_buffer_timer,
+                        "Redrawing", /* parent */
+                        "egl_blit_sub_buffer",
+                        "The time spent in _egl_blit_sub_buffer",
+                        0 /* no application private data */);
+
 #ifdef COGL_HAS_X11_SUPPORT
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_egl);
 
   wrapper = CLUTTER_ACTOR (stage_x11->wrapper);
-  egl_surface = stage_egl->egl_surface;
 #else
   wrapper = CLUTTER_ACTOR (stage_egl->wrapper);
-  /* Without X we only support one surface and that is associated
-   * with the backend directly instead of the stage */
-  egl_surface = backend_egl->egl_surface;
 #endif
 
+  if (!stage_egl->onscreen)
+    return;
+
+  backend = clutter_get_default_backend ();
+  backend_egl = CLUTTER_BACKEND_EGL (backend);
+
+  CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer);
+
   if (G_LIKELY (backend_egl->can_blit_sub_buffer) &&
-      /* NB: a zero width clip == full stage redraw */
+      /* NB: a zero width redraw clip == full stage redraw */
       stage_egl->bounding_redraw_clip.width != 0 &&
       /* some drivers struggle to get going and produce some junk
        * frames when starting up... */
@@ -303,7 +339,9 @@ clutter_stage_egl_redraw (ClutterStageWindow *stage_window)
       && G_LIKELY (stage_x11->clipped_redraws_cool_off == 0)
 #endif
       )
-    may_use_clipped_redraw = TRUE;
+    {
+      may_use_clipped_redraw = TRUE;
+    }
   else
     may_use_clipped_redraw = FALSE;
 
@@ -327,11 +365,12 @@ clutter_stage_egl_redraw (ClutterStageWindow *stage_window)
   else
     _clutter_stage_do_paint (CLUTTER_STAGE (wrapper), NULL);
 
-  if (clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS &&
-      may_use_clipped_redraw)
+  if (may_use_clipped_redraw &&
+      G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
     {
-      ClutterGeometry *clip = &stage_egl->bounding_redraw_clip;
       static CoglMaterial *outline = NULL;
+      ClutterGeometry *clip = &stage_egl->bounding_redraw_clip;
+      ClutterActor *actor = CLUTTER_ACTOR (wrapper);
       CoglHandle vbo;
       float x_1 = clip->x;
       float x_2 = clip->x + clip->width;
@@ -363,7 +402,7 @@ clutter_stage_egl_redraw (ClutterStageWindow *stage_window)
 
       cogl_push_matrix ();
       cogl_matrix_init_identity (&modelview);
-      _clutter_actor_apply_modelview_transform (wrapper, &modelview);
+      _clutter_actor_apply_modelview_transform (actor, &modelview);
       cogl_set_modelview_matrix (&modelview);
       cogl_set_source (outline);
       cogl_vertex_buffer_draw (vbo, COGL_VERTICES_MODE_LINE_LOOP,
@@ -372,46 +411,52 @@ clutter_stage_egl_redraw (ClutterStageWindow *stage_window)
       cogl_object_unref (vbo);
     }
 
-  cogl_flush ();
+  CLUTTER_TIMER_STOP (_clutter_uprof_context, painting_timer);
 
   /* push on the screen */
   if (use_clipped_redraw)
     {
       ClutterGeometry *clip = &stage_egl->bounding_redraw_clip;
-      ClutterGeometry copy_area;
+      int copy_area[4];
+      ClutterActor *actor;
+
+      /* XXX: It seems there will be a race here in that the stage
+       * window may be resized before the cogl_framebuffer_swap_region
+       * is handled and so we may copy the wrong region. I can't
+       * really see how we can handle this with the current state of X
+       * but at least in this case a full redraw should be queued by
+       * the resize anyway so it should only exhibit temporary
+       * artefacts.
+       */
+
+      actor = CLUTTER_ACTOR (wrapper);
+      copy_area[0] = clip->x;
+      copy_area[1] = clutter_actor_get_height (actor) - clip->y - clip->height;
+      copy_area[2] = clip->width;
+      copy_area[3] = clip->height;
 
       CLUTTER_NOTE (BACKEND,
-                    "_egl_blit_sub_buffer (surface: %p, "
-                                          "x: %d, y: %d, "
-                                          "width: %d, height: %d)",
-                    egl_surface,
-                    stage_egl->bounding_redraw_clip.x,
-                    stage_egl->bounding_redraw_clip.y,
-                    stage_egl->bounding_redraw_clip.width,
-                    stage_egl->bounding_redraw_clip.height);
-
-      copy_area.x = clip->x;
-      copy_area.y = clip->y;
-      copy_area.width = clip->width;
-      copy_area.height = clip->height;
+                    "cogl_framebuffer_swap_region (onscreen: %p, "
+                                                  "x: %d, y: %d, "
+                                                  "width: %d, height: %d)",
+                    stage_egl->onscreen,
+                    copy_area[0], copy_area[1], copy_area[2], copy_area[3]);
+
 
       CLUTTER_TIMER_START (_clutter_uprof_context, blit_sub_buffer_timer);
-      _clutter_backend_egl_blit_sub_buffer (backend_egl,
-                                            egl_surface,
-                                            copy_area.x,
-                                            copy_area.y,
-                                            copy_area.width,
-                                            copy_area.height);
+
+      cogl_framebuffer_swap_region (COGL_FRAMEBUFFER (stage_egl->onscreen),
+                                    copy_area, 1);
+
       CLUTTER_TIMER_STOP (_clutter_uprof_context, blit_sub_buffer_timer);
     }
   else
     {
-      CLUTTER_NOTE (BACKEND, "eglwapBuffers (display: %p, surface: %p)",
-                    backend_egl->edpy,
-                    egl_surface);
+      CLUTTER_NOTE (BACKEND, "cogl_framebuffer_swap_buffers (onscreen: %p)",
+                    stage_egl->onscreen);
 
       CLUTTER_TIMER_START (_clutter_uprof_context, swapbuffers_timer);
-      eglSwapBuffers (backend_egl->edpy, egl_surface);
+      cogl_framebuffer_swap_buffers (COGL_FRAMEBUFFER (stage_egl->onscreen));
       CLUTTER_TIMER_STOP (_clutter_uprof_context, swapbuffers_timer);
     }
 
@@ -467,25 +512,14 @@ _clutter_stage_egl_class_init (ClutterStageEGLClass *klass)
 
   gobject_class->dispose = clutter_stage_egl_dispose;
 }
-
-static void
-_clutter_stage_egl_init (ClutterStageEGL *stage)
-{
-  stage->egl_surface = EGL_NO_SURFACE;
-}
-
-#else /* COGL_HAS_X11_SUPPORT */
-
+#else
 static void
 _clutter_stage_egl_class_init (ClutterStageEGLClass *klass)
 {
 }
+#endif /* COGL_HAS_X11_SUPPORT */
 
 static void
 _clutter_stage_egl_init (ClutterStageEGL *stage)
 {
-  /* Without X we only support one surface and that is associated
-   * with the backend directly instead of the stage */
 }
-
-#endif /* COGL_HAS_X11_SUPPORT */
index 86e075e..e080f3c 100644 (file)
@@ -36,8 +36,6 @@ struct _ClutterStageEGL
 
   ClutterStageX11 parent_instance;
 
-  EGLSurface egl_surface;
-
 #else
 
   GObject parent_instance;
@@ -50,6 +48,8 @@ struct _ClutterStageEGL
 
 #endif
 
+  CoglOnscreen *onscreen;
+
   /* We only enable clipped redraws after 2 frames, since we've seen
    * a lot of drivers can struggle to get going and may output some
    * junk frames to start with. */
index a1d6eae..0b64aa4 100644 (file)
@@ -56,16 +56,9 @@ struct _ClutterBackendGLX
 {
   ClutterBackendX11 parent_instance;
 
-  int                    error_base;
-  int                    event_base;
+  CoglContext *cogl_context;
 
-  CoglContext           *cogl_context;
-
-  /* Vblank stuff */
-  ClutterGLXVBlankType   vblank_type;
-  unsigned int           last_video_sync_count;
-
-  gboolean               can_blit_sub_buffer;
+  gboolean can_blit_sub_buffer;
 
   /* props */
   Atom atom_WM_STATE;
index 36e6916..d0553b0 100644 (file)
@@ -1359,111 +1359,6 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
 }
 
 void
-_clutter_stage_x11_destroy_window_untrapped (ClutterStageX11 *stage_x11)
-{
-  Window xwin = stage_x11->xwin;
-
-  if (clutter_stages_by_xid != NULL)
-    {
-      CLUTTER_NOTE (BACKEND, "Removing X11 stage 0x%x [%p]",
-                    (unsigned int) xwin,
-                    stage_x11);
-
-      g_hash_table_remove (clutter_stages_by_xid, GINT_TO_POINTER (xwin));
-    }
-
-  if (!stage_x11->is_foreign_xwin && xwin != None)
-    {
-      ClutterBackendX11 *backend_x11 = stage_x11->backend;
-
-      g_assert (clutter_stages_by_xid != NULL);
-
-      XDestroyWindow (backend_x11->xdpy, xwin);
-      stage_x11->xwin = None;
-    }
-  else
-    stage_x11->xwin = None;
-}
-
-void
-_clutter_stage_x11_destroy_window (ClutterStageX11 *stage_x11)
-{
-  if (stage_x11->xwin == None)
-    return;
-
-  clutter_x11_trap_x_errors ();
-
-  _clutter_stage_x11_destroy_window_untrapped (stage_x11);
-
-  clutter_x11_untrap_x_errors ();
-}
-
-gboolean
-_clutter_stage_x11_create_window (ClutterStageX11 *stage_x11)
-{
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
-  XSetWindowAttributes xattr;
-  XVisualInfo *xvisinfo;
-  unsigned long mask;
-  gfloat width, height;
-
-  if (stage_x11->xwin != None)
-    return TRUE;
-
-  CLUTTER_NOTE (MISC, "Creating stage X window");
-
-  xvisinfo = _clutter_backend_x11_get_visual_info (backend_x11);
-  if (xvisinfo == NULL)
-    {
-      g_critical ("Unable to find suitable GL visual.");
-      return FALSE;
-    }
-
-  /* window attributes */
-  xattr.background_pixel = WhitePixel (backend_x11->xdpy,
-                                       backend_x11->xscreen_num);
-  xattr.border_pixel = 0;
-  xattr.colormap = XCreateColormap (backend_x11->xdpy,
-                                    backend_x11->xwin_root,
-                                    xvisinfo->visual,
-                                    AllocNone);
-  mask = CWBorderPixel | CWColormap;
-
-  /* Call get_size - this will either get the geometry size (which
-   * before we create the window is set to 640x480), or if a size
-   * is set, it will get that. This lets you set a size on the
-   * stage before it's realized.
-   *
-   * we also round to the nearest integer because stage sizes
-   * should always be in pixels
-   */
-  clutter_actor_get_size (CLUTTER_ACTOR (stage_x11->wrapper), &width, &height);
-  stage_x11->xwin_width = floorf (width + 0.5);
-  stage_x11->xwin_height = floorf (height + 0.5);
-
-  stage_x11->xwin = XCreateWindow (backend_x11->xdpy,
-                                   backend_x11->xwin_root,
-                                   0, 0,
-                                   stage_x11->xwin_width,
-                                   stage_x11->xwin_height,
-                                   0,
-                                   xvisinfo->depth,
-                                   InputOutput,
-                                   xvisinfo->visual,
-                                   mask, &xattr);
-
-  CLUTTER_NOTE (BACKEND, "Stage [%p], window: 0x%x, size: %dx%d",
-                stage_x11,
-                (unsigned int) stage_x11->xwin,
-                stage_x11->xwin_width,
-                stage_x11->xwin_height);
-
-  XFree (xvisinfo);
-
-  return TRUE;
-}
-
-void
 _clutter_stage_x11_set_user_time (ClutterStageX11 *stage_x11,
                                   guint32          user_time)
 {
index f2621f9..71732f5 100644 (file)
@@ -81,9 +81,6 @@ struct _ClutterStageX11Class
 GType _clutter_stage_x11_get_type (void) G_GNUC_CONST;
 
 /* Private to subclasses */
-gboolean        _clutter_stage_x11_create_window                (ClutterStageX11 *stage_x11);
-void            _clutter_stage_x11_destroy_window_untrapped     (ClutterStageX11 *stage_x11);
-void            _clutter_stage_x11_destroy_window               (ClutterStageX11 *stage_x11);
 void            _clutter_stage_x11_set_user_time                (ClutterStageX11 *stage_x11,
                                                                  guint32          user_time);
 gboolean        _clutter_stage_x11_get_root_coords              (ClutterStageX11 *stage_x11,
index 65d044f..4e98302 100644 (file)
@@ -459,6 +459,8 @@ AS_IF([test "x$SUPPORT_GLX" = "x1"],
 
         AC_DEFINE([HAVE_CLUTTER_GLX], [1], [Have the GLX backend])
 
+        AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], [Cogl can create its own OpenGL context])
+
         AC_CHECK_HEADERS([GL/glx.h],
                          [],
                          [AC_MSG_ERROR([Unable to locate required GLX headers])])
@@ -489,12 +491,14 @@ AS_IF([test "x$SUPPORT_EGL_PLATFORM_POWERVR_X11" = "x1"],
       [
         AC_DEFINE([COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT], [1],
                   [Cogl supports OpenGL[ES] using the EGL API with PowerVR X11 platform typedefs])
+        AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], [Cogl can create its own OpenGL context])
       ])
 
 AS_IF([test "x$SUPPORT_EGL_PLATFORM_POWERVR_NULL" = "x1"],
       [
         AC_DEFINE([COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT], [1],
                   [Cogl supports OpenGL[ES] using the EGL API with PowerVR NULL platform typedefs])
+        AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], [Cogl can create its own OpenGL context])
       ])
 
 AS_IF([test "x$SUPPORT_EGL_PLATFORM_POWERVR_GDL" = "x1"],