[cogl/wip/runtime-egl-platform: 4/12] winsys: Move X11/Xlib-specific code out of the EGL winsys
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/runtime-egl-platform: 4/12] winsys: Move X11/Xlib-specific code out of the EGL winsys
- Date: Tue, 13 Dec 2011 12:26:07 +0000 (UTC)
commit cf438bdbe4005c58cf37c25cb6e30cc149fee138
Author: Neil Roberts <neil linux intel com>
Date: Mon Dec 12 15:59:35 2011 +0000
winsys: Move X11/Xlib-specific code out of the EGL winsys
All of the X11/Xlib-specific code now lives in the EGL_X11 winsys.
cogl/winsys/cogl-winsys-egl-private.h | 38 +-
cogl/winsys/cogl-winsys-egl-x11.c | 676 ++++++++++++++++++++++++++++++
cogl/winsys/cogl-winsys-egl.c | 745 ++++-----------------------------
3 files changed, 776 insertions(+), 683 deletions(-)
---
diff --git a/cogl/winsys/cogl-winsys-egl-private.h b/cogl/winsys/cogl-winsys-egl-private.h
index 9d51d12..95fc011 100644
--- a/cogl/winsys/cogl-winsys-egl-private.h
+++ b/cogl/winsys/cogl-winsys-egl-private.h
@@ -28,9 +28,6 @@
#include "cogl-winsys-private.h"
#include "cogl-context.h"
#include "cogl-context-private.h"
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-#include "cogl-xlib-renderer-private.h"
-#endif
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
#include <wayland-client.h>
#include <wayland-egl.h>
@@ -49,8 +46,25 @@ typedef struct _CoglWinsysEGLVtable
EGLint *attribs,
GError **error);
+ gboolean
+ (* context_created) (CoglDisplay *display,
+ GError **error);
+
void
(* cleanup_context) (CoglDisplay *display);
+
+ gboolean
+ (* context_init) (CoglContext *context, GError **error);
+
+ void
+ (* context_deinit) (CoglContext *context);
+
+ gboolean
+ (* onscreen_init) (CoglOnscreen *onscreen,
+ EGLConfig config,
+ GError **error);
+ void
+ (* onscreen_deinit) (CoglOnscreen *onscreen);
} CoglWinsysEGLVtable;
typedef enum _CoglEGLWinsysFeature
@@ -87,7 +101,7 @@ typedef struct _CoglRendererEGL
/* vtable for platform specific parts */
const CoglWinsysEGLVtable *platform_vtable;
- /* Function pointers for GLX specific extensions */
+ /* Function pointers for EGL specific extensions */
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d)
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
@@ -104,10 +118,6 @@ typedef struct _CoglRendererEGL
typedef struct _CoglDisplayEGL
{
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- Window dummy_xwin;
-#endif
-
EGLContext egl_context;
EGLSurface dummy_surface;
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
@@ -137,20 +147,8 @@ typedef struct _CoglContextEGL
EGLSurface current_surface;
} CoglContextEGL;
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-typedef struct _CoglOnscreenXlib
-{
- Window xwin;
- gboolean is_foreign_xwin;
-} CoglOnscreenXlib;
-#endif
-
typedef struct _CoglOnscreenEGL
{
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- CoglOnscreenXlib _parent;
-#endif
-
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
struct wl_egl_window *wayland_egl_native_window;
struct wl_surface *wayland_surface;
diff --git a/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/winsys/cogl-winsys-egl-x11.c
index c8991ba..3a646e9 100644
--- a/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/winsys/cogl-winsys-egl-x11.c
@@ -29,8 +29,657 @@
#include "config.h"
#endif
+#include <X11/Xlib.h>
+
#include "cogl-winsys-egl-x11-private.h"
#include "cogl-winsys-egl-private.h"
+#include "cogl-xlib-renderer-private.h"
+#include "cogl-xlib-renderer.h"
+#include "cogl-framebuffer-private.h"
+#include "cogl-onscreen-private.h"
+#include "cogl-display-private.h"
+#include "cogl-renderer-private.h"
+
+#include "cogl-texture-pixmap-x11-private.h"
+#include "cogl-texture-2d-private.h"
+
+#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
+
+static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
+
+typedef struct _CoglDisplayXlib
+{
+ Window dummy_xwin;
+} CoglDisplayXlib;
+
+typedef struct _CoglOnscreenXlib
+{
+ Window xwin;
+ gboolean is_foreign_xwin;
+} CoglOnscreenXlib;
+
+#ifdef EGL_KHR_image_pixmap
+typedef struct _CoglTexturePixmapEGL
+{
+ EGLImageKHR image;
+ CoglTexture *texture;
+} CoglTexturePixmapEGL;
+#endif
+
+static CoglOnscreen *
+find_onscreen_for_xid (CoglContext *context, guint32 xid)
+{
+ GList *l;
+
+ for (l = context->framebuffers; l; l = l->next)
+ {
+ CoglFramebuffer *framebuffer = l->data;
+ CoglOnscreenEGL *egl_onscreen;
+ CoglOnscreenXlib *xlib_onscreen;
+
+ if (!framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+ continue;
+
+ egl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;
+ xlib_onscreen = egl_onscreen->platform;
+ if (xlib_onscreen->xwin == (Window)xid)
+ return COGL_ONSCREEN (framebuffer);
+ }
+
+ return NULL;
+}
+
+static CoglFilterReturn
+event_filter_cb (XEvent *xevent, void *data)
+{
+ CoglContext *context = data;
+
+ if (xevent->type == ConfigureNotify)
+ {
+ CoglOnscreen *onscreen =
+ find_onscreen_for_xid (context, xevent->xconfigure.window);
+
+ if (onscreen)
+ {
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+
+ _cogl_framebuffer_winsys_update_size (framebuffer,
+ xevent->xconfigure.width,
+ xevent->xconfigure.height);
+ }
+ }
+
+ return COGL_FILTER_CONTINUE;
+}
+
+static XVisualInfo *
+get_visual_info (CoglDisplay *display, EGLConfig egl_config)
+{
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (display->renderer);
+ 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;
+}
+
+static void
+_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
+{
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+
+ _cogl_xlib_renderer_disconnect (renderer);
+
+ eglTerminate (egl_renderer->edpy);
+
+ g_slice_free (CoglRendererEGL, egl_renderer);
+}
+
+static gboolean
+_cogl_winsys_renderer_connect (CoglRenderer *renderer,
+ GError **error)
+{
+ CoglRendererEGL *egl_renderer;
+ CoglXlibRenderer *xlib_renderer;
+
+ renderer->winsys = g_slice_new0 (CoglRendererEGL);
+ egl_renderer = renderer->winsys;
+ xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
+
+ egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
+
+ if (!_cogl_xlib_renderer_connect (renderer, error))
+ goto error;
+
+ egl_renderer->edpy =
+ eglGetDisplay ((NativeDisplayType) xlib_renderer->xdpy);
+
+ if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
+ goto error;
+
+ return TRUE;
+
+error:
+ _cogl_winsys_renderer_disconnect (renderer);
+ return FALSE;
+}
+
+static gboolean
+_cogl_winsys_egl_display_setup (CoglDisplay *display,
+ GError **error)
+{
+ CoglDisplayEGL *egl_display = display->winsys;
+ CoglDisplayXlib *xlib_display;
+
+ xlib_display = g_slice_new0 (CoglDisplayXlib);
+ egl_display->platform = xlib_display;
+
+ return TRUE;
+}
+
+static void
+_cogl_winsys_egl_display_destroy (CoglDisplay *display)
+{
+ CoglDisplayEGL *egl_display = display->winsys;
+
+ g_slice_free (CoglDisplayXlib, egl_display->platform);
+}
+
+static gboolean
+_cogl_winsys_egl_context_init (CoglContext *context,
+ GError **error)
+{
+ cogl_xlib_renderer_add_filter (context->display->renderer,
+ event_filter_cb,
+ context);
+
+ context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
+ COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
+ COGL_FLAGS_SET (context->winsys_features,
+ COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
+ TRUE);
+
+ return TRUE;
+}
+
+static void
+_cogl_winsys_egl_context_deinit (CoglContext *context)
+{
+ cogl_xlib_renderer_remove_filter (context->display->renderer,
+ event_filter_cb,
+ context);
+}
+
+static gboolean
+_cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
+ EGLConfig egl_config,
+ GError **error)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = framebuffer->context;
+ CoglDisplay *display = context->display;
+ CoglRenderer *renderer = display->renderer;
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (renderer);
+ CoglOnscreenXlib *xlib_onscreen;
+ CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+ Window xwin;
+
+ /* 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_xlib_renderer_trap_errors (display->renderer, &state);
+
+ status = XGetWindowAttributes (xlib_renderer->xdpy, xwin, &attr);
+ xerror = _cogl_xlib_renderer_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);
+
+ /* Make sure the app selects for the events we require... */
+ onscreen->foreign_update_mask_callback (onscreen,
+ COGL_ONSCREEN_X11_EVENT_MASK,
+ onscreen->
+ foreign_update_mask_data);
+ }
+ 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_xlib_renderer_trap_errors (display->renderer, &state);
+
+ xvisinfo = get_visual_info (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);
+ xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
+
+ mask = CWBorderPixel | CWColormap | CWEventMask;
+
+ xwin = XCreateWindow (xlib_renderer->xdpy,
+ DefaultRootWindow (xlib_renderer->xdpy),
+ 0, 0,
+ width, height,
+ 0,
+ xvisinfo->depth,
+ InputOutput,
+ xvisinfo->visual,
+ mask, &xattr);
+
+ XFree (xvisinfo);
+
+ XSync (xlib_renderer->xdpy, False);
+ xerror =
+ _cogl_xlib_renderer_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;
+ }
+ }
+
+ xlib_onscreen = g_slice_new (CoglOnscreenXlib);
+ egl_onscreen->platform = xlib_onscreen;
+
+ xlib_onscreen->xwin = xwin;
+ xlib_onscreen->is_foreign_xwin = onscreen->foreign_xid ? TRUE : FALSE;
+
+ egl_onscreen->egl_surface =
+ eglCreateWindowSurface (egl_renderer->edpy,
+ egl_config,
+ (NativeWindowType) xlib_onscreen->xwin,
+ NULL);
+
+ return TRUE;
+}
+
+static void
+_cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = framebuffer->context;
+ CoglRenderer *renderer = context->display->renderer;
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (renderer);
+ CoglXlibTrapState old_state;
+ CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+ CoglOnscreenXlib *xlib_onscreen = egl_onscreen->platform;
+
+ _cogl_xlib_renderer_trap_errors (renderer, &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_renderer_untrap_errors (renderer,
+ &old_state) != Success)
+ g_warning ("X Error while destroying X window");
+
+ g_slice_free (CoglOnscreenXlib, xlib_onscreen);
+}
+
+static void
+_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
+ gboolean visibility)
+{
+ CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+ CoglRenderer *renderer = context->display->renderer;
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (renderer);
+ CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
+ CoglOnscreenXlib *xlib_onscreen = onscreen_egl->platform;
+
+ if (visibility)
+ XMapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
+ else
+ XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
+}
+
+static guint32
+_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
+{
+ CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+ CoglOnscreenXlib *xlib_onscreen = egl_onscreen->platform;
+
+ return xlib_onscreen->xwin;
+}
+
+static gboolean
+_cogl_winsys_egl_context_created (CoglDisplay *display,
+ GError **error)
+{
+ CoglRenderer *renderer = display->renderer;
+ CoglDisplayEGL *egl_display = display->winsys;
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (renderer);
+ CoglDisplayXlib *xlib_display = egl_display->platform;
+ XVisualInfo *xvisinfo;
+ XSetWindowAttributes attrs;
+ const char *error_message;
+
+ xvisinfo = get_visual_info (display, egl_display->egl_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 (egl_renderer->edpy,
+ egl_display->egl_config,
+ (NativeWindowType) xlib_display->dummy_xwin,
+ NULL);
+
+ if (egl_display->dummy_surface == EGL_NO_SURFACE)
+ {
+ error_message = "Unable to create an EGL surface";
+ goto fail;
+ }
+
+ if (!eglMakeCurrent (egl_renderer->edpy,
+ egl_display->dummy_surface,
+ egl_display->dummy_surface,
+ egl_display->egl_context))
+ {
+ error_message = "Unable to eglMakeCurrent with dummy surface";
+ goto fail;
+ }
+
+ return TRUE;
+
+fail:
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_CREATE_CONTEXT,
+ "%s", error_message);
+ return FALSE;
+}
+
+static void
+_cogl_winsys_egl_cleanup_context (CoglDisplay *display)
+{
+ CoglDisplayEGL *egl_display = display->winsys;
+ CoglDisplayXlib *xlib_display = egl_display->platform;
+ CoglRenderer *renderer = display->renderer;
+ CoglXlibRenderer *xlib_renderer =
+ _cogl_xlib_renderer_get_data (renderer);
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+
+ 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;
+ }
+}
+
+/* XXX: This is a particularly hacky _cogl_winsys interface... */
+static XVisualInfo *
+_cogl_winsys_xlib_get_visual_info (void)
+{
+ CoglDisplayEGL *egl_display;
+
+ _COGL_GET_CONTEXT (ctx, NULL);
+
+ _COGL_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);
+}
+
+#ifdef EGL_KHR_image_pixmap
+
+static gboolean
+_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
+{
+ CoglTexturePixmapEGL *egl_tex_pixmap;
+ EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
+ CoglPixelFormat texture_format;
+ CoglRendererEGL *egl_renderer;
+
+ /* FIXME: It should be possible to get to a CoglContext from any
+ * CoglTexture pointer. */
+ _COGL_GET_CONTEXT (ctx, FALSE);
+
+ egl_renderer = ctx->display->renderer->winsys;
+
+ if (!(egl_renderer->private_features &
+ COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) ||
+ !(ctx->private_feature_flags &
+ COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE))
+ {
+ tex_pixmap->winsys = NULL;
+ return FALSE;
+ }
+
+ egl_tex_pixmap = g_new0 (CoglTexturePixmapEGL, 1);
+
+ egl_tex_pixmap->image =
+ _cogl_egl_create_image (ctx,
+ EGL_NATIVE_PIXMAP_KHR,
+ (EGLClientBuffer)tex_pixmap->pixmap,
+ attribs);
+ if (egl_tex_pixmap->image == EGL_NO_IMAGE_KHR)
+ {
+ g_free (egl_tex_pixmap);
+ return FALSE;
+ }
+
+ texture_format = (tex_pixmap->depth >= 32 ?
+ COGL_PIXEL_FORMAT_RGBA_8888_PRE :
+ COGL_PIXEL_FORMAT_RGB_888);
+
+ egl_tex_pixmap->texture = COGL_TEXTURE (
+ _cogl_egl_texture_2d_new_from_image (ctx,
+ tex_pixmap->width,
+ tex_pixmap->height,
+ texture_format,
+ egl_tex_pixmap->image,
+ NULL));
+
+ tex_pixmap->winsys = egl_tex_pixmap;
+
+ return TRUE;
+}
+
+static void
+_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
+{
+ CoglTexturePixmapEGL *egl_tex_pixmap;
+
+ /* FIXME: It should be possible to get to a CoglContext from any
+ * CoglTexture pointer. */
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+ if (!tex_pixmap->winsys)
+ return;
+
+ egl_tex_pixmap = tex_pixmap->winsys;
+
+ if (egl_tex_pixmap->texture)
+ cogl_object_unref (egl_tex_pixmap->texture);
+
+ if (egl_tex_pixmap->image != EGL_NO_IMAGE_KHR)
+ _cogl_egl_destroy_image (ctx, egl_tex_pixmap->image);
+
+ tex_pixmap->winsys = NULL;
+ g_free (egl_tex_pixmap);
+}
+
+static gboolean
+_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
+ gboolean needs_mipmap)
+{
+ if (needs_mipmap)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
+{
+}
+
+static CoglHandle
+_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+{
+ CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys;
+
+ return egl_tex_pixmap->texture;
+}
+
+#endif /* EGL_KHR_image_pixmap */
+
+static const CoglWinsysEGLVtable
+_cogl_winsys_egl_vtable =
+ {
+ .display_setup = _cogl_winsys_egl_display_setup,
+ .display_destroy = _cogl_winsys_egl_display_destroy,
+ .context_created = _cogl_winsys_egl_context_created,
+ .cleanup_context = _cogl_winsys_egl_cleanup_context,
+ .context_init = _cogl_winsys_egl_context_init,
+ .context_deinit = _cogl_winsys_egl_context_deinit,
+ .onscreen_init = _cogl_winsys_egl_onscreen_init,
+ .onscreen_deinit = _cogl_winsys_egl_onscreen_deinit
+ };
const CoglWinsysVtable *
_cogl_winsys_egl_x11_get_vtable (void)
@@ -48,6 +697,33 @@ _cogl_winsys_egl_x11_get_vtable (void)
vtable.id = COGL_WINSYS_ID_EGL_X11;
vtable.name = "EGL_X11";
+ vtable.renderer_connect = _cogl_winsys_renderer_connect;
+ vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect;
+
+ vtable.onscreen_set_visibility =
+ _cogl_winsys_onscreen_set_visibility;
+
+ vtable.onscreen_x11_get_window_xid =
+ _cogl_winsys_onscreen_x11_get_window_xid;
+
+ vtable.xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info;
+
+#ifdef EGL_KHR_image_pixmap
+ /* X11 tfp support... */
+ /* XXX: instead of having a rather monolithic winsys vtable we could
+ * perhaps look for a way to separate these... */
+ vtable.texture_pixmap_x11_create =
+ _cogl_winsys_texture_pixmap_x11_create;
+ vtable.texture_pixmap_x11_free =
+ _cogl_winsys_texture_pixmap_x11_free;
+ vtable.texture_pixmap_x11_update =
+ _cogl_winsys_texture_pixmap_x11_update;
+ vtable.texture_pixmap_x11_damage_notify =
+ _cogl_winsys_texture_pixmap_x11_damage_notify;
+ vtable.texture_pixmap_x11_get_texture =
+ _cogl_winsys_texture_pixmap_x11_get_texture;
+#endif /* EGL_KHR_image_pixmap) */
+
vtable_inited = TRUE;
}
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index abd43cb..674f5f6 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -40,15 +40,6 @@
#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-xlib-renderer-private.h"
-#include "cogl-xlib-renderer.h"
-#endif
-
-#ifdef COGL_HAS_XLIB_SUPPORT
-#include "cogl-texture-pixmap-x11-private.h"
-#include "cogl-texture-2d-private.h"
-#endif
#include "cogl-private.h"
@@ -69,22 +60,8 @@
#include <glib/gi18n-lib.h>
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-#include <X11/Xlib.h>
-
-#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
-#endif
-
#define MAX_EGL_CONFIG_ATTRIBS 30
-#ifdef EGL_KHR_image_pixmap
-typedef struct _CoglTexturePixmapEGL
-{
- EGLImageKHR image;
- CoglTexture *texture;
-} CoglTexturePixmapEGL;
-#endif
-
/* Define a set of arrays containing the functions required from GL
for each winsys feature */
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
@@ -144,52 +121,6 @@ cogl_android_set_native_window (ANativeWindow *window)
}
#endif
-#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 (XEvent *xevent, void *data)
-{
- CoglContext *context = data;
-
- if (xevent->type == ConfigureNotify)
- {
- CoglOnscreen *onscreen =
- find_onscreen_for_xid (context, xevent->xconfigure.window);
-
- if (onscreen)
- {
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-
- _cogl_framebuffer_winsys_update_size (framebuffer,
- xevent->xconfigure.width,
- xevent->xconfigure.height);
- }
- }
-
- return COGL_FILTER_CONTINUE;
-}
-#endif /* COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT */
-
static void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
{
@@ -201,11 +132,6 @@ _cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
gdl_close ();
#endif
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- if (renderer->winsys_vtable->id == COGL_WINSYS_ID_EGL_X11)
- _cogl_xlib_renderer_disconnect (renderer);
-#endif
-
eglTerminate (egl_renderer->edpy);
g_slice_free (CoglRendererEGL, egl_renderer);
@@ -283,9 +209,6 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
GError **error)
{
CoglRendererEGL *egl_renderer;
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- CoglXlibRenderer *xlib_renderer;
-#endif
#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
gdl_ret_t rc = GDL_SUCCESS;
gdl_display_info_t gdl_display_info;
@@ -301,18 +224,6 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
g_warn_if_reached ();
goto error;
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- case COGL_WINSYS_ID_EGL_X11:
- xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
-
- if (!_cogl_xlib_renderer_connect (renderer, error))
- goto error;
-
- egl_renderer->edpy =
- eglGetDisplay ((NativeDisplayType) xlib_renderer->xdpy);
- break;
-#endif
-
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
case COGL_WINSYS_ID_EGL_WAYLAND:
/* The EGL API doesn't provide for a way to explicitly select a
@@ -411,95 +322,6 @@ error:
return FALSE;
}
-static gboolean
-update_winsys_features (CoglContext *context, GError **error)
-{
- CoglRenderer *renderer = context->display->renderer;
- CoglDisplayEGL *egl_display = context->display->winsys;
- CoglRendererEGL *egl_renderer = renderer->winsys;
-
- _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);
-
- memset (context->winsys_features, 0, sizeof (context->winsys_features));
-
- check_egl_extensions (renderer);
-
- if (!_cogl_context_update_features (context, error))
- return FALSE;
-
- if (renderer->winsys_vtable->id == COGL_WINSYS_ID_EGL_X11 ||
- renderer->winsys_vtable->id == COGL_WINSYS_ID_EGL_WAYLAND)
- {
- context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
- COGL_FLAGS_SET (context->features,
- COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
- COGL_FLAGS_SET (context->winsys_features,
- COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
- TRUE);
- }
-
- if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION)
- {
- 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);
- }
-
- return TRUE;
-}
-
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-static XVisualInfo *
-get_visual_info (CoglDisplay *display, EGLConfig egl_config)
-{
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (display->renderer);
- 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 void
egl_attributes_from_framebuffer_config (CoglDisplay *display,
CoglFramebufferConfig *config,
@@ -569,10 +391,6 @@ try_create_context (CoglDisplay *display,
{
CoglRenderer *renderer = display->renderer;
CoglDisplayEGL *egl_display = display->winsys;
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (renderer);
-#endif
CoglRendererEGL *egl_renderer = renderer->winsys;
EGLDisplay edpy;
EGLConfig config;
@@ -580,10 +398,6 @@ try_create_context (CoglDisplay *display,
EGLBoolean status;
EGLint attribs[3];
EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- XVisualInfo *xvisinfo;
- XSetWindowAttributes attrs;
-#endif
const char *error_message;
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE);
@@ -638,62 +452,11 @@ try_create_context (CoglDisplay *display,
switch (renderer->winsys_vtable->id)
{
default:
- g_warn_if_reached ();
- goto fail;
-
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- case COGL_WINSYS_ID_EGL_X11:
- 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;
-
- egl_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) egl_display->dummy_xwin,
- NULL);
-
- if (egl_display->dummy_surface == EGL_NO_SURFACE)
- {
- error_message = "Unable to create an EGL surface";
- goto fail;
- }
-
- if (!eglMakeCurrent (edpy,
- egl_display->dummy_surface,
- egl_display->dummy_surface,
- egl_display->egl_context))
- {
- error_message = "Unable to eglMakeCurrent with dummy surface";
- goto fail;
- }
+ if (egl_renderer->platform_vtable &&
+ egl_renderer->platform_vtable->context_created &&
+ !egl_renderer->platform_vtable->context_created (display, error))
+ return FALSE;
break;
-#endif
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
case COGL_WINSYS_ID_EGL_WAYLAND:
@@ -879,14 +642,6 @@ cleanup_context (CoglDisplay *display)
CoglRenderer *renderer = display->renderer;
CoglDisplayEGL *egl_display = display->winsys;
CoglRendererEGL *egl_renderer = renderer->winsys;
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (renderer);
-#endif
-
- if (egl_renderer->platform_vtable &&
- egl_renderer->platform_vtable->cleanup_context)
- egl_renderer->platform_vtable->cleanup_context (display);
if (egl_display->egl_context != EGL_NO_CONTEXT)
{
@@ -896,6 +651,10 @@ cleanup_context (CoglDisplay *display)
egl_display->egl_context = EGL_NO_CONTEXT;
}
+ if (egl_renderer->platform_vtable &&
+ egl_renderer->platform_vtable->cleanup_context)
+ egl_renderer->platform_vtable->cleanup_context (display);
+
switch (renderer->winsys_vtable->id)
{
default:
@@ -913,22 +672,6 @@ cleanup_context (CoglDisplay *display)
break;
#endif
-#if COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- case COGL_WINSYS_ID_EGL_X11:
- if (egl_display->dummy_surface != EGL_NO_SURFACE)
- {
- eglDestroySurface (egl_renderer->edpy, egl_display->dummy_surface);
- egl_display->dummy_surface = EGL_NO_SURFACE;
- }
-
- if (egl_display->dummy_xwin)
- {
- XDestroyWindow (xlib_renderer->xdpy, egl_display->dummy_xwin);
- egl_display->dummy_xwin = None;
- }
- break;
-#endif
-
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
case COGL_WINSYS_ID_EGL_WAYLAND:
if (egl_display->dummy_surface != EGL_NO_SURFACE)
@@ -1131,26 +874,57 @@ error:
static gboolean
_cogl_winsys_context_init (CoglContext *context, GError **error)
{
+ CoglRenderer *renderer = context->display->renderer;
+ CoglDisplayEGL *egl_display = context->display->winsys;
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+
context->winsys = g_new0 (CoglContextEGL, 1);
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- if (context->display->renderer->winsys_vtable->id == COGL_WINSYS_ID_EGL_X11)
- cogl_xlib_renderer_add_filter (context->display->renderer,
- event_filter_cb,
- context);
-#endif
- return update_winsys_features (context, error);
+ _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);
+
+ memset (context->winsys_features, 0, sizeof (context->winsys_features));
+
+ check_egl_extensions (renderer);
+
+ if (!_cogl_context_update_features (context, error))
+ return FALSE;
+
+ if (renderer->winsys_vtable->id == COGL_WINSYS_ID_EGL_WAYLAND)
+ {
+ context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
+ COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
+ COGL_FLAGS_SET (context->winsys_features,
+ COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
+ TRUE);
+ }
+
+ if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION)
+ {
+ 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);
+ }
+
+ if (egl_renderer->platform_vtable &&
+ egl_renderer->platform_vtable->context_init &&
+ !egl_renderer->platform_vtable->context_init (context, error))
+ return FALSE;
+
+ return TRUE;
}
static void
_cogl_winsys_context_deinit (CoglContext *context)
{
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- if (context->display->renderer->winsys_vtable->id == COGL_WINSYS_ID_EGL_X11)
- cogl_xlib_renderer_remove_filter (context->display->renderer,
- event_filter_cb,
- context);
-#endif
+ CoglRenderer *renderer = context->display->renderer;
+ CoglRendererEGL *egl_renderer = renderer->winsys;
+
+ if (egl_renderer->platform_vtable &&
+ egl_renderer->platform_vtable->context_deinit)
+ egl_renderer->platform_vtable->context_deinit (context);
+
g_free (context->winsys);
}
@@ -1164,12 +938,6 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
CoglDisplayEGL *egl_display = display->winsys;
CoglRenderer *renderer = display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys;
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (renderer);
- CoglOnscreenXlib *xlib_onscreen;
- Window xwin;
-#endif
CoglOnscreenEGL *egl_onscreen;
EGLint attributes[MAX_EGL_CONFIG_ATTRIBS];
EGLConfig egl_config;
@@ -1209,143 +977,22 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
framebuffer->samples_per_pixel = samples;
}
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- if (renderer->winsys_vtable->id == COGL_WINSYS_ID_EGL_X11)
- {
- /* 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_xlib_renderer_trap_errors (display->renderer, &state);
-
- status = XGetWindowAttributes (xlib_renderer->xdpy, xwin, &attr);
- xerror = _cogl_xlib_renderer_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);
-
- /* Make sure the app selects for the events we require... */
- onscreen->foreign_update_mask_callback (onscreen,
- COGL_ONSCREEN_X11_EVENT_MASK,
- onscreen->
- foreign_update_mask_data);
- }
- 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_xlib_renderer_trap_errors (display->renderer, &state);
-
- xvisinfo = get_visual_info (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);
- xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
-
- mask = CWBorderPixel | CWColormap | CWEventMask;
-
- xwin = XCreateWindow (xlib_renderer->xdpy,
- DefaultRootWindow (xlib_renderer->xdpy),
- 0, 0,
- width, height,
- 0,
- xvisinfo->depth,
- InputOutput,
- xvisinfo->visual,
- mask, &xattr);
-
- XFree (xvisinfo);
-
- XSync (xlib_renderer->xdpy, False);
- xerror =
- _cogl_xlib_renderer_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;
switch (renderer->winsys_vtable->id)
{
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- case COGL_WINSYS_ID_EGL_X11:
- 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_config,
- (NativeWindowType) xlib_onscreen->xwin,
- NULL);
+ default:
+ if (egl_renderer->platform_vtable &&
+ egl_renderer->platform_vtable->onscreen_init &&
+ !egl_renderer->platform_vtable->onscreen_init (onscreen,
+ egl_config,
+ error))
+ {
+ g_slice_free (CoglOnscreenEGL, onscreen->winsys);
+ return FALSE;
+ }
break;
-#endif
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
case COGL_WINSYS_ID_EGL_WAYLAND:
@@ -1410,10 +1057,6 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
egl_display->have_onscreen = TRUE;
break;
#endif
-
- default:
- g_warn_if_reached ();
- return FALSE;
}
return TRUE;
@@ -1426,12 +1069,6 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
CoglContext *context = framebuffer->context;
CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys;
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (renderer);
- CoglXlibTrapState old_state;
- CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
-#endif
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT
CoglDisplayEGL *egl_display = context->display->winsys;
#endif
@@ -1447,26 +1084,13 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
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_renderer_trap_errors (renderer, &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 (egl_renderer->platform_vtable &&
+ egl_renderer->platform_vtable->onscreen_deinit)
+ egl_renderer->platform_vtable->onscreen_deinit (onscreen);
- if (_cogl_xlib_renderer_untrap_errors (renderer,
- &old_state) != Success)
- g_warning ("X Error while destroying X window");
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT
+ egl_display->have_onscreen = FALSE;
#endif
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
@@ -1494,31 +1118,22 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
CoglDisplayEGL *egl_display = context->display->winsys;
CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys;
+ CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+ CoglContextEGL *egl_context = context->winsys;
-#if defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
- defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT) || \
- defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT) || \
- defined (COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT) || \
- defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
- {
- CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
- CoglContextEGL *egl_context = context->winsys;
-
- if (egl_context->current_surface == egl_onscreen->egl_surface)
- return;
-
- 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);
- }
-#endif
+ if (egl_context->current_surface == egl_onscreen->egl_surface)
+ return;
+
+ 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);
}
static void
@@ -1526,12 +1141,6 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
const int *user_rectangles,
int n_rectangles)
{
-#if defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
- defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT) || \
- defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT) || \
- defined (COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT) || \
- defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
-
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys;
@@ -1564,29 +1173,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
n_rectangles,
rectangles) == EGL_FALSE)
g_warning ("Error reported by eglSwapBuffersRegion");
-#endif
-}
-
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-static void
-_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
- gboolean visibility)
-{
- CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
- CoglRenderer *renderer = context->display->renderer;
- CoglXlibRenderer *xlib_renderer =
- _cogl_xlib_renderer_get_data (renderer);
- CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
-
- if (renderer->winsys_vtable->id != COGL_WINSYS_ID_EGL_X11)
- return;
-
- if (visibility)
- XMapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
- else
- XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
}
-#endif
static void
_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
@@ -1619,23 +1206,6 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
#endif
}
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-static guint32
-_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
-{
- CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
- CoglRenderer *renderer = context->display->renderer;
-
- if (renderer->winsys_vtable->id == COGL_WINSYS_ID_EGL_X11)
- {
- CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
- return xlib_onscreen->xwin;
- }
- else
- return None;
-}
-#endif
-
static void
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
{
@@ -1651,29 +1221,6 @@ _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
_cogl_winsys_onscreen_bind (onscreen);
}
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-/* XXX: This is a particularly hacky _cogl_winsys interface... */
-static XVisualInfo *
-_cogl_winsys_xlib_get_visual_info (void)
-{
- CoglDisplayEGL *egl_display;
-
- _COGL_GET_CONTEXT (ctx, NULL);
-
- _COGL_RETURN_VAL_IF_FAIL (ctx->display->winsys, FALSE);
-
- if (ctx->display->renderer->winsys_vtable->id != COGL_WINSYS_ID_EGL_X11)
- return NULL;
-
- egl_display = ctx->display->winsys;
-
- if (!egl_display->found_egl_config)
- return NULL;
-
- return get_visual_info (ctx->display, egl_display->egl_config);
-}
-#endif
-
static EGLDisplay
_cogl_winsys_context_egl_get_egl_display (CoglContext *context)
{
@@ -1682,109 +1229,6 @@ _cogl_winsys_context_egl_get_egl_display (CoglContext *context)
return egl_renderer->edpy;
}
-#if defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap)
-static gboolean
-_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
-{
- CoglTexturePixmapEGL *egl_tex_pixmap;
- EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
- CoglPixelFormat texture_format;
- CoglRendererEGL *egl_renderer;
-
- /* FIXME: It should be possible to get to a CoglContext from any
- * CoglTexture pointer. */
- _COGL_GET_CONTEXT (ctx, FALSE);
-
- egl_renderer = ctx->display->renderer->winsys;
-
- if (!(egl_renderer->private_features &
- COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) ||
- !(ctx->private_feature_flags &
- COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE))
- {
- tex_pixmap->winsys = NULL;
- return FALSE;
- }
-
- egl_tex_pixmap = g_new0 (CoglTexturePixmapEGL, 1);
-
- egl_tex_pixmap->image =
- _cogl_egl_create_image (ctx,
- EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer)tex_pixmap->pixmap,
- attribs);
- if (egl_tex_pixmap->image == EGL_NO_IMAGE_KHR)
- {
- g_free (egl_tex_pixmap);
- return FALSE;
- }
-
- texture_format = (tex_pixmap->depth >= 32 ?
- COGL_PIXEL_FORMAT_RGBA_8888_PRE :
- COGL_PIXEL_FORMAT_RGB_888);
-
- egl_tex_pixmap->texture = COGL_TEXTURE (
- _cogl_egl_texture_2d_new_from_image (ctx,
- tex_pixmap->width,
- tex_pixmap->height,
- texture_format,
- egl_tex_pixmap->image,
- NULL));
-
- tex_pixmap->winsys = egl_tex_pixmap;
-
- return TRUE;
-}
-
-static void
-_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
-{
- CoglTexturePixmapEGL *egl_tex_pixmap;
-
- /* FIXME: It should be possible to get to a CoglContext from any
- * CoglTexture pointer. */
- _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
- if (!tex_pixmap->winsys)
- return;
-
- egl_tex_pixmap = tex_pixmap->winsys;
-
- if (egl_tex_pixmap->texture)
- cogl_object_unref (egl_tex_pixmap->texture);
-
- if (egl_tex_pixmap->image != EGL_NO_IMAGE_KHR)
- _cogl_egl_destroy_image (ctx, egl_tex_pixmap->image);
-
- tex_pixmap->winsys = NULL;
- g_free (egl_tex_pixmap);
-}
-
-static gboolean
-_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
- gboolean needs_mipmap)
-{
- if (needs_mipmap)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
-{
-}
-
-static CoglHandle
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
-{
- CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys;
-
- return egl_tex_pixmap->texture;
-}
-#endif /* defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap) */
-
-
static CoglWinsysVtable _cogl_winsys_vtable =
{
/* This winsys is only used as a base for the EGL-platform
@@ -1799,38 +1243,13 @@ static CoglWinsysVtable _cogl_winsys_vtable =
.context_deinit = _cogl_winsys_context_deinit,
.context_egl_get_egl_display =
_cogl_winsys_context_egl_get_egl_display,
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- .xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info,
-#endif
.onscreen_init = _cogl_winsys_onscreen_init,
.onscreen_deinit = _cogl_winsys_onscreen_deinit,
.onscreen_bind = _cogl_winsys_onscreen_bind,
.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers,
.onscreen_swap_region = _cogl_winsys_onscreen_swap_region,
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- .onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility,
-#endif
.onscreen_update_swap_throttled =
_cogl_winsys_onscreen_update_swap_throttled,
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
- .onscreen_x11_get_window_xid =
- _cogl_winsys_onscreen_x11_get_window_xid,
-#endif
-#if defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap)
- /* X11 tfp support... */
- /* XXX: instead of having a rather monolithic winsys vtable we could
- * perhaps look for a way to separate these... */
- .texture_pixmap_x11_create =
- _cogl_winsys_texture_pixmap_x11_create,
- .texture_pixmap_x11_free =
- _cogl_winsys_texture_pixmap_x11_free,
- .texture_pixmap_x11_update =
- _cogl_winsys_texture_pixmap_x11_update,
- .texture_pixmap_x11_damage_notify =
- _cogl_winsys_texture_pixmap_x11_damage_notify,
- .texture_pixmap_x11_get_texture =
- _cogl_winsys_texture_pixmap_x11_get_texture,
-#endif /* defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap) */
};
/* XXX: we use a function because no doubt someone will complain
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]