[clutter/wip/cogl-winsys-egl: 2/21] Moves all EGL code down from Clutter to Cogl
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/cogl-winsys-egl: 2/21] Moves all EGL code down from Clutter to Cogl
- Date: Tue, 3 May 2011 16:15:59 +0000 (UTC)
commit ad2d62bb520d9db732da616ddcde7bfb251b07db
Author: Robert Bragg <robert linux intel com>
Date: Fri Feb 25 00:31:41 2011 +0000
Moves all EGL code down from Clutter to Cogl
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.
clutter/Makefile.am | 4 -
clutter/cogl/cogl/Makefile.am | 9 +-
clutter/cogl/cogl/cogl-context.c | 9 +
clutter/cogl/cogl/cogl-context.h | 17 +
clutter/cogl/cogl/winsys/cogl-winsys-egl.c | 1054 +++++++++++++++++++++++-
clutter/cogl/cogl/winsys/cogl-winsys-private.h | 5 +
clutter/egl/clutter-backend-cex100.c | 369 ---------
clutter/egl/clutter-backend-cex100.h | 60 --
clutter/egl/clutter-backend-egl.c | 762 ++++-------------
clutter/egl/clutter-backend-egl.h | 57 +--
clutter/egl/clutter-stage-egl.c | 229 +++---
clutter/egl/clutter-stage-egl.h | 4 +-
clutter/glx/clutter-backend-glx.h | 11 +-
clutter/x11/clutter-stage-x11.c | 105 ---
clutter/x11/clutter-stage-x11.h | 3 -
configure.ac | 4 +
16 files changed, 1405 insertions(+), 1297 deletions(-)
---
diff --git a/clutter/Makefile.am b/clutter/Makefile.am
index 480474d..d171178 100644
--- a/clutter/Makefile.am
+++ b/clutter/Makefile.am
@@ -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
diff --git a/clutter/cogl/cogl/Makefile.am b/clutter/cogl/cogl/Makefile.am
index 426b59a..335f21d 100644
--- a/clutter/cogl/cogl/Makefile.am
+++ b/clutter/cogl/cogl/Makefile.am
@@ -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 += \
diff --git a/clutter/cogl/cogl/cogl-context.c b/clutter/cogl/cogl/cogl-context.c
index ac76d4f..e1b18f6 100644
--- a/clutter/cogl/cogl/cogl-context.c
+++ b/clutter/cogl/cogl/cogl-context.c
@@ -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
+
diff --git a/clutter/cogl/cogl/cogl-context.h b/clutter/cogl/cogl/cogl-context.h
index 9394fbf..7cd0785 100644
--- a/clutter/cogl/cogl/cogl-context.h
+++ b/clutter/cogl/cogl/cogl-context.h
@@ -33,6 +33,17 @@
#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.c b/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
index bafafc0..d5231ba 100644
--- a/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
+++ b/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
@@ -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
@@ -16,9 +16,12 @@
* 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
@@ -27,19 +30,1058 @@
#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_wait_for_vblank (void)
+{
+ /* Unsupported feature */
+}
+
+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;
+}
diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-private.h b/clutter/cogl/cogl/winsys/cogl-winsys-private.h
index 8d56bea..4f3d494 100644
--- a/clutter/cogl/cogl/winsys/cogl-winsys-private.h
+++ b/clutter/cogl/cogl/winsys/cogl-winsys-private.h
@@ -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-egl.c b/clutter/egl/clutter-backend-egl.c
index 2af37de..c09e19a 100644
--- a/clutter/egl/clutter-backend-egl.c
+++ b/clutter/egl/clutter-backend-egl.c
@@ -48,12 +48,20 @@
#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,23 @@ 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);
+ if (backend->cogl_context)
+ cogl_object_unref (backend->cogl_context);
+
#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)
- {
- 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;
- }
-
-#ifdef HAVE_TSLIB
if (backend_egl->event_timer != NULL)
{
g_timer_destroy (backend_egl->event_timer);
@@ -651,85 +225,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 +404,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 +422,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 +464,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 +496,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
diff --git a/clutter/egl/clutter-backend-egl.h b/clutter/egl/clutter-backend-egl.h
index c946380..e1b082d 100644
--- a/clutter/egl/clutter-backend-egl.h
+++ b/clutter/egl/clutter-backend-egl.h
@@ -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
diff --git a/clutter/egl/clutter-stage-egl.c b/clutter/egl/clutter-stage-egl.c
index 276c479..af5eff3 100644
--- a/clutter/egl/clutter-stage-egl.c
+++ b/clutter/egl/clutter-stage-egl.c
@@ -32,41 +32,31 @@ 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);
-
- 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 +65,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 */
-
-static void
-clutter_stage_egl_unrealize (ClutterStageWindow *stage_window)
-{
-}
+#ifndef COGL_HAS_XLIB_SUPPORT
-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 +160,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 +278,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 +334,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 +360,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 +397,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 +406,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 +507,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 */
diff --git a/clutter/egl/clutter-stage-egl.h b/clutter/egl/clutter-stage-egl.h
index 86e075e..e080f3c 100644
--- a/clutter/egl/clutter-stage-egl.h
+++ b/clutter/egl/clutter-stage-egl.h
@@ -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. */
diff --git a/clutter/glx/clutter-backend-glx.h b/clutter/glx/clutter-backend-glx.h
index a1d6eae..0b64aa4 100644
--- a/clutter/glx/clutter-backend-glx.h
+++ b/clutter/glx/clutter-backend-glx.h
@@ -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;
diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c
index 36e6916..d0553b0 100644
--- a/clutter/x11/clutter-stage-x11.c
+++ b/clutter/x11/clutter-stage-x11.c
@@ -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)
{
diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h
index f2621f9..71732f5 100644
--- a/clutter/x11/clutter-stage-x11.h
+++ b/clutter/x11/clutter-stage-x11.h
@@ -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,
diff --git a/configure.ac b/configure.ac
index 65d044f..4e98302 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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"],
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]