[cogl/wip/runtime-egl-platform: 4/12] winsys: Move X11/Xlib-specific code out of the EGL winsys



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]