[cairo-commit] 2 commits - boilerplate/cairo-boilerplate-egl.c boilerplate/cairo-boilerplate-glx.c boilerplate/cairo-boilerplate-wgl.c boilerplate/meson.build .gitlab-ci.yml meson.build meson_options.txt src/cairo-egl-context.c src/cairo-gl-composite.c src/cairo-gl-device.c src/cairo-gl-dispatch.c src/cairo-gl-dispatch-private.h src/cairo-gl-ext-def-private.h src/cairo-gl-glyphs.c src/cairo-gl-gradient.c src/cairo-gl-gradient-private.h src/cairo-gl.h src/cairo-gl-info.c src/cairo-gl-msaa-compositor.c src/cairo-gl-operand.c src/cairo-gl-private.h src/cairo-gl-shaders.c src/cairo-gl-source.c src/cairo-gl-spans-compositor.c src/cairo-gl-surface.c src/cairo-gl-surface-legacy.c src/cairo-gl-traps-compositor.c src/cairo-glx-context.c src/cairo.h src/cairo-mutex-list-private.h src/cairo-wgl-context.c src/cairo-xcb-surface-render.c src/meson.build test/api-special-cases.c test/egl-oversized-surface.c test/egl-surface-source.c test/error-setters.c test/gl-device-release.c test/gl-oversized-surface. c test/gl-surface-source.c test/meson.build util/cairo-script util/cairo-trace

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Jan 29 01:32:58 UTC 2023


 .gitlab-ci.yml                      |   10 
 boilerplate/cairo-boilerplate-egl.c |  192 ----
 boilerplate/cairo-boilerplate-glx.c |  457 ----------
 boilerplate/cairo-boilerplate-wgl.c |  239 -----
 boilerplate/meson.build             |    4 
 meson.build                         |  135 ---
 meson_options.txt                   |   10 
 src/cairo-egl-context.c             |  317 -------
 src/cairo-gl-composite.c            | 1364 -------------------------------
 src/cairo-gl-device.c               |  851 -------------------
 src/cairo-gl-dispatch-private.h     |  129 --
 src/cairo-gl-dispatch.c             |  273 ------
 src/cairo-gl-ext-def-private.h      |  143 ---
 src/cairo-gl-glyphs.c               |  507 -----------
 src/cairo-gl-gradient-private.h     |   96 --
 src/cairo-gl-gradient.c             |  339 -------
 src/cairo-gl-info.c                 |  147 ---
 src/cairo-gl-msaa-compositor.c      |  956 ----------------------
 src/cairo-gl-operand.c              |  793 ------------------
 src/cairo-gl-private.h              |  865 --------------------
 src/cairo-gl-shaders.c              | 1111 -------------------------
 src/cairo-gl-source.c               |  113 --
 src/cairo-gl-spans-compositor.c     |  556 ------------
 src/cairo-gl-surface-legacy.c       |  602 -------------
 src/cairo-gl-surface.c              | 1552 ------------------------------------
 src/cairo-gl-traps-compositor.c     |  531 ------------
 src/cairo-gl.h                      |  155 ---
 src/cairo-glx-context.c             |  324 -------
 src/cairo-mutex-list-private.h      |    4 
 src/cairo-wgl-context.c             |  260 ------
 src/cairo-xcb-surface-render.c      |    6 
 src/cairo.h                         |    4 
 src/meson.build                     |   24 
 test/api-special-cases.c            |   41 
 test/egl-oversized-surface.c        |  117 --
 test/egl-surface-source.c           |  135 ---
 test/error-setters.c                |    8 
 test/gl-device-release.c            |  182 ----
 test/gl-oversized-surface.c         |   88 --
 test/gl-surface-source.c            |  111 --
 test/meson.build                    |   15 
 util/cairo-script/csi-replay.c      |   61 -
 util/cairo-trace/trace.c            |  188 ----
 43 files changed, 1 insertion(+), 14014 deletions(-)

New commits:
commit 47a932bffc16323b58e3c8f9bc3fe0d821838a84
Merge: 1e8be6bbc b5793081d
Author: Emmanuele Bassi <ebassi at gmail.com>
Date:   Sun Jan 29 01:32:55 2023 +0000

    Merge branch 'no-more-gl' into 'master'
    
    Drop cairo-gl
    
    See merge request cairo/cairo!287

diff --cc test/meson.build
index e5b4f89d5,d950e2254..b18a23f48
--- a/test/meson.build
+++ b/test/meson.build
@@@ -436,20 -436,9 +436,9 @@@ test_ft_svg_font_sources = 
  test_ft_svg_ttx_font_sources = [
    'ft-svg-cairo-logo.c',
    'ft-svg-render.c',
 -  'ft-svg-render-palette.c'
 +  'ft-svg-render-color.c'
  ]
  
- test_gl_sources = [
-   'gl-device-release.c',
-   'gl-oversized-surface.c',
-   'gl-surface-source.c',
- ]
- 
- test_egl_sources = [
-   'egl-oversized-surface.c',
-   'egl-surface-source.c',
- ]
- 
  test_quartz_sources = [
    'quartz-surface-source.c',
    'quartz-color-font.c',
commit b5793081d095a13517e157d793b367e4527fd39d
Author: Emmanuele Bassi <ebassi at gnome.org>
Date:   Sun Apr 18 00:11:16 2021 +0100

    Drop cairo-gl
    
    The GL support in Cairo has always been a prototype, and
    nothing happened in the past 10+ years to make it work as
    it was meant to.
    
    GL support is not enabled by any downstream packagers of
    Cairo, so nobody should notice its absence.

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 699fdbf1f..e7479889e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,9 +16,6 @@ variables:
 
   DEFAULT_MESON_ARGS: >
     --default-library=both
-    -Dgl-backend=auto
-    -Dglesv2=auto
-    -Dglesv3=auto
 
 stages:
   - prep
@@ -78,12 +75,6 @@ fedora image:
       pixman-devel
       systemd-devel
       systemd-udev
-      mesa-libEGL
-      mesa-libGL
-      mesa-libGL-devel
-      mesa-libgbm
-      mesa-libgbm-devel
-      mesa-libglapi
       expat-devel
       autoconf
       automake
@@ -229,7 +220,6 @@ fedora meson build:
   variables:
     MESON_ARGS: >
       ${DEFAULT_MESON_ARGS}
-      -Dgl-backend=gl
   script:
     - export CFLAGS="-Werror -Wno-error=deprecated-declarations"
     - meson builddir ${MESON_ARGS}
diff --git a/boilerplate/cairo-boilerplate-egl.c b/boilerplate/cairo-boilerplate-egl.c
deleted file mode 100644
index 8196b1ffd..000000000
--- a/boilerplate/cairo-boilerplate-egl.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Chris Wilson
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Chris Wilson.
- */
-
-#include "cairo-boilerplate-private.h"
-
-#include <cairo-gl.h>
-#if CAIRO_HAS_GLESV3_SURFACE
-#include <GLES3/gl3.h>
-#include <EGL/eglext.h>
-#elif CAIRO_HAS_GLESV2_SURFACE
-#include <GLES2/gl2.h>
-#elif CAIRO_HAS_GL_SURFACE
-#include <GL/gl.h>
-#endif
-
-typedef struct _egl_target_closure {
-    EGLDisplay dpy;
-    EGLContext ctx;
-
-    cairo_device_t *device;
-    cairo_surface_t *surface;
-} egl_target_closure_t;
-
-static void
-_cairo_boilerplate_egl_cleanup (void *closure)
-{
-    egl_target_closure_t *gltc = closure;
-
-    cairo_device_finish (gltc->device);
-    cairo_device_destroy (gltc->device);
-
-    eglDestroyContext (gltc->dpy, gltc->ctx);
-    eglMakeCurrent (gltc->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    eglTerminate (gltc->dpy);
-
-    free (gltc);
-}
-
-static cairo_surface_t *
-_cairo_boilerplate_egl_create_surface (const char		 *name,
-				       cairo_content_t		  content,
-				       double			  width,
-				       double			  height,
-				       double			  max_width,
-				       double			  max_height,
-				       cairo_boilerplate_mode_t   mode,
-				       void			**closure)
-{
-    egl_target_closure_t *gltc;
-    cairo_surface_t *surface;
-    int major, minor;
-    EGLConfig config;
-    EGLint numConfigs;
-    EGLint config_attribs[] = {
-	EGL_RED_SIZE, 8,
-	EGL_GREEN_SIZE, 8,
-	EGL_BLUE_SIZE, 8,
-	EGL_ALPHA_SIZE, 8,
-	EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-#if CAIRO_HAS_GLESV3_SURFACE
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
-#elif CAIRO_HAS_GLESV2_SURFACE
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#elif CAIRO_HAS_GL_SURFACE
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
-#endif
-	EGL_NONE
-    };
-    const EGLint ctx_attribs[] = {
-#if CAIRO_HAS_GLESV3_SURFACE
-	EGL_CONTEXT_CLIENT_VERSION, 3,
-#elif CAIRO_HAS_GLESV2_SURFACE
-	EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-	EGL_NONE
-    };
-
-    gltc = xcalloc (1, sizeof (egl_target_closure_t));
-    *closure = gltc;
-
-    gltc->dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
-
-    if (! eglInitialize (gltc->dpy, &major, &minor)) {
-	free (gltc);
-	return NULL;
-    }
-
-    eglChooseConfig (gltc->dpy, config_attribs, &config, 1, &numConfigs);
-#if CAIRO_HAS_GLESV3_SURFACE && CAIRO_HAS_GLESV2_SURFACE
-    if (numConfigs == 0) {
-        /* retry with ES2_BIT */
-        config_attribs[11] = ES2_BIT;  /* FIXME: Ick */
-        eglChooseConfig (gltc->dpy, config_attribs, &config, 1, &numConfigs);
-    }
-#endif
-    if (numConfigs == 0) {
-	free (gltc);
-	return NULL;
-    }
-
-#if CAIRO_HAS_GLESV3_SURFACE || CAIRO_HAS_GLESV2_SURFACE
-    eglBindAPI (EGL_OPENGL_ES_API);
-#elif CAIRO_HAS_GL_SURFACE
-    eglBindAPI (EGL_OPENGL_API);
-#endif
-
-    gltc->ctx = eglCreateContext (gltc->dpy, config, EGL_NO_CONTEXT,
-				  ctx_attribs);
-    if (gltc->ctx == EGL_NO_CONTEXT) {
-	eglTerminate (gltc->dpy);
-	free (gltc);
-	return NULL;
-    }
-
-    gltc->device = cairo_egl_device_create (gltc->dpy, gltc->ctx);
-    if (mode == CAIRO_BOILERPLATE_MODE_PERF)
-	cairo_gl_device_set_thread_aware(gltc->device, FALSE);
-
-    if (width < 1)
-	width = 1;
-    if (height < 1)
-	height = 1;
-
-    gltc->surface = surface = cairo_gl_surface_create (gltc->device,
-						       content,
-						       ceil (width),
-						       ceil (height));
-    if (cairo_surface_status (surface))
-	_cairo_boilerplate_egl_cleanup (gltc);
-
-    return surface;
-}
-
-static void
-_cairo_boilerplate_egl_synchronize (void *closure)
-{
-    egl_target_closure_t *gltc = closure;
-
-    if (cairo_device_acquire (gltc->device))
-	return;
-
-    glFinish ();
-
-    cairo_device_release (gltc->device);
-}
-
-static const cairo_boilerplate_target_t targets[] = {
-    {
-	"egl", "gl", NULL, NULL,
-	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
-	"cairo_egl_device_create",
-	_cairo_boilerplate_egl_create_surface,
-	cairo_surface_create_similar,
-	NULL, NULL,
-	_cairo_boilerplate_get_image_surface,
-	cairo_surface_write_to_png,
-	_cairo_boilerplate_egl_cleanup,
-	_cairo_boilerplate_egl_synchronize,
-        NULL,
-	TRUE, FALSE, FALSE
-    }
-};
-CAIRO_BOILERPLATE (egl, targets)
diff --git a/boilerplate/cairo-boilerplate-glx.c b/boilerplate/cairo-boilerplate-glx.c
deleted file mode 100644
index 7701d908f..000000000
--- a/boilerplate/cairo-boilerplate-glx.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/* Cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Chris Wilson
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Chris Wilson.
- */
-
-#include "cairo-boilerplate-private.h"
-
-#include <cairo-gl.h>
-
-#include <X11/X.h>
-#include <X11/Xutil.h> /* for XDestroyImage */
-
-static const cairo_user_data_key_t gl_closure_key;
-
-typedef struct _gl_target_closure {
-    Display *dpy;
-    int screen;
-    Window drawable;
-
-    GLXContext ctx;
-    cairo_device_t *device;
-    cairo_surface_t *surface;
-} gl_target_closure_t;
-
-static void
-_cairo_boilerplate_gl_cleanup (void *closure)
-{
-    gl_target_closure_t *gltc = closure;
-
-    cairo_device_finish (gltc->device);
-    cairo_device_destroy (gltc->device);
-
-    glXDestroyContext (gltc->dpy, gltc->ctx);
-
-    if (gltc->drawable)
-	XDestroyWindow (gltc->dpy, gltc->drawable);
-    XCloseDisplay (gltc->dpy);
-
-    free (gltc);
-}
-
-static cairo_surface_t *
-_cairo_boilerplate_gl_create_surface (const char		*name,
-				      cairo_content_t		 content,
-				      double			 width,
-				      double			 height,
-				      double			 max_width,
-				      double			 max_height,
-				      cairo_boilerplate_mode_t	 mode,
-				      void		       **closure)
-{
-    int rgba_attribs[] = { GLX_RGBA,
-			   GLX_RED_SIZE, 1,
-			   GLX_GREEN_SIZE, 1,
-			   GLX_BLUE_SIZE, 1,
-			   GLX_ALPHA_SIZE, 1,
-			   GLX_DOUBLEBUFFER,
-			   None };
-    int rgb_attribs[] = { GLX_RGBA,
-			  GLX_RED_SIZE, 1,
-			  GLX_GREEN_SIZE, 1,
-			  GLX_BLUE_SIZE, 1,
-			  GLX_DOUBLEBUFFER,
-			  None };
-    XVisualInfo *visinfo;
-    GLXContext ctx;
-    gl_target_closure_t *gltc;
-    cairo_surface_t *surface;
-    Display *dpy;
-
-    gltc = calloc (1, sizeof (gl_target_closure_t));
-    *closure = gltc;
-
-    width = ceil (width);
-    height = ceil (height);
-
-    if (width == 0)
-	width = 1;
-    if (height == 0)
-	height = 1;
-
-    dpy = XOpenDisplay (NULL);
-    gltc->dpy = dpy;
-    if (!gltc->dpy) {
-	fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0));
-	free (gltc);
-	return NULL;
-    }
-
-    if (mode == CAIRO_BOILERPLATE_MODE_TEST)
-	XSynchronize (gltc->dpy, 1);
-
-    if (content == CAIRO_CONTENT_COLOR)
-	visinfo = glXChooseVisual (dpy, DefaultScreen (dpy), rgb_attribs);
-    else
-	visinfo = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
-
-    if (visinfo == NULL) {
-	fprintf (stderr, "Failed to create RGB, double-buffered visual\n");
-	XCloseDisplay (dpy);
-	free (gltc);
-	return NULL;
-    }
-
-    ctx = glXCreateContext (dpy, visinfo, NULL, True);
-    XFree (visinfo);
-
-    gltc->ctx = ctx;
-    gltc->device = cairo_glx_device_create (dpy, ctx);
-
-    if (mode == CAIRO_BOILERPLATE_MODE_PERF)
-	cairo_gl_device_set_thread_aware(gltc->device, FALSE);
-
-    gltc->surface = surface = cairo_gl_surface_create (gltc->device,
-						       content, width, height);
-    if (cairo_surface_status (surface))
-	_cairo_boilerplate_gl_cleanup (gltc);
-
-    return surface;
-}
-
-static cairo_surface_t *
-_cairo_boilerplate_gl_create_window_common (int				rgba_attribs[],
-					    cairo_content_t		content,
-					    double			width,
-					    double			height,
-					    double			max_width,
-					    double			max_height,
-					    cairo_boilerplate_mode_t	mode,
-					    gl_target_closure_t		*gltc)
-{
-    XVisualInfo *vi;
-    GLXContext ctx;
-    cairo_surface_t *surface;
-    Display *dpy;
-    XSetWindowAttributes attr;
-
-    width = ceil (width);
-    height = ceil (height);
-
-    if (width == 0)
-	width = 1;
-    if (height == 0)
-	height = 1;
-
-    dpy = XOpenDisplay (NULL);
-    gltc->dpy = dpy;
-    if (!gltc->dpy) {
-	fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0));
-	free (gltc);
-	return NULL;
-    }
-
-    if (mode == CAIRO_BOILERPLATE_MODE_TEST)
-	XSynchronize (gltc->dpy, 1);
-
-    vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
-    if (vi == NULL) {
-	fprintf (stderr, "Failed to create RGBA, double-buffered visual\n");
-	XCloseDisplay (dpy);
-	free (gltc);
-	return NULL;
-    }
-
-    attr.colormap = XCreateColormap (dpy,
-				     RootWindow (dpy, vi->screen),
-				     vi->visual,
-				     AllocNone);
-    attr.border_pixel = 0;
-    attr.override_redirect = True;
-    gltc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0,
-				    width, height, 0, vi->depth,
-				    InputOutput, vi->visual,
-				    CWOverrideRedirect | CWBorderPixel | CWColormap,
-				    &attr);
-    XMapWindow (dpy, gltc->drawable);
-
-    ctx = glXCreateContext (dpy, vi, NULL, True);
-    XFree (vi);
-
-    gltc->ctx = ctx;
-    gltc->device = cairo_glx_device_create (dpy, ctx);
-
-    gltc->surface = surface = cairo_gl_surface_create_for_window (gltc->device,
-								  gltc->drawable,
-								  width, height);
-    if (cairo_surface_status (surface)) {
-	_cairo_boilerplate_gl_cleanup (gltc);
-	return NULL;
-    }
-    return surface;
-}
-
-static cairo_surface_t *
-_cairo_boilerplate_gl_create_window (const char		       *name,
-				     cairo_content_t		content,
-				     double			width,
-				     double			height,
-				     double			max_width,
-				     double			max_height,
-				     cairo_boilerplate_mode_t	mode,
-				     void		      **closure)
-{
-    gl_target_closure_t *gltc;
-
-    int rgba_attribs[] = { GLX_RGBA,
-			   GLX_RED_SIZE, 1,
-			   GLX_GREEN_SIZE, 1,
-			   GLX_BLUE_SIZE, 1,
-			   GLX_ALPHA_SIZE, 1,
-			   GLX_DOUBLEBUFFER,
-			   GLX_NONE };
-
-    gltc = calloc (1, sizeof (gl_target_closure_t));
-    *closure = gltc;
-
-    return _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
-						       width, height,
-						       max_width, max_height,
-						       mode, gltc);
-}
-
-static cairo_surface_t *
-_cairo_boilerplate_gl_create_window_msaa (const char		       *name,
-					  cairo_content_t		content,
-					  double			width,
-					  double			height,
-					  double			max_width,
-					  double			max_height,
-					  cairo_boilerplate_mode_t	mode,
-					  void			      **closure)
-{
-    gl_target_closure_t *gltc;
-
-    int rgba_attribs[] = { GLX_RGBA,
-			   GLX_RED_SIZE, 1,
-			   GLX_GREEN_SIZE, 1,
-			   GLX_BLUE_SIZE, 1,
-			   GLX_ALPHA_SIZE, 1,
-			   GLX_STENCIL_SIZE, 1,
-			   GLX_SAMPLES, 4,
-			   GLX_SAMPLE_BUFFERS, 1,
-			   GLX_DOUBLEBUFFER,
-			   GLX_NONE };
-
-    gltc = calloc (1, sizeof (gl_target_closure_t));
-    *closure = gltc;
-    return _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
-						       width, height,
-						       max_width, max_height,
-						       mode, gltc);
-
-}
-
-static cairo_surface_t *
-_cairo_boilerplate_gl_create_window_db (const char		  *name,
-					cairo_content_t		   content,
-					double			   width,
-					double			   height,
-					double			   max_width,
-					double			   max_height,
-					cairo_boilerplate_mode_t   mode,
-					void			 **closure)
-{
-    cairo_status_t status;
-    cairo_surface_t *surface;
-    gl_target_closure_t *gltc;
-
-    int rgba_attribs[] = { GLX_RGBA,
-			   GLX_RED_SIZE, 1,
-			   GLX_GREEN_SIZE, 1,
-			   GLX_BLUE_SIZE, 1,
-			   GLX_ALPHA_SIZE, 1,
-			   GLX_DOUBLEBUFFER,
-			   GLX_NONE };
-
-    gltc = calloc (1, sizeof (gl_target_closure_t));
-    *closure = gltc;
-
-    surface = _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
-							  width, height,
-							  max_width, max_height,
-							  mode, gltc);
-
-   if (! surface)
-	return NULL;
-
-    surface = cairo_surface_create_similar (gltc->surface, content, width, height);
-    status = cairo_surface_set_user_data (surface, &gl_closure_key, gltc, NULL);
-    if (status == CAIRO_STATUS_SUCCESS)
-	return surface;
-
-    cairo_surface_destroy (surface);
-    _cairo_boilerplate_gl_cleanup (gltc);
-    return cairo_boilerplate_surface_create_in_error (status);
-}
-
-static cairo_status_t
-_cairo_boilerplate_gl_finish_window (cairo_surface_t *surface)
-{
-    gl_target_closure_t *gltc = cairo_surface_get_user_data (surface,
-							     &gl_closure_key);
-
-    if (gltc != NULL && gltc->surface != NULL) {
-	cairo_t *cr;
-
-	cr = cairo_create (gltc->surface);
-	cairo_surface_set_device_offset (surface, 0, 0);
-	cairo_set_source_surface (cr, surface, 0, 0);
-	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
-	cairo_paint (cr);
-	cairo_destroy (cr);
-
-	surface = gltc->surface;
-    }
-
-    cairo_gl_surface_swapbuffers (surface);
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-_cairo_boilerplate_gl_synchronize (void *closure)
-{
-    gl_target_closure_t *gltc = closure;
-
-    if (cairo_device_acquire (gltc->device))
-	return;
-
-    glFinish ();
-
-    cairo_device_release (gltc->device);
-}
-
-static char *
-_cairo_boilerplate_gl_describe (void *closure)
-{
-    gl_target_closure_t *gltc = closure;
-    char *s;
-    const GLubyte *vendor, *renderer, *version;
-
-    if (cairo_device_acquire (gltc->device))
-	return NULL;
-
-    vendor   = glGetString (GL_VENDOR);
-    renderer = glGetString (GL_RENDERER);
-    version  = glGetString (GL_VERSION);
-
-    xasprintf (&s, "%s %s %s", vendor, renderer, version);
-
-    cairo_device_release (gltc->device);
-
-    return s;
-}
-
-static const cairo_boilerplate_target_t targets[] = {
-    {
-	"gl", "gl", NULL, NULL,
-	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
-	"cairo_gl_surface_create",
-	_cairo_boilerplate_gl_create_surface,
-	cairo_surface_create_similar,
-	NULL, NULL,
-	_cairo_boilerplate_get_image_surface,
-	cairo_surface_write_to_png,
-	_cairo_boilerplate_gl_cleanup,
-	_cairo_boilerplate_gl_synchronize,
-        _cairo_boilerplate_gl_describe,
-	TRUE, FALSE, FALSE
-    },
-    {
-	"gl", "gl", NULL, NULL,
-	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR, 1,
-	"cairo_gl_surface_create",
-	_cairo_boilerplate_gl_create_surface,
-	cairo_surface_create_similar,
-	NULL, NULL,
-	_cairo_boilerplate_get_image_surface,
-	cairo_surface_write_to_png,
-	_cairo_boilerplate_gl_cleanup,
-	_cairo_boilerplate_gl_synchronize,
-        _cairo_boilerplate_gl_describe,
-	FALSE, FALSE, FALSE
-    },
-    {
-	"gl-window", "gl", NULL, NULL,
-	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
-	"cairo_gl_surface_create_for_window",
-	_cairo_boilerplate_gl_create_window,
-	cairo_surface_create_similar,
-	NULL,
-	_cairo_boilerplate_gl_finish_window,
-	_cairo_boilerplate_get_image_surface,
-	cairo_surface_write_to_png,
-	_cairo_boilerplate_gl_cleanup,
-	_cairo_boilerplate_gl_synchronize,
-        _cairo_boilerplate_gl_describe,
-	FALSE, FALSE, FALSE
-    },
-    {
-	"gl-window-msaa", "gl", NULL, NULL,
-	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
-	"cairo_gl_surface_create_for_window",
-	_cairo_boilerplate_gl_create_window_msaa,
-	cairo_surface_create_similar,
-	NULL,
-	_cairo_boilerplate_gl_finish_window,
-	_cairo_boilerplate_get_image_surface,
-	cairo_surface_write_to_png,
-	_cairo_boilerplate_gl_cleanup,
-	_cairo_boilerplate_gl_synchronize,
-        _cairo_boilerplate_gl_describe,
-	FALSE, FALSE, FALSE
-    },
-    {
-	"gl-window&", "gl", NULL, NULL,
-	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
-	"cairo_gl_surface_create_for_window",
-	_cairo_boilerplate_gl_create_window_db,
-	cairo_surface_create_similar,
-	NULL,
-	_cairo_boilerplate_gl_finish_window,
-	_cairo_boilerplate_get_image_surface,
-	cairo_surface_write_to_png,
-	_cairo_boilerplate_gl_cleanup,
-	_cairo_boilerplate_gl_synchronize,
-        _cairo_boilerplate_gl_describe,
-	FALSE, FALSE, FALSE
-    },
-};
-CAIRO_BOILERPLATE (gl, targets)
diff --git a/boilerplate/cairo-boilerplate-wgl.c b/boilerplate/cairo-boilerplate-wgl.c
deleted file mode 100644
index 908817788..000000000
--- a/boilerplate/cairo-boilerplate-wgl.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Chris Wilson
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Chris Wilson.
- *
- * Contributor(s):
- *	Zoxc <zoxc32 at gmail.com>
- */
-
-#include "cairo-boilerplate-private.h"
-
-#include <cairo-gl.h>
-
-static const cairo_user_data_key_t gl_closure_key;
-
-typedef struct _wgl_target_closure {
-    HWND wnd;
-    HDC dc;
-    HGLRC rc;
-    cairo_device_t *device;
-    cairo_surface_t *surface;
-} wgl_target_closure_t;
-
-static void
-_cairo_boilerplate_wgl_cleanup (void *closure)
-{
-    wgl_target_closure_t *wgltc = closure;
-
-    cairo_device_finish (wgltc->device);
-    cairo_device_destroy (wgltc->device);
-
-    wglDeleteContext(wgltc->rc);
-
-    ReleaseDC(wgltc->wnd, wgltc->dc);
-    DestroyWindow (wgltc->wnd);
-
-    free (wgltc);
-}
-
-static void
-_cairo_boilerplate_wgl_create_window (int		    width,
-				      int		    height,
-				      wgl_target_closure_t *wgltc)
-{
-    WNDCLASSEXA wincl;
-    PIXELFORMATDESCRIPTOR pfd;
-    int format;
-    cairo_surface_t *surface;
-    
-    ZeroMemory (&wincl, sizeof (WNDCLASSEXA));
-    wincl.cbSize = sizeof (WNDCLASSEXA);
-    wincl.hInstance = GetModuleHandle (0);
-    wincl.lpszClassName = "cairo_boilerplate_wgl_dummy";
-    wincl.lpfnWndProc = DefWindowProcA;
-    wincl.style = CS_OWNDC;
-
-    RegisterClassExA (&wincl);
-    
-    wgltc->wnd = CreateWindow ("cairo_boilerplate_wgl_dummy", 0, WS_POPUP, 0, 0, width, height, 0, 0, 0, 0);
-    wgltc->dc = GetDC (wgltc->wnd);
-
-    ZeroMemory (&pfd, sizeof (PIXELFORMATDESCRIPTOR));
-    pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
-    pfd.nVersion = 1;
-    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
-    pfd.iPixelType = PFD_TYPE_RGBA;
-    pfd.cColorBits = 24;
-    pfd.cDepthBits = 16;
-    pfd.iLayerType = PFD_MAIN_PLANE;
-
-    format = ChoosePixelFormat (wgltc->dc, &pfd);
-    SetPixelFormat (wgltc->dc, format, &pfd);
-    
-    wgltc->rc = wglCreateContext (wgltc->dc);
-    wgltc->device = cairo_wgl_device_create (wgltc->rc);
-}
-
-static cairo_surface_t *
-_cairo_boilerplate_wgl_create_surface (const char		 *name,
-				       cairo_content_t		  content,
-				       double			  width,
-				       double			  height,
-				       double			  max_width,
-				       double			  max_height,
-				       cairo_boilerplate_mode_t   mode,
-				       void			**closure)
-{
-    wgl_target_closure_t *wgltc;
-    cairo_surface_t *surface;
-    
-    wgltc = calloc (1, sizeof (wgl_target_closure_t));
-    
-    *closure = wgltc;
-
-    _cairo_boilerplate_wgl_create_window(0, 0, wgltc);
-    
-    if (width == 0)
-	width = 1;
-    if (height == 0)
-	height = 1;
-    
-    wgltc->surface = surface = cairo_gl_surface_create (wgltc->device,
-						       content,
-						       ceil (width),
-						       ceil (height));
-    if (cairo_surface_status (surface)) {
-	_cairo_boilerplate_wgl_cleanup (wgltc);
-	return NULL;
-    }
-
-    return surface;
-}
-
-static cairo_surface_t *
-_cairo_boilerplate_wgl_for_create_window (const char		    *name,
-					  cairo_content_t	     content,
-					  double		     width,
-					  double		     height,
-					  double		     max_width,
-					  double		     max_height,
-					  cairo_boilerplate_mode_t   mode,
-					  void			   **closure)
-{
-    wgl_target_closure_t *wgltc;
-    cairo_surface_t *surface;
-    
-    wgltc = calloc (1, sizeof (wgl_target_closure_t));
-    
-    *closure = wgltc;
-
-     _cairo_boilerplate_wgl_create_window(width, height, wgltc);
-    
-    wgltc->surface = surface = cairo_gl_surface_create_for_dc (wgltc->device,
-						       wgltc->dc,
-						       ceil (width),
-						       ceil (height));
-    
-    if (cairo_surface_status (surface)) {
-	_cairo_boilerplate_wgl_cleanup (wgltc);
-	return NULL;
-    }
-
-    return surface;
-}
-
-static cairo_status_t
-_cairo_boilerplate_wgl_finish_window (cairo_surface_t *surface)
-{
-    wgl_target_closure_t *wgltc = cairo_surface_get_user_data (surface,
-							     &gl_closure_key);
-
-    if (wgltc != NULL && wgltc->surface != NULL) {
-	cairo_t *cr;
-
-	cr = cairo_create (wgltc->surface);
-	cairo_surface_set_device_offset (surface, 0, 0);
-	cairo_set_source_surface (cr, surface, 0, 0);
-	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
-	cairo_paint (cr);
-	cairo_destroy (cr);
-
-	surface = wgltc->surface;
-    }
-
-    cairo_gl_surface_swapbuffers (surface);
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-_cairo_boilerplate_wgl_synchronize (void *closure)
-{
-    wgl_target_closure_t *wgltc = closure;
-
-    if (cairo_device_acquire (wgltc->device))
-	return;
-
-    glFinish ();
-
-    cairo_device_release (wgltc->device);
-}
-
-static const cairo_boilerplate_target_t targets[] = {
-    {
-	"gl", "gl", NULL, NULL,
-	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
-	"cairo_gl_surface_create",
-	_cairo_boilerplate_wgl_create_surface,
-	cairo_surface_create_similar,
-	NULL, NULL,
-	_cairo_boilerplate_get_image_surface,
-	cairo_surface_write_to_png,
-	_cairo_boilerplate_wgl_cleanup,
-	_cairo_boilerplate_wgl_synchronize,
-        NULL,
-	TRUE, FALSE, FALSE
-    },
-    {
-	"gl-dc", "gl", NULL, NULL,
-	CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
-	"cairo_gl_surface_create_for_dc",
-	_cairo_boilerplate_wgl_for_create_window,
-	NULL,
-	_cairo_boilerplate_wgl_finish_window,
-	_cairo_boilerplate_get_image_surface,
-	cairo_surface_write_to_png,
-	_cairo_boilerplate_wgl_cleanup,
-	_cairo_boilerplate_wgl_synchronize,
-        NULL,
-	FALSE, FALSE, FALSE
-    },
-};
-
-CAIRO_BOILERPLATE (wgl, targets)
diff --git a/boilerplate/meson.build b/boilerplate/meson.build
index 7f663c273..450eabf3e 100644
--- a/boilerplate/meson.build
+++ b/boilerplate/meson.build
@@ -13,10 +13,6 @@ cairo_boilerplate_feature_sources = {
   'cairo-ps': ['cairo-boilerplate-ps.c'],
   'cairo-svg': ['cairo-boilerplate-svg.c'],
   'cairo-script': ['cairo-boilerplate-script.c'],
-  # All tests crash with FPE
-  # 'cairo-egl': ['cairo-boilerplate-egl.c'],
-  # cairo-glx: ['cairo-boilerplate-glx.c'],
-  'cairo-wgl': ['cairo-boilerplate-wgl.c'],
 }
 
 foreach feature: built_features
diff --git a/meson.build b/meson.build
index 0faf8638e..34679304e 100644
--- a/meson.build
+++ b/meson.build
@@ -551,135 +551,6 @@ if host_machine.system() == 'windows'
   endif
 endif
 
-# GL / GLESV2 / GLESV3 are mutually exclusive
-gl_backend = get_option('gl-backend')
-need_egl_functions = false
-need_wgl_functions = false
-need_glx_functions = false
-
-if gl_backend in ['auto', 'gl']
-  gl_dep = dependency('gl', required: false)
-  if not gl_dep.found()
-    gl_dep = cc.find_library('GL', required: gl_backend == 'gl')
-  endif
-  if gl_dep.found() and \
-     cc.has_header('GL/gl.h', required: gl_backend == 'gl', dependencies: gl_dep) and \
-     cc.has_header('GL/glext.h', required: gl_backend == 'gl', dependencies: gl_dep)
-    deps += [gl_dep]
-
-    need_egl_functions = true
-    need_wgl_functions = true
-    need_glx_functions = true
-
-    feature_conf.set('CAIRO_HAS_GL_SURFACE', 1)
-    built_features += [{
-      'name': 'cairo-gl',
-      'description': 'OpenGL surface backend',
-      'deps': [gl_dep],
-    }]
-  endif
-endif
-
-if feature_conf.get('CAIRO_HAS_GL_SURFACE', 0) == 0 and ['auto', 'glesv2'].contains(gl_backend)
-  glesv2_dep = dependency('glesv2', required: false)
-  if not glesv2_dep.found()
-    glesv2_dep = cc.find_library('GLESv2', required: gl_backend == 'glesv2')
-  endif
-  if glesv2_dep.found() and \
-     cc.has_header('GLES2/gl2.h', required: gl_backend == 'glesv2', dependencies: glesv2_dep) and \
-     cc.has_header('GLES2/gl2ext.h', required: gl_backend == 'glesv2', dependencies: glesv2_dep)
-    deps += [glesv2_dep]
-    need_egl_functions = true
-
-    feature_conf.set('CAIRO_HAS_GLESV2_SURFACE', 1)
-    built_features += [{
-      'name': 'cairo-glesv2',
-      'source-key': 'cairo-gl',
-      'description': 'OpenGLESv2 surface backend',
-      'deps': [glesv2_dep],
-    }]
-  endif
-endif
-
-if feature_conf.get('CAIRO_HAS_GL_SURFACE', 0) == 0 and feature_conf.get('CAIRO_HAS_GLESV2_SURFACE', 0) == 0 and ['auto', 'glesv3'].contains(gl_backend)
-  # glesv3 is provided via libGLESv2.so (there is no libGLESv3, nor glesv3.pc)
-  glesv3_dep = dependency('glesv2', required: false)
-  if not glesv3_dep.found()
-    glesv3_dep = cc.find_library('GLESv2', required: gl_backend == 'glesv3')
-  endif
-
-  if glesv3_dep.found() and \
-     cc.has_header('GLES3/gl3.h', required: gl_backend == 'glesv3', dependencies: glesv3_dep) and \
-     cc.has_header('GLES3/gl3ext.h', required: gl_backend == 'glesv3', dependencies: glesv3_dep)
-    deps += [glesv3_dep]
-    need_egl_functions = true
-
-    feature_conf.set('CAIRO_HAS_GLESV3_SURFACE', 1)
-    built_features += [{
-      'name': 'cairo-glesv3',
-      'source-key': 'cairo-gl',
-      'description': 'OpenGLESv3 surface backend',
-      'deps': [glesv3_dep],
-    }]
-  endif
-endif
-
-if need_egl_functions
-  # FIXME: automagic
-  egl_extra_deps = []
-  egl_dep = dependency('egl', required: false)
-  if not egl_dep.found()
-    if cc.has_header('EGL/egl.h')
-      csi_dep = cc.find_library('csi', required: false)
-      if csi_dep.found() and cc.has_function('csi_stream_attachresource', dependencies: [csi_dep])
-        egl_extra_deps += csi_dep
-      endif
-
-      foreach libname : ['EGL', 'egl13', 'egl12', 'egl11']
-        dep = cc.find_library(libname, required: false)
-        if dep.found() and cc.has_function('eglGetError', dependencies: [dep])
-          egl_dep = dep
-          break
-        endif
-      endforeach
-    endif
-  endif
-
-  if egl_dep.found()
-    deps += egl_dep
-    feature_conf.set('CAIRO_HAS_EGL_FUNCTIONS', 1)
-    built_features += [{
-      'name': 'cairo-egl',
-      'description': 'EGL functions',
-      'deps': [egl_dep] + egl_extra_deps,
-    }]
-  endif
-endif
-
-if need_glx_functions
-  # FIXME: automagic
-  if cc.has_header('GL/glx.h')
-    feature_conf.set('CAIRO_HAS_GLX_FUNCTIONS', 1)
-    built_features += [{
-      'name': 'cairo-glx',
-      'description': 'GLX functions',
-      'deps': [cc.find_library('GL')],
-    }]
-  endif
-endif
-
-# Untested
-if need_wgl_functions
-  # FIXME: automagic
-  if cc.has_header('windows.h')
-    feature_conf.set('CAIRO_HAS_WGL_FUNCTIONS', 1)
-    built_features += [{
-      'name': 'cairo-wgl',
-      'description': 'WGL functions',
-    }]
-  endif
-endif
-
 gobject_dep = dependency('gobject-2.0',
   required: get_option('glib'),
   fallback: ['glib', 'libgobject_dep']
@@ -979,9 +850,6 @@ summary({
         'PostScript':  feature_conf.get('CAIRO_HAS_PS_SURFACE', 0) == 1,
         'PDF':  feature_conf.get('CAIRO_HAS_PDF_SURFACE', 0) == 1,
         'SVG':  feature_conf.get('CAIRO_HAS_SVG_SURFACE', 0) == 1,
-        'OpenGL': feature_conf.get('CAIRO_HAS_GL_SURFACE', 0) == 1,
-        'OpenGL ES 2.0': feature_conf.get('CAIRO_HAS_GLESV2_SURFACE', 0) == 1,
-        'OpenGL ES 3.0': feature_conf.get('CAIRO_HAS_GLESV3_SURFACE', 0) == 1,
         }, section: 'Surface Backends', bool_yn: true)
 
 summary({
@@ -995,9 +863,6 @@ summary({
 
 summary({
         'PNG functions': feature_conf.get('CAIRO_HAS_PNG_FUNCTIONS', 0) == 1,
-        'GLX functions': feature_conf.get('CAIRO_HAS_GLX_FUNCTIONS', 0) == 1,
-        'WGL functions': feature_conf.get('CAIRO_HAS_WGL_FUNCTIONS', 0) == 1,
-        'EGL functions': feature_conf.get('CAIRO_HAS_EGL_FUNCTIONS', 0) == 1,
         'X11-xcb': feature_conf.get('CAIRO_HAS_XLIB_XCB_FUNCTIONS', 0) == 1,
         'XCB-shm': feature_conf.get('CAIRO_HAS_XCB_SHM_FUNCTIONS', 0) == 1,
         }, section: 'Functions', bool_yn: true)
diff --git a/meson_options.txt b/meson_options.txt
index 1d4d018c4..4bdfe8a13 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -4,11 +4,6 @@ option('fontconfig', type : 'feature', value : 'auto')
 option('freetype', type : 'feature', value : 'auto')
 
 # Cairo surface backends
-option('gl-backend', type : 'combo', value : 'disabled',
-       # FIXME: https://github.com/mesonbuild/meson/issues/4566
-       choices : ['auto', 'gl', 'glesv2', 'glesv3', 'disabled'])
-option('glesv2', type : 'feature', value : 'disabled')
-option('glesv3', type : 'feature', value : 'disabled')
 option('png', type : 'feature', value : 'auto') # png and svg surfaces
 option('quartz', type : 'feature', value : 'auto')
 option('tee', type : 'feature', value : 'disabled')
@@ -33,8 +28,3 @@ option('symbol-lookup', type: 'feature', value : 'auto',
 # Documentation
 option('gtk_doc', type : 'boolean', value : false,
        description: 'Build the Cairo API reference (depends on gtk-doc)')
-
-# FIXME: implement these to avoid automagic
-#option('egl', type : 'feature', value : 'auto')
-#option('glx', type : 'feature', value : 'auto')
-#option('wgl', type : 'feature', value : 'auto')
diff --git a/src/cairo-egl-context.c b/src/cairo-egl-context.c
deleted file mode 100644
index bf704c630..000000000
--- a/src/cairo-egl-context.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-error-private.h"
-
-typedef struct _cairo_egl_context {
-    cairo_gl_context_t base;
-
-    EGLDisplay display;
-    EGLContext context;
-
-    EGLSurface dummy_surface;
-
-    EGLContext previous_context;
-    EGLSurface previous_surface;
-} cairo_egl_context_t;
-
-typedef struct _cairo_egl_surface {
-    cairo_gl_surface_t base;
-
-    EGLSurface egl;
-} cairo_egl_surface_t;
-
-
-static cairo_bool_t
-_context_acquisition_changed_egl_state (cairo_egl_context_t *ctx,
-					EGLSurface current_surface)
-{
-    return ctx->previous_context != ctx->context ||
-	   ctx->previous_surface != current_surface;
-}
-
-static EGLSurface
-_egl_get_current_surface (cairo_egl_context_t *ctx)
-{
-    if (ctx->base.current_target == NULL ||
-        _cairo_gl_surface_is_texture (ctx->base.current_target)) {
-	return  ctx->dummy_surface;
-    }
-
-    return ((cairo_egl_surface_t *) ctx->base.current_target)->egl;
-}
-
-static void
-_egl_query_current_state (cairo_egl_context_t *ctx)
-{
-    ctx->previous_surface = eglGetCurrentSurface (EGL_DRAW);
-    ctx->previous_context = eglGetCurrentContext ();
-
-    /* If any of the values were none, assume they are all none. Not all
-       drivers seem well behaved when it comes to using these values across
-       multiple threads. */
-    if (ctx->previous_surface == EGL_NO_SURFACE ||
-	ctx->previous_context == EGL_NO_CONTEXT) {
-	ctx->previous_surface = EGL_NO_SURFACE;
-	ctx->previous_context = EGL_NO_CONTEXT;
-    }
-}
-
-static void
-_egl_acquire (void *abstract_ctx)
-{
-    cairo_egl_context_t *ctx = abstract_ctx;
-    EGLSurface current_surface = _egl_get_current_surface (ctx);
-
-    _egl_query_current_state (ctx);
-    if (!_context_acquisition_changed_egl_state (ctx, current_surface))
-	return;
-
-    eglMakeCurrent (ctx->display,
-		    current_surface, current_surface, ctx->context);
-}
-
-static void
-_egl_release (void *abstract_ctx)
-{
-    cairo_egl_context_t *ctx = abstract_ctx;
-    if (!ctx->base.thread_aware ||
-	!_context_acquisition_changed_egl_state (ctx,
-						 _egl_get_current_surface (ctx))) {
-	return;
-    }
-
-    eglMakeCurrent (ctx->display,
-		    EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-}
-
-static void
-_egl_make_current (void *abstract_ctx,
-	           cairo_gl_surface_t *abstract_surface)
-{
-    cairo_egl_context_t *ctx = abstract_ctx;
-    cairo_egl_surface_t *surface = (cairo_egl_surface_t *) abstract_surface;
-
-    eglMakeCurrent(ctx->display, surface->egl, surface->egl, ctx->context);
-}
-
-static void
-_egl_swap_buffers (void *abstract_ctx,
-		   cairo_gl_surface_t *abstract_surface)
-{
-    cairo_egl_context_t *ctx = abstract_ctx;
-    cairo_egl_surface_t *surface = (cairo_egl_surface_t *) abstract_surface;
-
-    eglSwapBuffers (ctx->display, surface->egl);
-}
-
-static void
-_egl_destroy (void *abstract_ctx)
-{
-    cairo_egl_context_t *ctx = abstract_ctx;
-
-    eglMakeCurrent (ctx->display,
-		    EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    if (ctx->dummy_surface != EGL_NO_SURFACE)
-        eglDestroySurface (ctx->display, ctx->dummy_surface);
-}
-
-static cairo_bool_t
-_egl_make_current_surfaceless(cairo_egl_context_t *ctx)
-{
-    const char *extensions;
-
-    extensions = eglQueryString(ctx->display, EGL_EXTENSIONS);
-    if (strstr(extensions, "EGL_KHR_surfaceless_context") == NULL &&
-	strstr(extensions, "EGL_KHR_surfaceless_opengl") == NULL)
-	return FALSE;
-
-    if (!eglMakeCurrent(ctx->display,
-			EGL_NO_SURFACE, EGL_NO_SURFACE, ctx->context))
-	return FALSE;
-
-    return TRUE;
-}
-
-cairo_device_t *
-cairo_egl_device_create (EGLDisplay dpy, EGLContext egl)
-{
-    cairo_egl_context_t *ctx;
-    cairo_status_t status;
-    int attribs[] = {
-	EGL_WIDTH, 1,
-	EGL_HEIGHT, 1,
-	EGL_NONE,
-    };
-    EGLConfig config;
-    EGLint numConfigs;
-
-    ctx = calloc (1, sizeof (cairo_egl_context_t));
-    if (unlikely (ctx == NULL))
-	return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
-
-    ctx->display = dpy;
-    ctx->context = egl;
-
-    ctx->base.acquire = _egl_acquire;
-    ctx->base.release = _egl_release;
-    ctx->base.make_current = _egl_make_current;
-    ctx->base.swap_buffers = _egl_swap_buffers;
-    ctx->base.destroy = _egl_destroy;
-
-    /* We are about the change the current state of EGL, so we should
-     * query the pre-existing surface now instead of later. */
-    _egl_query_current_state (ctx);
-
-    if (!_egl_make_current_surfaceless (ctx)) {
-	/* Fall back to dummy surface, meh. */
-	EGLint config_attribs[] = {
-	    EGL_CONFIG_ID, 0,
-	    EGL_NONE
-	};
-
-	/*
-	 * In order to be able to make an egl context current when using a
-	 * pbuffer surface, that surface must have been created with a config
-	 * that is compatible with the context config. For Mesa, this means
-	 * that the configs must be the same.
-	 */
-	eglQueryContext (dpy, egl, EGL_CONFIG_ID, &config_attribs[1]);
-	eglChooseConfig (dpy, config_attribs, &config, 1, &numConfigs);
-
-	ctx->dummy_surface = eglCreatePbufferSurface (dpy, config, attribs);
-	if (ctx->dummy_surface == NULL) {
-	    free (ctx);
-	    return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
-	}
-
-	if (!eglMakeCurrent (dpy, ctx->dummy_surface, ctx->dummy_surface, egl)) {
-	    free (ctx);
-	    return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
-	}
-    }
-
-    status = _cairo_gl_dispatch_init (&ctx->base.dispatch, eglGetProcAddress);
-    if (unlikely (status)) {
-	free (ctx);
-	return _cairo_gl_context_create_in_error (status);
-    }
-
-    status = _cairo_gl_context_init (&ctx->base);
-    if (unlikely (status)) {
-	if (ctx->dummy_surface != EGL_NO_SURFACE)
-	    eglDestroySurface (dpy, ctx->dummy_surface);
-	free (ctx);
-	return _cairo_gl_context_create_in_error (status);
-    }
-
-    /* Tune the default VBO size to reduce overhead on embedded devices.
-     * This smaller size means that flushing needs to be done more often,
-     * but it is less demanding of scarce memory on embedded devices.
-     */
-    ctx->base.vbo_size = 16*1024;
-
-    eglMakeCurrent (dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-    return &ctx->base.base;
-}
-
-cairo_surface_t *
-cairo_gl_surface_create_for_egl (cairo_device_t	*device,
-				 EGLSurface	 egl,
-				 int		 width,
-				 int		 height)
-{
-    cairo_egl_surface_t *surface;
-
-    if (unlikely (device->status))
-	return _cairo_surface_create_in_error (device->status);
-
-    if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
-
-    if (width <= 0 || height <= 0)
-        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
-
-    surface = calloc (1, sizeof (cairo_egl_surface_t));
-    if (unlikely (surface == NULL))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _cairo_gl_surface_init (device, &surface->base,
-			    CAIRO_CONTENT_COLOR_ALPHA, width, height);
-    surface->egl = egl;
-
-    return &surface->base.base;
-}
-
-static cairo_bool_t is_egl_device (cairo_device_t *device)
-{
-    return (device->backend != NULL &&
-	    device->backend->type == CAIRO_DEVICE_TYPE_GL);
-}
-
-static cairo_egl_context_t *to_egl_context (cairo_device_t *device)
-{
-    return (cairo_egl_context_t *) device;
-}
-
-EGLDisplay
-cairo_egl_device_get_display (cairo_device_t *device)
-{
-    if (! is_egl_device (device)) {
-	_cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
-	return EGL_NO_DISPLAY;
-    }
-
-    return to_egl_context (device)->display;
-}
-
-cairo_public EGLContext
-cairo_egl_device_get_context (cairo_device_t *device)
-{
-    if (! is_egl_device (device)) {
-	_cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
-	return EGL_NO_CONTEXT;
-    }
-
-    return to_egl_context (device)->context;
-}
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
deleted file mode 100644
index 5477ef0d8..000000000
--- a/src/cairo-gl-composite.c
+++ /dev/null
@@ -1,1364 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- * Copyright © 2011 Linaro Limited
- * Copyright © 2011 Samsung Electronics
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- *	Alexandros Frantzis <alexandros.frantzis at linaro.org>
- *	Henry Song <hsong at sisa.samsung.com>
- *	Martin Robinson <mrobinson at igalia.com>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-composite-rectangles-private.h"
-#include "cairo-clip-private.h"
-#include "cairo-error-private.h"
-#include "cairo-image-surface-private.h"
-
-/* FIXME: Copy of same routine in cairo-gl-msaa-compositor.c */
-static cairo_int_status_t
-_draw_int_rect (cairo_gl_context_t      *ctx,
-		cairo_gl_composite_t    *setup,
-		cairo_rectangle_int_t   *rect)
-{
-    cairo_box_t box;
-    cairo_point_t quad[4];
-
-    _cairo_box_from_rectangle (&box, rect);
-    quad[0].x = box.p1.x;
-    quad[0].y = box.p1.y;
-    quad[1].x = box.p1.x;
-    quad[1].y = box.p2.y;
-    quad[2].x = box.p2.x;
-    quad[2].y = box.p2.y;
-    quad[3].x = box.p2.x;
-    quad[3].y = box.p1.y;
-
-    return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad);
-}
-
-static cairo_int_status_t
-_blit_texture_to_renderbuffer (cairo_gl_surface_t *surface)
-{
-    cairo_gl_context_t *ctx = NULL;
-    cairo_gl_composite_t setup;
-    cairo_surface_pattern_t pattern;
-    cairo_rectangle_int_t extents;
-    cairo_int_status_t status;
-
-    /* FIXME: This only permits blit when glesv3 is enabled.  But note that
-       glesv2 with the ANGLE extension should also be able to support this feature,
-       so once the ANGLE support code is in place this check can be relaxed. */
-    if (((cairo_gl_context_t *)surface->base.device)->gl_flavor != CAIRO_GL_FLAVOR_ES3)
-	return CAIRO_INT_STATUS_SUCCESS;
-
-    if (! surface->content_in_texture)
-	return CAIRO_INT_STATUS_SUCCESS;
-
-    memset (&setup, 0, sizeof (cairo_gl_composite_t));
-
-    status = _cairo_gl_composite_set_operator (&setup,
-					       CAIRO_OPERATOR_SOURCE,
-					       FALSE);
-
-    if (status)
-	return status;
-
-    setup.dst = surface;
-    setup.clip_region = surface->clip_region;
-
-    _cairo_pattern_init_for_surface (&pattern, &surface->base);
-    status = _cairo_gl_composite_set_source (&setup, &pattern.base,
-					     NULL, NULL, FALSE);
-    _cairo_pattern_fini (&pattern.base);
-
-    if (unlikely (status))
-	goto FAIL;
-
-    _cairo_gl_composite_set_multisample (&setup);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-
-    if (unlikely (status))
-	goto FAIL;
-
-    extents.x = extents.y = 0;
-    extents.width = surface->width;
-    extents.height = surface->height;
-
-    status = _draw_int_rect (ctx, &setup, &extents);
-
-    if (status == CAIRO_INT_STATUS_SUCCESS)
-	surface->content_in_texture = FALSE;
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-
-    if (ctx) {
-	_cairo_gl_composite_flush (ctx);
-	status = _cairo_gl_context_release (ctx, status);
-    }
-
-    return status;
-}
-
-cairo_int_status_t
-_cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
-				const cairo_pattern_t *pattern,
-				const cairo_rectangle_int_t *sample,
-				const cairo_rectangle_int_t *extents,
-				cairo_bool_t use_texgen)
-{
-    _cairo_gl_operand_destroy (&setup->src);
-    return _cairo_gl_operand_init (&setup->src, pattern, setup->dst,
-				   sample, extents, use_texgen);
-}
-
-void
-_cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup,
-					const cairo_gl_operand_t *source)
-{
-    cairo_int_status_t status;
-
-    _cairo_gl_operand_destroy (&setup->src);
-    _cairo_gl_operand_copy (&setup->src, source);
-
-    if (source->type == CAIRO_GL_OPERAND_TEXTURE)
-	status = _cairo_gl_surface_resolve_multisampling (source->texture.surface);
-}
-
-void
-_cairo_gl_composite_set_solid_source (cairo_gl_composite_t *setup,
-				      const cairo_color_t *color)
-{
-    _cairo_gl_operand_destroy (&setup->src);
-    _cairo_gl_solid_operand_init (&setup->src, color);
-}
-
-cairo_int_status_t
-_cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
-			      const cairo_pattern_t *pattern,
-			      const cairo_rectangle_int_t *sample,
-			      const cairo_rectangle_int_t *extents,
-			      cairo_bool_t use_texgen)
-{
-    _cairo_gl_operand_destroy (&setup->mask);
-    if (pattern == NULL)
-	return CAIRO_STATUS_SUCCESS;
-
-    return _cairo_gl_operand_init (&setup->mask, pattern, setup->dst,
-				   sample, extents, use_texgen);
-}
-
-void
-_cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
-				      const cairo_gl_operand_t *mask)
-{
-    cairo_int_status_t status;
-    _cairo_gl_operand_destroy (&setup->mask);
-    if (mask) {
-	_cairo_gl_operand_copy (&setup->mask, mask);
-	if (mask->type == CAIRO_GL_OPERAND_TEXTURE)
-	    status = _cairo_gl_surface_resolve_multisampling (mask->texture.surface);
-    }
-}
-
-void
-_cairo_gl_composite_set_spans (cairo_gl_composite_t *setup)
-{
-    setup->spans = TRUE;
-}
-
-void
-_cairo_gl_composite_set_multisample (cairo_gl_composite_t *setup)
-{
-    setup->multisample = TRUE;
-}
-
-void
-_cairo_gl_composite_set_clip_region (cairo_gl_composite_t *setup,
-				     cairo_region_t *clip_region)
-{
-    setup->clip_region = clip_region;
-}
-
-void
-_cairo_gl_composite_set_clip (cairo_gl_composite_t *setup,
-			      cairo_clip_t *clip)
-{
-    setup->clip = clip;
-}
-
-static void
-_cairo_gl_composite_bind_to_shader (cairo_gl_context_t   *ctx,
-				    cairo_gl_composite_t *setup)
-{
-    _cairo_gl_shader_bind_matrix4f(ctx, ctx->current_shader->mvp_location,
-				   ctx->modelviewprojection_matrix);
-    _cairo_gl_operand_bind_to_shader (ctx, &setup->src,  CAIRO_GL_TEX_SOURCE);
-    _cairo_gl_operand_bind_to_shader (ctx, &setup->mask, CAIRO_GL_TEX_MASK);
-}
-
-static void
-_cairo_gl_texture_set_filter (cairo_gl_context_t *ctx,
-			      GLuint              target,
-			      cairo_filter_t      filter)
-{
-    switch (filter) {
-    case CAIRO_FILTER_FAST:
-    case CAIRO_FILTER_NEAREST:
-	glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	break;
-    case CAIRO_FILTER_GOOD:
-    case CAIRO_FILTER_BEST:
-    case CAIRO_FILTER_BILINEAR:
-	glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	break;
-    default:
-    case CAIRO_FILTER_GAUSSIAN:
-	ASSERT_NOT_REACHED;
-    }
-}
-
-static void
-_cairo_gl_texture_set_extend (cairo_gl_context_t *ctx,
-			      GLuint              target,
-			      cairo_extend_t      extend)
-{
-    GLint wrap_mode;
-    assert (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base) ||
-	    (extend != CAIRO_EXTEND_REPEAT && extend != CAIRO_EXTEND_REFLECT));
-
-    switch (extend) {
-    case CAIRO_EXTEND_NONE:
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	    ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2)
-	    wrap_mode = GL_CLAMP_TO_EDGE;
-	else
-	    wrap_mode = GL_CLAMP_TO_BORDER;
-	break;
-    case CAIRO_EXTEND_PAD:
-	wrap_mode = GL_CLAMP_TO_EDGE;
-	break;
-    case CAIRO_EXTEND_REPEAT:
-	if (ctx->has_npot_repeat)
-	    wrap_mode = GL_REPEAT;
-	else
-	    wrap_mode = GL_CLAMP_TO_EDGE;
-	break;
-    case CAIRO_EXTEND_REFLECT:
-	if (ctx->has_npot_repeat)
-	    wrap_mode = GL_MIRRORED_REPEAT;
-	else
-	    wrap_mode = GL_CLAMP_TO_EDGE;
-	break;
-    default:
-	wrap_mode = 0;
-    }
-
-    if (likely (wrap_mode)) {
-	glTexParameteri (target, GL_TEXTURE_WRAP_S, wrap_mode);
-	glTexParameteri (target, GL_TEXTURE_WRAP_T, wrap_mode);
-    }
-}
-
-
-static void
-_cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
-				 cairo_gl_tex_t      tex_unit,
-				 cairo_gl_operand_t *operand,
-				 unsigned int        vertex_offset,
-				 cairo_bool_t        vertex_size_changed)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    cairo_bool_t needs_setup;
-
-    /* XXX: we need to do setup when switching from shaders
-     * to no shaders (or back) */
-    needs_setup = vertex_size_changed;
-    needs_setup |= _cairo_gl_operand_needs_setup (&ctx->operands[tex_unit],
-						 operand,
-						 vertex_offset);
-
-    if (needs_setup) {
-	_cairo_gl_composite_flush (ctx);
-	_cairo_gl_context_destroy_operand (ctx, tex_unit);
-    }
-
-    memcpy (&ctx->operands[tex_unit], operand, sizeof (cairo_gl_operand_t));
-    ctx->operands[tex_unit].vertex_offset = vertex_offset;
-
-    if (! needs_setup)
-	return;
-
-    switch (operand->type) {
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-	break;
-	/* fall through */
-    case CAIRO_GL_OPERAND_CONSTANT:
-	break;
-    case CAIRO_GL_OPERAND_TEXTURE:
-	glActiveTexture (GL_TEXTURE0 + tex_unit);
-	glBindTexture (ctx->tex_target, operand->texture.tex);
-	_cairo_gl_texture_set_extend (ctx, ctx->tex_target,
-				      operand->texture.attributes.extend);
-	_cairo_gl_texture_set_filter (ctx, ctx->tex_target,
-				      operand->texture.attributes.filter);
-
-	if (! operand->texture.texgen) {
-	    dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
-					   GL_FLOAT, GL_FALSE, ctx->vertex_size,
-					   ctx->vb + vertex_offset);
-	    dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
-	}
-	break;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	glActiveTexture (GL_TEXTURE0 + tex_unit);
-	glBindTexture (ctx->tex_target, operand->gradient.gradient->tex);
-	_cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->gradient.extend);
-	_cairo_gl_texture_set_filter (ctx, ctx->tex_target, CAIRO_FILTER_BILINEAR);
-
-	if (! operand->gradient.texgen) {
-	    dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
-					   GL_FLOAT, GL_FALSE, ctx->vertex_size,
-					   ctx->vb + vertex_offset);
-	    dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
-	}
-	break;
-    }
-}
-
-static void
-_cairo_gl_context_setup_spans (cairo_gl_context_t *ctx,
-			       cairo_bool_t        spans_enabled,
-			       unsigned int        vertex_size,
-			       unsigned int        vertex_offset)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-
-    if (! spans_enabled) {
-	dispatch->DisableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX);
-	ctx->spans = FALSE;
-	return;
-    }
-
-    dispatch->VertexAttribPointer (CAIRO_GL_COLOR_ATTRIB_INDEX, 4,
-				   GL_UNSIGNED_BYTE, GL_TRUE, vertex_size,
-				   ctx->vb + vertex_offset);
-    dispatch->EnableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX);
-    ctx->spans = TRUE;
-}
-
-void
-_cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
-				   cairo_gl_tex_t tex_unit)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-
-    if  (!_cairo_gl_context_is_flushed (ctx))
-	_cairo_gl_composite_flush (ctx);
-
-    switch (ctx->operands[tex_unit].type) {
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-	break;
-	/* fall through */
-    case CAIRO_GL_OPERAND_CONSTANT:
-	break;
-    case CAIRO_GL_OPERAND_TEXTURE:
-	dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
-	break;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
-	break;
-    }
-
-    memset (&ctx->operands[tex_unit], 0, sizeof (cairo_gl_operand_t));
-}
-
-static void
-_cairo_gl_set_operator (cairo_gl_context_t *ctx,
-			cairo_operator_t    op,
-			cairo_bool_t        component_alpha)
-{
-    struct {
-	GLenum src;
-	GLenum dst;
-    } blend_factors[] = {
-	{ GL_ZERO, GL_ZERO }, /* Clear */
-	{ GL_ONE, GL_ZERO }, /* Source */
-	{ GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, /* Over */
-	{ GL_DST_ALPHA, GL_ZERO }, /* In */
-	{ GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, /* Out */
-	{ GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Atop */
-
-	{ GL_ZERO, GL_ONE }, /* Dest */
-	{ GL_ONE_MINUS_DST_ALPHA, GL_ONE }, /* DestOver */
-	{ GL_ZERO, GL_SRC_ALPHA }, /* DestIn */
-	{ GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, /* DestOut */
-	{ GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, /* DestAtop */
-
-	{ GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Xor */
-	{ GL_ONE, GL_ONE }, /* Add */
-    };
-    GLenum src_factor, dst_factor;
-
-    assert (op < ARRAY_LENGTH (blend_factors));
-    /* different dst and component_alpha changes cause flushes elsewhere */
-    if (ctx->current_operator != op)
-	_cairo_gl_composite_flush (ctx);
-    ctx->current_operator = op;
-
-    src_factor = blend_factors[op].src;
-    dst_factor = blend_factors[op].dst;
-
-    /* Even when the user requests CAIRO_CONTENT_COLOR, we use GL_RGBA
-     * due to texture filtering of GL_CLAMP_TO_BORDER.  So fix those
-     * bits in that case.
-     */
-    if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) {
-	if (src_factor == GL_ONE_MINUS_DST_ALPHA)
-	    src_factor = GL_ZERO;
-	if (src_factor == GL_DST_ALPHA)
-	    src_factor = GL_ONE;
-    }
-
-    if (component_alpha) {
-	if (dst_factor == GL_ONE_MINUS_SRC_ALPHA)
-	    dst_factor = GL_ONE_MINUS_SRC_COLOR;
-	if (dst_factor == GL_SRC_ALPHA)
-	    dst_factor = GL_SRC_COLOR;
-    }
-
-    if (ctx->current_target->base.content == CAIRO_CONTENT_ALPHA) {
-	glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor);
-    } else if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) {
-	glBlendFuncSeparate (src_factor, dst_factor, GL_ONE, GL_ONE);
-    } else {
-	glBlendFunc (src_factor, dst_factor);
-    }
-}
-
-static cairo_status_t
-_cairo_gl_composite_begin_component_alpha  (cairo_gl_context_t *ctx,
-					    cairo_gl_composite_t *setup)
-{
-    cairo_gl_shader_t *pre_shader = NULL;
-    cairo_status_t status;
-
-    /* For CLEAR, cairo's rendering equation (quoting Owen's description in:
-     * https://lists.cairographics.org/archives/cairo/2005-August/004992.html)
-     * is:
-     *     mask IN clip ? src OP dest : dest
-     * or more simply:
-     *     mask IN CLIP ? 0 : dest
-     *
-     * where the ternary operator A ? B : C is (A * B) + ((1 - A) * C).
-     *
-     * The model we use in _cairo_gl_set_operator() is Render's:
-     *     src IN mask IN clip OP dest
-     * which would boil down to:
-     *     0 (bounded by the extents of the drawing).
-     *
-     * However, we can do a Render operation using an opaque source
-     * and DEST_OUT to produce:
-     *    1 IN mask IN clip DEST_OUT dest
-     * which is
-     *    mask IN clip ? 0 : dest
-     */
-    if (setup->op == CAIRO_OPERATOR_CLEAR) {
-	_cairo_gl_solid_operand_init (&setup->src, CAIRO_COLOR_WHITE);
-	setup->op = CAIRO_OPERATOR_DEST_OUT;
-    }
-
-    /*
-     * implements component-alpha %CAIRO_OPERATOR_OVER using two passes of
-     * the simpler operations %CAIRO_OPERATOR_DEST_OUT and %CAIRO_OPERATOR_ADD.
-     *
-     * From http://anholt.livejournal.com/32058.html:
-     *
-     * The trouble is that component-alpha rendering requires two different sources
-     * for blending: one for the source value to the blender, which is the
-     * per-channel multiplication of source and mask, and one for the source alpha
-     * for multiplying with the destination channels, which is the multiplication
-     * of the source channels by the mask alpha. So the equation for Over is:
-     *
-     * dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A
-     * dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R
-     * dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G
-     * dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B
-     *
-     * But we can do some simpler operations, right? How about PictOpOutReverse,
-     * which has a source factor of 0 and dest factor of (1 - source alpha). We
-     * can get the source alpha value (srca.X = src.A * mask.X) out of the texture
-     * blenders pretty easily. So we can do a component-alpha OutReverse, which
-     * gets us:
-     *
-     * dst.A = 0 + (1 - (src.A * mask.A)) * dst.A
-     * dst.R = 0 + (1 - (src.A * mask.R)) * dst.R
-     * dst.G = 0 + (1 - (src.A * mask.G)) * dst.G
-     * dst.B = 0 + (1 - (src.A * mask.B)) * dst.B
-     *
-     * OK. And if an op doesn't use the source alpha value for the destination
-     * factor, then we can do the channel multiplication in the texture blenders
-     * to get the source value, and ignore the source alpha that we wouldn't use.
-     * We've supported this in the Radeon driver for a long time. An example would
-     * be PictOpAdd, which does:
-     *
-     * dst.A = src.A * mask.A + dst.A
-     * dst.R = src.R * mask.R + dst.R
-     * dst.G = src.G * mask.G + dst.G
-     * dst.B = src.B * mask.B + dst.B
-     *
-     * Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right
-     * after it, we get:
-     *
-     * dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A)
-     * dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R)
-     * dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G)
-     * dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B)
-     *
-     * This two-pass trickery could be avoided using a new GL extension that
-     * lets two values come out of the shader and into the blend unit.
-     */
-    if (setup->op == CAIRO_OPERATOR_OVER) {
-	setup->op = CAIRO_OPERATOR_ADD;
-	status = _cairo_gl_get_shader_by_type (ctx,
-					       &setup->src,
-					       &setup->mask,
-					       setup->spans,
-					       CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
-					       &pre_shader);
-	if (unlikely (status))
-	    return status;
-    }
-
-    if (ctx->pre_shader != pre_shader)
-	_cairo_gl_composite_flush (ctx);
-    ctx->pre_shader = pre_shader;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-_scissor_to_doubles (cairo_gl_surface_t	*surface,
-		     double x1, double y1,
-		     double x2, double y2)
-{
-    double height;
-
-    height = y2 - y1;
-    if (_cairo_gl_surface_is_texture (surface) == FALSE)
-	y1 = surface->height - (y1 + height);
-    glScissor (x1, y1, x2 - x1, height);
-    glEnable (GL_SCISSOR_TEST);
-}
-
-void
-_cairo_gl_scissor_to_rectangle (cairo_gl_surface_t *surface,
-		       const cairo_rectangle_int_t *r)
-{
-    _scissor_to_doubles (surface, r->x, r->y, r->x+r->width, r->y+r->height);
-}
-
-static void
-_scissor_to_box (cairo_gl_surface_t	*surface,
-		 const cairo_box_t	*box)
-{
-    double x1, y1, x2, y2;
-    _cairo_box_to_doubles (box, &x1, &y1, &x2, &y2);
-    _scissor_to_doubles (surface, x1, y1, x2, y2);
-}
-
-static cairo_bool_t
-_cairo_gl_composite_setup_vbo (cairo_gl_context_t *ctx,
-			       unsigned int size_per_vertex)
-{
-    cairo_bool_t vertex_size_changed = ctx->vertex_size != size_per_vertex;
-    if (vertex_size_changed) {
-	ctx->vertex_size = size_per_vertex;
-	_cairo_gl_composite_flush (ctx);
-    }
-
-    if (_cairo_gl_context_is_flushed (ctx)) {
-	ctx->dispatch.VertexAttribPointer (CAIRO_GL_VERTEX_ATTRIB_INDEX, 2,
-					   GL_FLOAT, GL_FALSE, size_per_vertex,
-					   ctx->vb);
-	ctx->dispatch.EnableVertexAttribArray (CAIRO_GL_VERTEX_ATTRIB_INDEX);
-    }
-
-    return vertex_size_changed;
-}
-
-static void
-_disable_stencil_buffer (void)
-{
-    glDisable (GL_STENCIL_TEST);
-    glDepthMask (GL_FALSE);
-}
-
-static cairo_int_status_t
-_cairo_gl_composite_setup_painted_clipping (cairo_gl_composite_t *setup,
-					    cairo_gl_context_t *ctx,
-					    int vertex_size)
-{
-    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
-    cairo_gl_surface_t *dst = setup->dst;
-    cairo_clip_t *clip = setup->clip;
-
-    if (clip->num_boxes == 1 && clip->path == NULL) {
-	_scissor_to_box (dst, &clip->boxes[0]);
-	goto disable_stencil_buffer_and_return;
-    }
-
-    if (! _cairo_gl_ensure_stencil (ctx, setup->dst)) {
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-	goto disable_stencil_buffer_and_return;
-    }
-
-    /* We only want to clear the part of the stencil buffer
-     * that we are about to use. It also does not hurt to
-     * scissor around the painted clip. */
-    _cairo_gl_scissor_to_rectangle (dst, _cairo_clip_get_extents (clip));
-
-    /* The clip is not rectangular, so use the stencil buffer. */
-    glDepthMask (GL_TRUE);
-    glEnable (GL_STENCIL_TEST);
-
-    /* Texture surfaces have private depth/stencil buffers, so we can
-     * rely on any previous clip being cached there. */
-    if (_cairo_gl_surface_is_texture (setup->dst)) {
-	cairo_clip_t *old_clip = setup->dst->clip_on_stencil_buffer;
-	if (_cairo_clip_equal (old_clip, setup->clip))
-	    goto activate_stencil_buffer_and_return;
-
-	if (old_clip) {
-	    _cairo_clip_destroy (setup->dst->clip_on_stencil_buffer);
-	}
-
-	setup->dst->clip_on_stencil_buffer = _cairo_clip_copy (setup->clip);
-    }
-
-    glClearStencil (0);
-    glClear (GL_STENCIL_BUFFER_BIT);
-
-    glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE);
-    glStencilFunc (GL_EQUAL, 1, 0xffffffff);
-    glColorMask (0, 0, 0, 0);
-
-    status = _cairo_gl_msaa_compositor_draw_clip (ctx, setup, clip);
-
-    if (unlikely (status)) {
-	glColorMask (1, 1, 1, 1);
-	goto disable_stencil_buffer_and_return;
-    }
-
-    /* We want to only render to the stencil buffer, so draw everything now.
-       Flushing also unbinds the VBO, which we want to rebind for regular
-       drawing. */
-    _cairo_gl_composite_flush (ctx);
-    _cairo_gl_composite_setup_vbo (ctx, vertex_size);
-
-activate_stencil_buffer_and_return:
-    glColorMask (1, 1, 1, 1);
-    glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
-    glStencilFunc (GL_EQUAL, 1, 0xffffffff);
-    return CAIRO_INT_STATUS_SUCCESS;
-
-disable_stencil_buffer_and_return:
-    _disable_stencil_buffer ();
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_gl_composite_setup_clipping (cairo_gl_composite_t *setup,
-				    cairo_gl_context_t *ctx,
-				    int vertex_size)
-{
-    cairo_bool_t clip_changing = TRUE;
-    cairo_bool_t clip_region_changing = TRUE;
-
-    if (! ctx->clip && ! setup->clip && ! setup->clip_region && ! ctx->clip_region)
-	goto disable_all_clipping;
-
-    clip_changing = ! _cairo_clip_equal (ctx->clip, setup->clip);
-    clip_region_changing = ! cairo_region_equal (ctx->clip_region, setup->clip_region);
-    if (! _cairo_gl_context_is_flushed (ctx) &&
-	(clip_region_changing || clip_changing))
-	_cairo_gl_composite_flush (ctx);
-
-    assert (!setup->clip_region || !setup->clip);
-
-    /* setup->clip is only used by the msaa compositor and setup->clip_region
-     * only by the other compositors, so it's safe to wait to clean up obsolete
-     * clips. */
-    if (clip_region_changing) {
-	cairo_region_destroy (ctx->clip_region);
-	ctx->clip_region = cairo_region_reference (setup->clip_region);
-    }
-    if (clip_changing) {
-	_cairo_clip_destroy (ctx->clip);
-	ctx->clip = _cairo_clip_copy (setup->clip);
-    }
-
-    /* For clip regions, we scissor right before drawing. */
-    if (setup->clip_region)
-	goto disable_all_clipping;
-
-    if (setup->clip)
-	return _cairo_gl_composite_setup_painted_clipping (setup, ctx,
-							   vertex_size);
-disable_all_clipping:
-    _disable_stencil_buffer ();
-    glDisable (GL_SCISSOR_TEST);
-    return CAIRO_INT_STATUS_SUCCESS;
-}
-
-cairo_status_t
-_cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup,
-				     cairo_gl_context_t *ctx)
-{
-    unsigned int dst_size, src_size, mask_size, vertex_size;
-    cairo_status_t status;
-    cairo_gl_shader_t *shader;
-    cairo_bool_t component_alpha;
-    cairo_bool_t vertex_size_changed;
-
-    component_alpha =
-	setup->mask.type == CAIRO_GL_OPERAND_TEXTURE &&
-	setup->mask.texture.attributes.has_component_alpha;
-
-    /* Do various magic for component alpha */
-    if (component_alpha) {
-	status = _cairo_gl_composite_begin_component_alpha (ctx, setup);
-	if (unlikely (status))
-	    return status;
-     } else {
-	if (ctx->pre_shader) {
-	    _cairo_gl_composite_flush (ctx);
-	    ctx->pre_shader = NULL;
-	}
-    }
-
-    status = _cairo_gl_get_shader_by_type (ctx,
-					   &setup->src,
-					   &setup->mask,
-					   setup->spans,
-					   component_alpha ?
-					   CAIRO_GL_SHADER_IN_CA_SOURCE :
-					   CAIRO_GL_SHADER_IN_NORMAL,
-					   &shader);
-    if (unlikely (status)) {
-	ctx->pre_shader = NULL;
-	return status;
-    }
-    if (ctx->current_shader != shader)
-	_cairo_gl_composite_flush (ctx);
-
-    status = CAIRO_STATUS_SUCCESS;
-
-    dst_size = 2 * sizeof (GLfloat);
-    src_size = _cairo_gl_operand_get_vertex_size (&setup->src);
-    mask_size = _cairo_gl_operand_get_vertex_size (&setup->mask);
-    vertex_size = dst_size + src_size + mask_size;
-
-    if (setup->spans)
-	vertex_size += sizeof (GLfloat);
-
-    vertex_size_changed = _cairo_gl_composite_setup_vbo (ctx, vertex_size);
-
-    _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_SOURCE, &setup->src, dst_size, vertex_size_changed);
-    _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_MASK, &setup->mask, dst_size + src_size, vertex_size_changed);
-
-    _cairo_gl_context_setup_spans (ctx, setup->spans, vertex_size,
-				   dst_size + src_size + mask_size);
-
-    _cairo_gl_set_operator (ctx, setup->op, component_alpha);
-
-    if (_cairo_gl_context_is_flushed (ctx)) {
-	if (ctx->pre_shader) {
-	    _cairo_gl_set_shader (ctx, ctx->pre_shader);
-	    _cairo_gl_composite_bind_to_shader (ctx, setup);
-	}
-	_cairo_gl_set_shader (ctx, shader);
-	_cairo_gl_composite_bind_to_shader (ctx, setup);
-    }
-
-    return status;
-}
-
-cairo_status_t
-_cairo_gl_composite_begin (cairo_gl_composite_t *setup,
-			   cairo_gl_context_t **ctx_out)
-{
-    cairo_gl_context_t *ctx;
-    cairo_status_t status;
-
-    assert (setup->dst);
-
-    status = _cairo_gl_context_acquire (setup->dst->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    _cairo_gl_context_set_destination (ctx, setup->dst, setup->multisample);
-    glEnable (GL_BLEND);
-
-    status = _cairo_gl_set_operands_and_operator (setup, ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    status = _cairo_gl_composite_setup_clipping (setup, ctx, ctx->vertex_size);
-    if (unlikely (status))
-	goto FAIL;
-
-    *ctx_out = ctx;
-
-FAIL:
-    if (unlikely (status))
-	status = _cairo_gl_context_release (ctx, status);
-
-    return status;
-}
-
-static inline void
-_cairo_gl_composite_draw_tristrip (cairo_gl_context_t *ctx)
-{
-    cairo_array_t* indices = &ctx->tristrip_indices;
-    const unsigned short *indices_array = _cairo_array_index_const (indices, 0);
-
-    if (ctx->pre_shader) {
-	cairo_gl_shader_t *prev_shader = ctx->current_shader;
-
-	_cairo_gl_set_shader (ctx, ctx->pre_shader);
-	_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE);
-	glDrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, indices_array);
-
-	_cairo_gl_set_shader (ctx, prev_shader);
-	_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
-    }
-
-    glDrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, indices_array);
-    _cairo_array_truncate (indices, 0);
-}
-
-static inline void
-_cairo_gl_composite_draw_triangles (cairo_gl_context_t *ctx,
-				    unsigned int count)
-{
-    if (! ctx->pre_shader) {
-	glDrawArrays (GL_TRIANGLES, 0, count);
-    } else {
-	cairo_gl_shader_t *prev_shader = ctx->current_shader;
-
-	_cairo_gl_set_shader (ctx, ctx->pre_shader);
-	_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE);
-	glDrawArrays (GL_TRIANGLES, 0, count);
-
-	_cairo_gl_set_shader (ctx, prev_shader);
-	_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
-	glDrawArrays (GL_TRIANGLES, 0, count);
-    }
-}
-
-static void
-_cairo_gl_composite_draw_triangles_with_clip_region (cairo_gl_context_t *ctx,
-						     unsigned int count)
-{
-    int i, num_rectangles;
-
-    if (!ctx->clip_region) {
-	_cairo_gl_composite_draw_triangles (ctx, count);
-	return;
-    }
-
-    num_rectangles = cairo_region_num_rectangles (ctx->clip_region);
-    for (i = 0; i < num_rectangles; i++) {
-	cairo_rectangle_int_t rect;
-
-	cairo_region_get_rectangle (ctx->clip_region, i, &rect);
-
-	_cairo_gl_scissor_to_rectangle (ctx->current_target, &rect);
-	_cairo_gl_composite_draw_triangles (ctx, count);
-    }
-}
-
-static void
-_cairo_gl_composite_unmap_vertex_buffer (cairo_gl_context_t *ctx)
-{
-    ctx->vb_offset = 0;
-}
-
-void
-_cairo_gl_composite_flush (cairo_gl_context_t *ctx)
-{
-    unsigned int count;
-    int i;
-
-    if (_cairo_gl_context_is_flushed (ctx))
-	return;
-
-    count = ctx->vb_offset / ctx->vertex_size;
-    _cairo_gl_composite_unmap_vertex_buffer (ctx);
-
-    if (ctx->primitive_type == CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS) {
-	_cairo_gl_composite_draw_tristrip (ctx);
-    } else {
-	assert (ctx->primitive_type == CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
-	_cairo_gl_composite_draw_triangles_with_clip_region (ctx, count);
-    }
-
-    for (i = 0; i < ARRAY_LENGTH (ctx->glyph_cache); i++)
-	_cairo_gl_glyph_cache_unlock (&ctx->glyph_cache[i]);
-}
-
-static void
-_cairo_gl_composite_prepare_buffer (cairo_gl_context_t *ctx,
-				    unsigned int n_vertices,
-				    cairo_gl_primitive_type_t primitive_type)
-{
-    if (ctx->primitive_type != primitive_type) {
-	_cairo_gl_composite_flush (ctx);
-	ctx->primitive_type = primitive_type;
-    }
-
-    assert(ctx->vbo_size > 0);
-    if (ctx->vb_offset + n_vertices * ctx->vertex_size > ctx->vbo_size)
-	_cairo_gl_composite_flush (ctx);
-}
-
-static inline void
-_cairo_gl_composite_emit_vertex (cairo_gl_context_t *ctx,
-				 GLfloat x, GLfloat y)
-{
-    GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
-
-    *vb++ = x;
-    *vb++ = y;
-
-    _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y);
-    _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_MASK  ], &vb, x, y);
-
-    ctx->vb_offset += ctx->vertex_size;
-}
-
-static inline void
-_cairo_gl_composite_emit_alpha_vertex (cairo_gl_context_t *ctx,
-				       GLfloat x, GLfloat y, uint8_t alpha)
-{
-    GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
-    union fi {
-	float f;
-	GLbyte bytes[4];
-    } fi;
-
-    *vb++ = x;
-    *vb++ = y;
-
-    _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y);
-    _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_MASK  ], &vb, x, y);
-
-    fi.bytes[0] = 0;
-    fi.bytes[1] = 0;
-    fi.bytes[2] = 0;
-    fi.bytes[3] = alpha;
-    *vb++ = fi.f;
-
-    ctx->vb_offset += ctx->vertex_size;
-}
-
-static void
-_cairo_gl_composite_emit_point (cairo_gl_context_t	*ctx,
-				const cairo_point_t	*point)
-{
-    _cairo_gl_composite_emit_vertex (ctx,
-				     _cairo_fixed_to_double (point->x),
-				     _cairo_fixed_to_double (point->y));
-}
-
-static void
-_cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
-			       GLfloat x1, GLfloat y1,
-			       GLfloat x2, GLfloat y2)
-{
-    _cairo_gl_composite_prepare_buffer (ctx, 6,
-					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
-
-    _cairo_gl_composite_emit_vertex (ctx, x1, y1);
-    _cairo_gl_composite_emit_vertex (ctx, x2, y1);
-    _cairo_gl_composite_emit_vertex (ctx, x1, y2);
-
-    _cairo_gl_composite_emit_vertex (ctx, x2, y1);
-    _cairo_gl_composite_emit_vertex (ctx, x2, y2);
-    _cairo_gl_composite_emit_vertex (ctx, x1, y2);
-}
-
-cairo_gl_emit_rect_t
-_cairo_gl_context_choose_emit_rect (cairo_gl_context_t *ctx)
-{
-    return _cairo_gl_composite_emit_rect;
-}
-
-void
-_cairo_gl_context_emit_rect (cairo_gl_context_t *ctx,
-			     GLfloat x1, GLfloat y1,
-			     GLfloat x2, GLfloat y2)
-{
-    _cairo_gl_composite_emit_rect (ctx, x1, y1, x2, y2);
-}
-
-static void
-_cairo_gl_composite_emit_span (cairo_gl_context_t *ctx,
-			       GLfloat x1, GLfloat y1,
-			       GLfloat x2, GLfloat y2,
-			       uint8_t alpha)
-{
-    _cairo_gl_composite_prepare_buffer (ctx, 6,
-					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
-
-    _cairo_gl_composite_emit_alpha_vertex (ctx, x1, y1, alpha);
-    _cairo_gl_composite_emit_alpha_vertex (ctx, x2, y1, alpha);
-    _cairo_gl_composite_emit_alpha_vertex (ctx, x1, y2, alpha);
-
-    _cairo_gl_composite_emit_alpha_vertex (ctx, x2, y1, alpha);
-    _cairo_gl_composite_emit_alpha_vertex (ctx, x2, y2, alpha);
-    _cairo_gl_composite_emit_alpha_vertex (ctx, x1, y2, alpha);
-}
-
-static void
-_cairo_gl_composite_emit_solid_span (cairo_gl_context_t *ctx,
-				     GLfloat x1, GLfloat y1,
-				     GLfloat x2, GLfloat y2,
-				     uint8_t alpha)
-{
-    GLfloat *v;
-    union fi {
-	float f;
-	GLbyte bytes[4];
-    } fi;
-
-    _cairo_gl_composite_prepare_buffer (ctx, 6,
-					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
-    v = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
-
-    v[15] = v[ 6] = v[0] = x1;
-    v[10] = v[ 4] = v[1] = y1;
-    v[12] = v[ 9] = v[3] = x2;
-    v[16] = v[13] = v[7] = y2;
-
-    fi.bytes[0] = 0;
-    fi.bytes[1] = 0;
-    fi.bytes[2] = 0;
-    fi.bytes[3] = alpha;
-    v[17] =v[14] = v[11] = v[8] = v[5] = v[2] = fi.f;
-
-    ctx->vb_offset += 6*3 * sizeof(GLfloat);
-}
-
-cairo_gl_emit_span_t
-_cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
-{
-    if (ctx->operands[CAIRO_GL_TEX_MASK].type != CAIRO_GL_OPERAND_NONE) {
-	    switch (ctx->operands[CAIRO_GL_TEX_MASK].type) {
-	    default:
-	    case CAIRO_GL_OPERAND_COUNT:
-		    ASSERT_NOT_REACHED;
-	    case CAIRO_GL_OPERAND_NONE:
-	    case CAIRO_GL_OPERAND_CONSTANT:
-		    break;
-
-	    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-	    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-	    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-	    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-		    if (!ctx->operands[CAIRO_GL_TEX_MASK].gradient.texgen)
-			    return _cairo_gl_composite_emit_span;
-		    break;
-
-	    case CAIRO_GL_OPERAND_TEXTURE:
-		    if (!ctx->operands[CAIRO_GL_TEX_MASK].texture.texgen)
-			    return _cairo_gl_composite_emit_span;
-		    break;
-	    }
-    }
-
-    switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-    case CAIRO_GL_OPERAND_CONSTANT:
-	break;
-
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	if (!ctx->operands[CAIRO_GL_TEX_SOURCE].gradient.texgen)
-		return _cairo_gl_composite_emit_span;
-	break;
-
-    case CAIRO_GL_OPERAND_TEXTURE:
-	if (!ctx->operands[CAIRO_GL_TEX_SOURCE].texture.texgen)
-		return _cairo_gl_composite_emit_span;
-    }
-
-    return _cairo_gl_composite_emit_solid_span;
-}
-
-static inline void
-_cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
-				       GLfloat x, GLfloat y,
-				       GLfloat glyph_x, GLfloat glyph_y)
-{
-    GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
-
-    *vb++ = x;
-    *vb++ = y;
-
-    _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y);
-
-    *vb++ = glyph_x;
-    *vb++ = glyph_y;
-
-    ctx->vb_offset += ctx->vertex_size;
-}
-
-static void
-_cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
-				GLfloat x1, GLfloat y1,
-				GLfloat x2, GLfloat y2,
-				GLfloat glyph_x1, GLfloat glyph_y1,
-				GLfloat glyph_x2, GLfloat glyph_y2)
-{
-    _cairo_gl_composite_prepare_buffer (ctx, 6,
-					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
-
-    _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y1, glyph_x1, glyph_y1);
-    _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1);
-    _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
-
-    _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1);
-    _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y2, glyph_x2, glyph_y2);
-    _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
-}
-
-static void
-_cairo_gl_composite_emit_solid_glyph (cairo_gl_context_t *ctx,
-				      GLfloat x1, GLfloat y1,
-				      GLfloat x2, GLfloat y2,
-				      GLfloat glyph_x1, GLfloat glyph_y1,
-				      GLfloat glyph_x2, GLfloat glyph_y2)
-{
-    GLfloat *v;
-
-    _cairo_gl_composite_prepare_buffer (ctx, 6,
-					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
-
-    v = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
-
-    v[20] = v[ 8] = v[0] = x1;
-    v[13] = v[ 5] = v[1] = y1;
-    v[22] = v[10] = v[2] = glyph_x1;
-    v[15] = v[ 7] = v[3] = glyph_y1;
-
-    v[16] = v[12] = v[4] = x2;
-    v[18] = v[14] = v[6] = glyph_x2;
-
-    v[21] = v[17] = v[ 9] = y2;
-    v[23] = v[19] = v[11] = glyph_y2;
-
-    ctx->vb_offset += 4 * 6 * sizeof (GLfloat);
-}
-
-cairo_gl_emit_glyph_t
-_cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx)
-{
-    switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-    case CAIRO_GL_OPERAND_CONSTANT:
-	return _cairo_gl_composite_emit_solid_glyph;
-
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-    case CAIRO_GL_OPERAND_TEXTURE:
-	return _cairo_gl_composite_emit_glyph;
-    }
-}
-
-void
-_cairo_gl_composite_fini (cairo_gl_composite_t *setup)
-{
-    _cairo_gl_operand_destroy (&setup->src);
-    _cairo_gl_operand_destroy (&setup->mask);
-}
-
-cairo_status_t
-_cairo_gl_composite_set_operator (cairo_gl_composite_t *setup,
-				  cairo_operator_t op,
-				  cairo_bool_t assume_component_alpha)
-{
-    if (assume_component_alpha) {
-	if (op != CAIRO_OPERATOR_CLEAR &&
-	    op != CAIRO_OPERATOR_OVER &&
-	    op != CAIRO_OPERATOR_ADD)
-	    return UNSUPPORTED ("unsupported component alpha operator");
-    } else {
-	if (! _cairo_gl_operator_is_supported (op))
-	    return UNSUPPORTED ("unsupported operator");
-    }
-
-    setup->op = op;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_status_t
-_cairo_gl_composite_init (cairo_gl_composite_t *setup,
-			  cairo_operator_t op,
-			  cairo_gl_surface_t *dst,
-			  cairo_bool_t assume_component_alpha)
-{
-    cairo_status_t status;
-
-    status = _blit_texture_to_renderbuffer (dst);
-
-    memset (setup, 0, sizeof (cairo_gl_composite_t));
-
-    status = _cairo_gl_composite_set_operator (setup, op,
-					       assume_component_alpha);
-    if (status)
-	return status;
-
-    setup->dst = dst;
-    setup->clip_region = dst->clip_region;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-_cairo_gl_composite_append_vertex_indices (cairo_gl_context_t	*ctx,
-					   int			 number_of_new_indices)
-{
-    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-    cairo_array_t *indices = &ctx->tristrip_indices;
-    int number_of_indices = _cairo_array_num_elements (indices);
-    unsigned short current_vertex_index = 0;
-    int i;
-
-    assert (number_of_new_indices > 0);
-
-    /* If any preexisting triangle triangle strip indices exist on this
-       context, we insert a set of degenerate triangles from the last
-       preexisting vertex to our first one. */
-    if (number_of_indices > 0) {
-	const unsigned short *indices_array = _cairo_array_index_const (indices, 0);
-	current_vertex_index = indices_array[number_of_indices - 1];
-
-	status = _cairo_array_append (indices, &current_vertex_index);
-	if (unlikely (status))
-	    return status;
-
-	current_vertex_index++;
-	status =_cairo_array_append (indices, &current_vertex_index);
-	if (unlikely (status))
-	    return status;
-    }
-
-    for (i = 0; i < number_of_new_indices; i++) {
-	status = _cairo_array_append (indices, &current_vertex_index);
-	current_vertex_index++;
-	if (unlikely (status))
-	    return status;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_int_status_t
-_cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t	*ctx,
-					   cairo_gl_composite_t	*setup,
-					   const cairo_point_t	quad[4])
-{
-    _cairo_gl_composite_prepare_buffer (ctx, 4,
-					CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS);
-
-    _cairo_gl_composite_emit_point (ctx, &quad[0]);
-    _cairo_gl_composite_emit_point (ctx, &quad[1]);
-
-    /* Cairo stores quad vertices in counter-clockwise order, but we need to
-       emit them from top to bottom in the triangle strip, so we need to reverse
-       the order of the last two vertices. */
-    _cairo_gl_composite_emit_point (ctx, &quad[3]);
-    _cairo_gl_composite_emit_point (ctx, &quad[2]);
-
-    return _cairo_gl_composite_append_vertex_indices (ctx, 4);
-}
-
-cairo_int_status_t
-_cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t	*ctx,
-					       cairo_gl_composite_t	*setup,
-					       const cairo_point_t	 triangle[3])
-{
-    _cairo_gl_composite_prepare_buffer (ctx, 3,
-					CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS);
-
-    _cairo_gl_composite_emit_point (ctx, &triangle[0]);
-    _cairo_gl_composite_emit_point (ctx, &triangle[1]);
-    _cairo_gl_composite_emit_point (ctx, &triangle[2]);
-    return _cairo_gl_composite_append_vertex_indices (ctx, 3);
-}
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
deleted file mode 100644
index 6f4c852a4..000000000
--- a/src/cairo-gl-device.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- * Copyright © 2010 Linaro Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- *	Alexandros Frantzis <alexandros.frantzis at linaro.org>
- */
-
-#include "cairoint.h"
-
-#include "cairo-error-private.h"
-#include "cairo-gl-private.h"
-
-#define MAX_MSAA_SAMPLES 4
-
-static void
-_gl_lock (void *device)
-{
-    cairo_gl_context_t *ctx = (cairo_gl_context_t *) device;
-
-    ctx->acquire (ctx);
-}
-
-static void
-_gl_unlock (void *device)
-{
-    cairo_gl_context_t *ctx = (cairo_gl_context_t *) device;
-
-    ctx->release (ctx);
-}
-
-static cairo_status_t
-_gl_flush (void *device)
-{
-    cairo_gl_context_t *ctx;
-    cairo_status_t status;
-
-    status = _cairo_gl_context_acquire (device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    _cairo_gl_composite_flush (ctx);
-
-    _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE);
-    _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK);
-
-    if (ctx->clip_region) {
-	cairo_region_destroy (ctx->clip_region);
-	ctx->clip_region = NULL;
-    }
-
-    ctx->current_target = NULL;
-    ctx->current_operator = -1;
-    ctx->vertex_size = 0;
-    ctx->pre_shader = NULL;
-    _cairo_gl_set_shader (ctx, NULL);
-
-    ctx->dispatch.BindBuffer (GL_ARRAY_BUFFER, 0);
-
-    glDisable (GL_SCISSOR_TEST);
-    glDisable (GL_BLEND);
-
-    return _cairo_gl_context_release (ctx, status);
-}
-
-static void
-_gl_finish (void *device)
-{
-    cairo_gl_context_t *ctx = device;
-    int n;
-
-    _gl_lock (device);
-
-    _cairo_cache_fini (&ctx->gradients);
-
-    _cairo_gl_context_fini_shaders (ctx);
-
-    for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++)
-	_cairo_gl_glyph_cache_fini (ctx, &ctx->glyph_cache[n]);
-
-    _gl_unlock (device);
-}
-
-static void
-_gl_destroy (void *device)
-{
-    cairo_gl_context_t *ctx = device;
-
-    ctx->acquire (ctx);
-
-    while (! cairo_list_is_empty (&ctx->fonts)) {
-	cairo_gl_font_t *font;
-
-	font = cairo_list_first_entry (&ctx->fonts,
-				       cairo_gl_font_t,
-				       link);
-
-	cairo_list_del (&font->base.link);
-	cairo_list_del (&font->link);
-	free (font);
-    }
-
-    _cairo_array_fini (&ctx->tristrip_indices);
-
-    cairo_region_destroy (ctx->clip_region);
-    _cairo_clip_destroy (ctx->clip);
-
-    free (ctx->vb);
-
-    ctx->destroy (ctx);
-
-    free (ctx);
-}
-
-static const cairo_device_backend_t _cairo_gl_device_backend = {
-    CAIRO_DEVICE_TYPE_GL,
-
-    _gl_lock,
-    _gl_unlock,
-
-    _gl_flush, /* flush */
-    _gl_finish,
-    _gl_destroy,
-};
-
-static cairo_bool_t
-_cairo_gl_msaa_compositor_enabled (void)
-{
-    const char *env = getenv ("CAIRO_GL_COMPOSITOR");
-    return env && strcmp(env, "msaa") == 0;
-}
-
-static cairo_bool_t
-test_can_read_bgra (cairo_gl_flavor_t gl_flavor)
-{
-    /* Desktop GL always supports BGRA formats. */
-    if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
-	return TRUE;
-
-    assert (gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	    gl_flavor == CAIRO_GL_FLAVOR_ES2);
-
-   /* For OpenGL ES we have to look for the specific extension and BGRA only
-    * matches cairo's integer packed bytes on little-endian machines. */
-    if (!_cairo_is_little_endian())
-	return FALSE;
-    return _cairo_gl_has_extension ("EXT_read_format_bgra");
-}
-
-cairo_status_t
-_cairo_gl_context_init (cairo_gl_context_t *ctx)
-{
-    cairo_status_t status;
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    int gl_version = _cairo_gl_get_version ();
-    cairo_gl_flavor_t gl_flavor = _cairo_gl_get_flavor ();
-    int n;
-
-    cairo_bool_t is_desktop = gl_flavor == CAIRO_GL_FLAVOR_DESKTOP;
-    cairo_bool_t is_gles = (gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-			    gl_flavor == CAIRO_GL_FLAVOR_ES2);
-
-    _cairo_device_init (&ctx->base, &_cairo_gl_device_backend);
-
-    /* XXX The choice of compositor should be made automatically at runtime.
-     * However, it is useful to force one particular compositor whilst
-     * testing.
-     */
-     if (_cairo_gl_msaa_compositor_enabled ())
-	ctx->compositor = _cairo_gl_msaa_compositor_get ();
-    else
-	ctx->compositor = _cairo_gl_span_compositor_get ();
-
-
-    ctx->thread_aware = TRUE;
-
-    memset (ctx->glyph_cache, 0, sizeof (ctx->glyph_cache));
-    cairo_list_init (&ctx->fonts);
-
-    /* Support only GL version >= 1.3 */
-    if (gl_version < CAIRO_GL_VERSION_ENCODE (1, 3))
-	return _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
-
-    /* Check for required extensions */
-    if (is_desktop) {
-	if (_cairo_gl_has_extension ("GL_ARB_texture_non_power_of_two")) {
-	    ctx->tex_target = GL_TEXTURE_2D;
-	    ctx->has_npot_repeat = TRUE;
-	} else if (_cairo_gl_has_extension ("GL_ARB_texture_rectangle")) {
-	    ctx->tex_target = GL_TEXTURE_RECTANGLE;
-	    ctx->has_npot_repeat = FALSE;
-	} else
-	    return _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
-    } else {
-	ctx->tex_target = GL_TEXTURE_2D;
-	if (_cairo_gl_has_extension ("GL_OES_texture_npot") ||
-	    _cairo_gl_has_extension ("GL_IMG_texture_npot"))
-	    ctx->has_npot_repeat = TRUE;
-	else
-	    ctx->has_npot_repeat = FALSE;
-    }
-
-    if (is_desktop && gl_version < CAIRO_GL_VERSION_ENCODE (2, 1) &&
-	! _cairo_gl_has_extension ("GL_ARB_pixel_buffer_object"))
-	return _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
-
-    if (is_gles && ! _cairo_gl_has_extension ("GL_EXT_texture_format_BGRA8888"))
-	return _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
-
-    ctx->has_map_buffer =
-	is_desktop || (is_gles && _cairo_gl_has_extension ("GL_OES_mapbuffer"));
-
-    ctx->can_read_bgra = test_can_read_bgra (gl_flavor);
-
-    ctx->has_mesa_pack_invert =
-	_cairo_gl_has_extension ("GL_MESA_pack_invert");
-
-    ctx->has_packed_depth_stencil =
-	(is_desktop && _cairo_gl_has_extension ("GL_EXT_packed_depth_stencil")) ||
-	(is_gles && _cairo_gl_has_extension ("GL_OES_packed_depth_stencil"));
-
-    ctx->num_samples = 1;
-
-#if CAIRO_HAS_GL_SURFACE
-    if (is_desktop && ctx->has_packed_depth_stencil &&
-	(gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) ||
-	 _cairo_gl_has_extension ("GL_ARB_framebuffer_object") ||
-	 (_cairo_gl_has_extension ("GL_EXT_framebuffer_blit") &&
-	  _cairo_gl_has_extension ("GL_EXT_framebuffer_multisample")))) {
-	glGetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples);
-    }
-#endif
-
-#if CAIRO_HAS_GLESV3_SURFACE
-    if (is_gles && ctx->has_packed_depth_stencil) {
-	glGetIntegerv(GL_MAX_SAMPLES, &ctx->num_samples);
-    }
-
-#elif CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_EXT)
-    if (is_gles && ctx->has_packed_depth_stencil &&
-	_cairo_gl_has_extension ("GL_EXT_multisampled_render_to_texture")) {
-	glGetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples);
-    }
-
-    if (is_gles && ctx->has_packed_depth_stencil &&
-	_cairo_gl_has_extension ("GL_IMG_multisampled_render_to_texture")) {
-	glGetIntegerv(GL_MAX_SAMPLES_IMG, &ctx->num_samples);
-    }
-#endif
-
-    /* we always use renderbuffer for rendering in glesv3 */
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	ctx->supports_msaa = TRUE;
-    else
-	ctx->supports_msaa = ctx->num_samples > 1;
-    if (ctx->num_samples > MAX_MSAA_SAMPLES)
-	ctx->num_samples = MAX_MSAA_SAMPLES;
-
-    ctx->current_operator = -1;
-    ctx->gl_flavor = gl_flavor;
-
-    status = _cairo_gl_context_init_shaders (ctx);
-    if (unlikely (status))
-	return status;
-
-    status = _cairo_cache_init (&ctx->gradients,
-				_cairo_gl_gradient_equal,
-				NULL,
-				(cairo_destroy_func_t) _cairo_gl_gradient_destroy,
-				CAIRO_GL_GRADIENT_CACHE_SIZE);
-    if (unlikely (status))
-	return status;
-
-    ctx->vbo_size = _cairo_gl_get_vbo_size();
-
-    ctx->vb = _cairo_malloc (ctx->vbo_size);
-    if (unlikely (ctx->vb == NULL)) {
-	    _cairo_cache_fini (&ctx->gradients);
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    ctx->primitive_type = CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES;
-    _cairo_array_init (&ctx->tristrip_indices, sizeof (unsigned short));
-
-    /* PBO for any sort of texture upload */
-    dispatch->GenBuffers (1, &ctx->texture_load_pbo);
-
-    ctx->max_framebuffer_size = 0;
-    glGetIntegerv (GL_MAX_RENDERBUFFER_SIZE, &ctx->max_framebuffer_size);
-    ctx->max_texture_size = 0;
-    glGetIntegerv (GL_MAX_TEXTURE_SIZE, &ctx->max_texture_size);
-    ctx->max_textures = 0;
-    glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &ctx->max_textures);
-
-    for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++)
-	_cairo_gl_glyph_cache_init (&ctx->glyph_cache[n]);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-void
-_cairo_gl_context_activate (cairo_gl_context_t *ctx,
-			    cairo_gl_tex_t      tex_unit)
-{
-    if (ctx->max_textures <= (GLint) tex_unit) {
-	if (tex_unit < 2) {
-	    _cairo_gl_composite_flush (ctx);
-	    _cairo_gl_context_destroy_operand (ctx, ctx->max_textures - 1);
-	}
-	glActiveTexture (ctx->max_textures - 1);
-    } else {
-	glActiveTexture (GL_TEXTURE0 + tex_unit);
-    }
-}
-
-static GLenum
-_get_depth_stencil_format (cairo_gl_context_t *ctx)
-{
-    /* This is necessary to properly handle the situation where both
-       OpenGL and OpenGLES are active and returning a sane default. */
-#if CAIRO_HAS_GL_SURFACE
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
-	return GL_DEPTH_STENCIL;
-#endif
-
-#if CAIRO_HAS_GLESV2_SURFACE && !CAIRO_HAS_GLESV3_SURFACE
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
-	return GL_DEPTH24_STENCIL8_OES;
-#endif
-
-#if CAIRO_HAS_GL_SURFACE
-    return GL_DEPTH_STENCIL;
-#elif CAIRO_HAS_GLESV3_SURFACE
-    return GL_DEPTH24_STENCIL8;
-#elif CAIRO_HAS_GLESV2_SURFACE
-    return GL_DEPTH24_STENCIL8_OES;
-#endif
-}
-
-#if CAIRO_HAS_GLESV2_SURFACE
-static void
-_cairo_gl_ensure_msaa_gles_framebuffer (cairo_gl_context_t *ctx,
-					cairo_gl_surface_t *surface)
-{
-    if (surface->msaa_active)
-	return;
-
-    ctx->dispatch.FramebufferTexture2DMultisample(GL_FRAMEBUFFER,
-						  GL_COLOR_ATTACHMENT0,
-						  ctx->tex_target,
-						  surface->tex,
-						  0,
-						  ctx->num_samples);
-
-    /* From now on MSAA will always be active on this surface. */
-    surface->msaa_active = TRUE;
-}
-#endif
-
-void
-_cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
-			      cairo_gl_surface_t *surface)
-{
-    GLenum status;
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-
-    if (likely (surface->fb))
-	return;
-
-    /* Create a framebuffer object wrapping the texture so that we can render
-     * to it.
-     */
-    dispatch->GenFramebuffers (1, &surface->fb);
-    dispatch->BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
-
-    /* Unlike for desktop GL we only maintain one multisampling framebuffer
-       for OpenGLES since the EXT_multisampled_render_to_texture extension
-       does not require an explicit multisample resolution. */
-#if CAIRO_HAS_GLESV2_SURFACE
-    if (surface->supports_msaa && _cairo_gl_msaa_compositor_enabled () &&
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
-	_cairo_gl_ensure_msaa_gles_framebuffer (ctx, surface);
-    } else
-#endif
-	dispatch->FramebufferTexture2D (GL_FRAMEBUFFER,
-					GL_COLOR_ATTACHMENT0,
-					ctx->tex_target,
-					surface->tex,
-					0);
-
-#if CAIRO_HAS_GL_SURFACE
-    glDrawBuffer (GL_COLOR_ATTACHMENT0);
-    glReadBuffer (GL_COLOR_ATTACHMENT0);
-#endif
-
-    status = dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER);
-    if (status != GL_FRAMEBUFFER_COMPLETE) {
-	const char *str;
-	switch (status) {
-	//case GL_FRAMEBUFFER_UNDEFINED: str= "undefined"; break;
-	case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: str= "incomplete attachment"; break;
-	case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: str= "incomplete/missing attachment"; break;
-	case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: str= "incomplete draw buffer"; break;
-	case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: str= "incomplete read buffer"; break;
-	case GL_FRAMEBUFFER_UNSUPPORTED: str= "unsupported"; break;
-	case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: str= "incomplete multiple"; break;
-	default: str = "unknown error"; break;
-	}
-
-	fprintf (stderr,
-		 "destination is framebuffer incomplete: %s [%#x]\n",
-		 str, status);
-    }
-}
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-static void
-_cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx,
-				cairo_gl_surface_t *surface)
-{
-    assert (surface->supports_msaa);
-    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3);
-
-    if (surface->msaa_fb)
-	return;
-
-    /* We maintain a separate framebuffer for multisampling operations.
-       This allows us to do a fast paint to the non-multisampling framebuffer
-       when mulitsampling is disabled. */
-    ctx->dispatch.GenFramebuffers (1, &surface->msaa_fb);
-    ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb);
-    ctx->dispatch.GenRenderbuffers (1, &surface->msaa_rb);
-    ctx->dispatch.BindRenderbuffer (GL_RENDERBUFFER, surface->msaa_rb);
-
-    /* FIXME: For now we assume that textures passed from the outside have GL_RGBA
-       format, but eventually we need to expose a way for the API consumer to pass
-       this information. */
-    ctx->dispatch.RenderbufferStorageMultisample (GL_RENDERBUFFER,
-						  ctx->num_samples,
-#if CAIRO_HAS_GLESV3_SURFACE
-						  GL_RGBA8,
-#else
-						  GL_RGBA,
-#endif
-						  surface->width,
-						  surface->height);
-    ctx->dispatch.FramebufferRenderbuffer (GL_FRAMEBUFFER,
-					   GL_COLOR_ATTACHMENT0,
-					   GL_RENDERBUFFER,
-					   surface->msaa_rb);
-
-    /* Cairo surfaces start out initialized to transparent (black) */
-    glDisable (GL_SCISSOR_TEST);
-    glClearColor (0, 0, 0, 0);
-    glClear (GL_COLOR_BUFFER_BIT);
-
-    /* for glesv3 with multisample renderbuffer, we always render to
-       this renderbuffer */
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	surface->msaa_active = TRUE;
-}
-#endif
-
-static cairo_bool_t
-_cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx,
-					    cairo_gl_surface_t *surface)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    if (surface->msaa_depth_stencil)
-	return TRUE;
-
-    _cairo_gl_ensure_framebuffer (ctx, surface);
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	_cairo_gl_ensure_multisampling (ctx, surface);
-#endif
-
-    dispatch->GenRenderbuffers (1, &surface->msaa_depth_stencil);
-    dispatch->BindRenderbuffer (GL_RENDERBUFFER,
-				surface->msaa_depth_stencil);
-
-    dispatch->RenderbufferStorageMultisample (GL_RENDERBUFFER,
-					      ctx->num_samples,
-					      _get_depth_stencil_format (ctx),
-					      surface->width,
-					      surface->height);
-
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) {
-	dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER,
-					   GL_DEPTH_STENCIL_ATTACHMENT,
-					   GL_RENDERBUFFER,
-					   surface->msaa_depth_stencil);
-    }
-#endif
-
-#if CAIRO_HAS_GLESV2_SURFACE
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
-	dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER,
-					   GL_DEPTH_ATTACHMENT,
-					   GL_RENDERBUFFER,
-					   surface->msaa_depth_stencil);
-	dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER,
-					   GL_STENCIL_ATTACHMENT,
-					   GL_RENDERBUFFER,
-					   surface->msaa_depth_stencil);
-    }
-#endif
-
-    if (dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-	dispatch->DeleteRenderbuffers (1, &surface->msaa_depth_stencil);
-	surface->msaa_depth_stencil = 0;
-	return FALSE;
-    }
-
-    return TRUE;
-}
-
-static cairo_bool_t
-_cairo_gl_ensure_depth_stencil_buffer (cairo_gl_context_t *ctx,
-				       cairo_gl_surface_t *surface)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-
-    if (surface->depth_stencil)
-	return TRUE;
-
-    _cairo_gl_ensure_framebuffer (ctx, surface);
-
-    dispatch->GenRenderbuffers (1, &surface->depth_stencil);
-    dispatch->BindRenderbuffer (GL_RENDERBUFFER, surface->depth_stencil);
-    dispatch->RenderbufferStorage (GL_RENDERBUFFER,
-				   _get_depth_stencil_format (ctx),
-				   surface->width, surface->height);
-
-    dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-				       GL_RENDERBUFFER, surface->depth_stencil);
-    dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-				       GL_RENDERBUFFER, surface->depth_stencil);
-    if (dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-	dispatch->DeleteRenderbuffers (1, &surface->depth_stencil);
-	surface->depth_stencil = 0;
-	return FALSE;
-    }
-
-    return TRUE;
-}
-
-cairo_bool_t
-_cairo_gl_ensure_stencil (cairo_gl_context_t *ctx,
-			  cairo_gl_surface_t *surface)
-{
-    if (! _cairo_gl_surface_is_texture (surface))
-	return TRUE; /* best guess for now, will check later */
-    if (! ctx->has_packed_depth_stencil)
-	return FALSE;
-
-    if (surface->msaa_active)
-	return _cairo_gl_ensure_msaa_depth_stencil_buffer (ctx, surface);
-    else
-	return _cairo_gl_ensure_depth_stencil_buffer (ctx, surface);
-}
-
-/*
- * Stores a parallel projection transformation in matrix 'm',
- * using column-major order.
- *
- * This is equivalent to:
- *
- * glLoadIdentity()
- * gluOrtho2D()
- *
- * The calculation for the ortho transformation was taken from the
- * mesa source code.
- */
-static void
-_gl_identity_ortho (GLfloat *m,
-		    GLfloat left, GLfloat right,
-		    GLfloat bottom, GLfloat top)
-{
-#define M(row,col)  m[col*4+row]
-    M(0,0) = 2.f / (right - left);
-    M(0,1) = 0.f;
-    M(0,2) = 0.f;
-    M(0,3) = -(right + left) / (right - left);
-
-    M(1,0) = 0.f;
-    M(1,1) = 2.f / (top - bottom);
-    M(1,2) = 0.f;
-    M(1,3) = -(top + bottom) / (top - bottom);
-
-    M(2,0) = 0.f;
-    M(2,1) = 0.f;
-    M(2,2) = -1.f;
-    M(2,3) = 0.f;
-
-    M(3,0) = 0.f;
-    M(3,1) = 0.f;
-    M(3,2) = 0.f;
-    M(3,3) = 1.f;
-#undef M
-}
-
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-static void
-bind_multisample_framebuffer (cairo_gl_context_t *ctx,
-			       cairo_gl_surface_t *surface)
-{
-    cairo_bool_t stencil_test_enabled;
-    cairo_bool_t scissor_test_enabled;
-
-    assert (surface->supports_msaa);
-    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3);
-
-    _cairo_gl_ensure_framebuffer (ctx, surface);
-    _cairo_gl_ensure_multisampling (ctx, surface);
-
-    if (surface->msaa_active) {
-#if CAIRO_HAS_GL_SURFACE
-	glEnable (GL_MULTISAMPLE);
-#endif
-	ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb);
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	    surface->content_in_texture = FALSE;
-	return;
-    }
-
-    _cairo_gl_composite_flush (ctx);
-
-    stencil_test_enabled = glIsEnabled (GL_STENCIL_TEST);
-    scissor_test_enabled = glIsEnabled (GL_SCISSOR_TEST);
-    glDisable (GL_STENCIL_TEST);
-    glDisable (GL_SCISSOR_TEST);
-
-#if CAIRO_HAS_GL_SURFACE
-    glEnable (GL_MULTISAMPLE);
-#endif
-
-    /* The last time we drew to the surface, we were not using multisampling,
-       so we need to blit from the non-multisampling framebuffer into the
-       multisampling framebuffer. */
-    ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->msaa_fb);
-    ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->fb);
-    ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height,
-				   0, 0, surface->width, surface->height,
-				   GL_COLOR_BUFFER_BIT
-#if CAIRO_HAS_GL_SURFACE
-				   | GL_STENCIL_BUFFER_BIT
-#endif
-				   ,
-				   GL_NEAREST);
-    ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb);
-
-    if (stencil_test_enabled)
-	glEnable (GL_STENCIL_TEST);
-    if (scissor_test_enabled)
-	glEnable (GL_SCISSOR_TEST);
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	surface->content_in_texture = FALSE;
-}
-#endif
-
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-static void
-bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
-			       cairo_gl_surface_t *surface)
-{
-    cairo_bool_t stencil_test_enabled;
-    cairo_bool_t scissor_test_enabled;
-
-    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3);
-    _cairo_gl_ensure_framebuffer (ctx, surface);
-
-    if (! surface->msaa_active) {
-#if CAIRO_HAS_GL_SURFACE
-	glDisable (GL_MULTISAMPLE);
-#endif
-
-	ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
-	return;
-    }
-
-    _cairo_gl_composite_flush (ctx);
-
-    stencil_test_enabled = glIsEnabled (GL_STENCIL_TEST);
-    scissor_test_enabled = glIsEnabled (GL_SCISSOR_TEST);
-    glDisable (GL_STENCIL_TEST);
-    glDisable (GL_SCISSOR_TEST);
-
-#if CAIRO_HAS_GL_SURFACE
-    glDisable (GL_MULTISAMPLE);
-#endif
-
-    /* The last time we drew to the surface, we were using multisampling,
-       so we need to blit from the multisampling framebuffer into the
-       non-multisampling framebuffer. */
-    ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->fb);
-    ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->msaa_fb);
-    ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height,
-				   0, 0, surface->width, surface->height,
-				   GL_COLOR_BUFFER_BIT, GL_NEAREST);
-    ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
-
-    if (stencil_test_enabled)
-	glEnable (GL_STENCIL_TEST);
-    if (scissor_test_enabled)
-	glEnable (GL_SCISSOR_TEST);
-}
-#endif
-
-void
-_cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx,
-				    cairo_gl_surface_t *surface,
-				    cairo_bool_t multisampling)
-{
-    if (_cairo_gl_surface_is_texture (surface)) {
-	/* OpenGL ES surfaces only have either a multisample framebuffer or a
-	 * singlesample framebuffer, so we cannot switch back and forth. */
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
-	    _cairo_gl_ensure_framebuffer (ctx, surface);
-	    ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
-	    return;
-	}
-
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-	if (multisampling)
-	    bind_multisample_framebuffer (ctx, surface);
-	else
-	    bind_singlesample_framebuffer (ctx, surface);
-#endif
-    } else {
-	ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, 0);
-
-#if CAIRO_HAS_GL_SURFACE
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) {
-	    if (multisampling)
-		glEnable (GL_MULTISAMPLE);
-	    else
-		glDisable (GL_MULTISAMPLE);
-	}
-#endif
-    }
-
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
-	surface->msaa_active = multisampling;
-}
-
-void
-_cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
-				   cairo_gl_surface_t *surface,
-				   cairo_bool_t multisampling)
-{
-    cairo_bool_t changing_surface, changing_sampling;
-
-    /* The decision whether or not to use multisampling happens when
-     * we create an OpenGL ES surface, so we can never switch modes. */
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2)
-	multisampling = surface->msaa_active;
-    /* For GLESV3, we always use renderbuffer for drawing */
-    else if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	multisampling = TRUE;
-
-    changing_surface = ctx->current_target != surface || surface->needs_update;
-    changing_sampling = (surface->msaa_active != multisampling ||
-			 surface->content_in_texture);
-    if (! changing_surface && ! changing_sampling)
-	return;
-
-    if (! changing_surface) {
-	_cairo_gl_composite_flush (ctx);
-	_cairo_gl_context_bind_framebuffer (ctx, surface, multisampling);
-	return;
-    }
-
-    _cairo_gl_composite_flush (ctx);
-
-    ctx->current_target = surface;
-    surface->needs_update = FALSE;
-
-    if (! _cairo_gl_surface_is_texture (surface)) {
-	ctx->make_current (ctx, surface);
-    }
-
-    _cairo_gl_context_bind_framebuffer (ctx, surface, multisampling);
-
-    if (! _cairo_gl_surface_is_texture (surface)) {
-#if CAIRO_HAS_GL_SURFACE
-	glDrawBuffer (GL_BACK_LEFT);
-	glReadBuffer (GL_BACK_LEFT);
-#endif
-    }
-
-    glDisable (GL_DITHER);
-    glViewport (0, 0, surface->width, surface->height);
-
-    if (_cairo_gl_surface_is_texture (surface))
-	_gl_identity_ortho (ctx->modelviewprojection_matrix,
-			    0, surface->width, 0, surface->height);
-    else
-	_gl_identity_ortho (ctx->modelviewprojection_matrix,
-			    0, surface->width, surface->height, 0);
-}
-
-void
-cairo_gl_device_set_thread_aware (cairo_device_t	*device,
-				  cairo_bool_t		 thread_aware)
-{
-    if (device->backend->type != CAIRO_DEVICE_TYPE_GL) {
-	_cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
-	return;
-    }
-    ((cairo_gl_context_t *) device)->thread_aware = thread_aware;
-}
diff --git a/src/cairo-gl-dispatch-private.h b/src/cairo-gl-dispatch-private.h
deleted file mode 100644
index cabf76f0d..000000000
--- a/src/cairo-gl-dispatch-private.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2010 Linaro Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * Contributor(s):
- *      Alexandros Frantzis <alexandros.frantzis at linaro.org>
- */
-
-#ifndef CAIRO_GL_DISPATCH_PRIVATE_H
-#define CAIRO_GL_DISPATCH_PRIVATE_H
-
-#include "cairo-gl-private.h"
-#include <stddef.h>
-
-typedef enum _cairo_gl_dispatch_name {
-    CAIRO_GL_DISPATCH_NAME_CORE,
-    CAIRO_GL_DISPATCH_NAME_EXT,
-    CAIRO_GL_DISPATCH_NAME_ES,
-    CAIRO_GL_DISPATCH_NAME_COUNT
-} cairo_gl_dispatch_name_t;
-
-typedef struct _cairo_gl_dispatch_entry {
-    const char *name[CAIRO_GL_DISPATCH_NAME_COUNT];
-    size_t offset;
-} cairo_gl_dispatch_entry_t;
-
-#define DISPATCH_ENTRY_ARB(name) { { "gl"#name, "gl"#name"ARB", "gl"#name }, \
-				   offsetof(cairo_gl_dispatch_t, name) }
-#define DISPATCH_ENTRY_EXT(name) { { "gl"#name, "gl"#name"EXT", "gl"#name }, \
-				   offsetof(cairo_gl_dispatch_t, name) }
-#define DISPATCH_ENTRY_ARB_OES(name) { { "gl"#name, "gl"#name"ARB", "gl"#name"OES" }, \
-				       offsetof(cairo_gl_dispatch_t, name) }
-#define DISPATCH_ENTRY_EXT_IMG(name) { { "gl"#name, "gl"#name"EXT", "gl"#name"IMG" }, \
-				       offsetof(cairo_gl_dispatch_t, name) }
-#define DISPATCH_ENTRY_CUSTOM(name, name2) { { "gl"#name, "gl"#name2, "gl"#name }, \
-			                     offsetof(cairo_gl_dispatch_t, name)}
-#define DISPATCH_ENTRY_LAST { { NULL, NULL, NULL }, 0 }
-
-cairo_private cairo_gl_dispatch_entry_t dispatch_buffers_entries[] = {
-    DISPATCH_ENTRY_ARB     (GenBuffers),
-    DISPATCH_ENTRY_ARB     (BindBuffer),
-    DISPATCH_ENTRY_ARB     (BufferData),
-    DISPATCH_ENTRY_ARB_OES (MapBuffer),
-    DISPATCH_ENTRY_ARB_OES (UnmapBuffer),
-    DISPATCH_ENTRY_LAST
-};
-
-cairo_private cairo_gl_dispatch_entry_t dispatch_shaders_entries[] = {
-    /* Shaders */
-    DISPATCH_ENTRY_CUSTOM (CreateShader, CreateShaderObjectARB),
-    DISPATCH_ENTRY_ARB    (ShaderSource),
-    DISPATCH_ENTRY_ARB    (CompileShader),
-    DISPATCH_ENTRY_CUSTOM (GetShaderiv, GetObjectParameterivARB),
-    DISPATCH_ENTRY_CUSTOM (GetShaderInfoLog, GetInfoLogARB),
-    DISPATCH_ENTRY_CUSTOM (DeleteShader, DeleteObjectARB),
-
-    /* Programs */
-    DISPATCH_ENTRY_CUSTOM (CreateProgram, CreateProgramObjectARB),
-    DISPATCH_ENTRY_CUSTOM (AttachShader, AttachObjectARB),
-    DISPATCH_ENTRY_CUSTOM (DeleteProgram, DeleteObjectARB),
-    DISPATCH_ENTRY_ARB    (LinkProgram),
-    DISPATCH_ENTRY_CUSTOM (UseProgram, UseProgramObjectARB),
-    DISPATCH_ENTRY_CUSTOM (GetProgramiv, GetObjectParameterivARB),
-    DISPATCH_ENTRY_CUSTOM (GetProgramInfoLog, GetInfoLogARB),
-
-    /* Uniforms */
-    DISPATCH_ENTRY_ARB (GetUniformLocation),
-    DISPATCH_ENTRY_ARB (Uniform1f),
-    DISPATCH_ENTRY_ARB (Uniform2f),
-    DISPATCH_ENTRY_ARB (Uniform3f),
-    DISPATCH_ENTRY_ARB (Uniform4f),
-    DISPATCH_ENTRY_ARB (UniformMatrix3fv),
-    DISPATCH_ENTRY_ARB (UniformMatrix4fv),
-    DISPATCH_ENTRY_ARB (Uniform1i),
-
-    /* Attributes */
-    DISPATCH_ENTRY_ARB (BindAttribLocation),
-    DISPATCH_ENTRY_ARB (VertexAttribPointer),
-    DISPATCH_ENTRY_ARB (EnableVertexAttribArray),
-    DISPATCH_ENTRY_ARB (DisableVertexAttribArray),
-
-    DISPATCH_ENTRY_LAST
-};
-
-cairo_private cairo_gl_dispatch_entry_t dispatch_fbo_entries[] = {
-    DISPATCH_ENTRY_EXT (GenFramebuffers),
-    DISPATCH_ENTRY_EXT (BindFramebuffer),
-    DISPATCH_ENTRY_EXT (FramebufferTexture2D),
-    DISPATCH_ENTRY_EXT (CheckFramebufferStatus),
-    DISPATCH_ENTRY_EXT (DeleteFramebuffers),
-    DISPATCH_ENTRY_EXT (GenRenderbuffers),
-    DISPATCH_ENTRY_EXT (BindRenderbuffer),
-    DISPATCH_ENTRY_EXT (RenderbufferStorage),
-    DISPATCH_ENTRY_EXT (FramebufferRenderbuffer),
-    DISPATCH_ENTRY_EXT (DeleteRenderbuffers),
-    DISPATCH_ENTRY_EXT (BlitFramebuffer),
-    DISPATCH_ENTRY_LAST
-};
-
-cairo_private cairo_gl_dispatch_entry_t dispatch_multisampling_entries[] = {
-    DISPATCH_ENTRY_EXT_IMG (RenderbufferStorageMultisample),
-    DISPATCH_ENTRY_EXT_IMG (FramebufferTexture2DMultisample),
-    DISPATCH_ENTRY_LAST
-};
-
-#endif /* CAIRO_GL_DISPATCH_PRIVATE_H */
diff --git a/src/cairo-gl-dispatch.c b/src/cairo-gl-dispatch.c
deleted file mode 100644
index a49199dbb..000000000
--- a/src/cairo-gl-dispatch.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2010 Linaro Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * Contributor(s):
- *      Alexandros Frantzis <alexandros.frantzis at linaro.org>
- */
-
-#include "cairoint.h"
-#include "cairo-gl-private.h"
-#include "cairo-gl-dispatch-private.h"
-#if CAIRO_HAS_DLSYM
-#include <dlfcn.h>
-#endif
-
-#if CAIRO_HAS_DLSYM
-static void *
-_cairo_gl_dispatch_open_lib (void)
-{
-    return dlopen (NULL, RTLD_LAZY);
-}
-
-static void
-_cairo_gl_dispatch_close_lib (void *handle)
-{
-    dlclose (handle);
-}
-
-static cairo_gl_generic_func_t
-_cairo_gl_dispatch_get_proc_addr (void *handle, const char *name)
-{
-    return (cairo_gl_generic_func_t) dlsym (handle, name);
-}
-#else
-static void *
-_cairo_gl_dispatch_open_lib (void)
-{
-    return NULL;
-}
-
-static void
-_cairo_gl_dispatch_close_lib (void *handle)
-{
-    return;
-}
-
-static cairo_gl_generic_func_t
-_cairo_gl_dispatch_get_proc_addr (void *handle, const char *name)
-{
-    return NULL;
-}
-#endif /* CAIRO_HAS_DLSYM */
-
-
-static void
-_cairo_gl_dispatch_init_entries (cairo_gl_dispatch_t *dispatch,
-				 cairo_gl_get_proc_addr_func_t get_proc_addr,
-				 cairo_gl_dispatch_entry_t *entries,
-				 cairo_gl_dispatch_name_t dispatch_name)
-{
-    cairo_gl_dispatch_entry_t *entry = entries;
-    void *handle = _cairo_gl_dispatch_open_lib ();
-
-    while (entry->name[CAIRO_GL_DISPATCH_NAME_CORE] != NULL) {
-	void *dispatch_ptr = &((char *) dispatch)[entry->offset];
-	const char *name = entry->name[dispatch_name];
-
-	/*
-	 * In strictly conforming EGL implementations, eglGetProcAddress() can
-	 * be used only to get extension functions, but some of the functions
-	 * we want belong to core GL(ES). If the *GetProcAddress function
-	 * provided by the context fails, try to get the address of the wanted
-	 * GL function using standard system facilities (eg dlsym() in *nix
-	 * systems).
-	 */
-	cairo_gl_generic_func_t func = get_proc_addr (name);
-	if (func == NULL)
-	    func = _cairo_gl_dispatch_get_proc_addr (handle, name);
-
-	*((cairo_gl_generic_func_t *) dispatch_ptr) = func;
-
-	++entry;
-    }
-
-    _cairo_gl_dispatch_close_lib (handle);
-}
-
-static cairo_status_t
-_cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch,
-				 cairo_gl_get_proc_addr_func_t get_proc_addr,
-				 int gl_version, cairo_gl_flavor_t gl_flavor)
-{
-    cairo_gl_dispatch_name_t dispatch_name;
-
-    if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
-    {
-	if (gl_version >= CAIRO_GL_VERSION_ENCODE (1, 5))
-	    dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
-	else if (_cairo_gl_has_extension ("GL_ARB_vertex_buffer_object"))
-	    dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT;
-	else
-	    return CAIRO_STATUS_DEVICE_ERROR;
-    }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES3)
-    {
-	dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
-    }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
-	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
-    {
-	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
-    }
-    else
-    {
-	return CAIRO_STATUS_DEVICE_ERROR;
-    }
-
-    _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr,
-				     dispatch_buffers_entries, dispatch_name);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_dispatch_init_shaders (cairo_gl_dispatch_t *dispatch,
-				 cairo_gl_get_proc_addr_func_t get_proc_addr,
-				 int gl_version, cairo_gl_flavor_t gl_flavor)
-{
-    cairo_gl_dispatch_name_t dispatch_name;
-
-    if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
-    {
-	if (gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
-	    dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
-	else if (_cairo_gl_has_extension ("GL_ARB_shader_objects"))
-	    dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT;
-	else
-	    return CAIRO_STATUS_DEVICE_ERROR;
-    }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES3)
-    {
-	dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
-    }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
-	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
-    {
-	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
-    }
-    else
-    {
-	return CAIRO_STATUS_DEVICE_ERROR;
-    }
-
-    _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr,
-				     dispatch_shaders_entries, dispatch_name);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_dispatch_init_fbo (cairo_gl_dispatch_t *dispatch,
-			     cairo_gl_get_proc_addr_func_t get_proc_addr,
-			     int gl_version, cairo_gl_flavor_t gl_flavor)
-{
-    cairo_gl_dispatch_name_t dispatch_name;
-
-    if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
-    {
-	if (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) ||
-	    _cairo_gl_has_extension ("GL_ARB_framebuffer_object"))
-	    dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
-	else if (_cairo_gl_has_extension ("GL_EXT_framebuffer_object"))
-	    dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT;
-	else
-	    return CAIRO_STATUS_DEVICE_ERROR;
-    }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES3)
-    {
-	dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
-    }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
-	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
-    {
-	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
-    }
-    else
-    {
-	return CAIRO_STATUS_DEVICE_ERROR;
-    }
-
-    _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr,
-				     dispatch_fbo_entries, dispatch_name);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_dispatch_init_multisampling (cairo_gl_dispatch_t *dispatch,
-				       cairo_gl_get_proc_addr_func_t get_proc_addr,
-				       int gl_version,
-				       cairo_gl_flavor_t gl_flavor)
-{
-    /* For the multisampling table, there are two GLES versions of the
-     * extension, so we put one in the EXT slot and one in the real ES slot.*/
-    cairo_gl_dispatch_name_t dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
-    if (gl_flavor == CAIRO_GL_FLAVOR_ES2) {
-	if (_cairo_gl_has_extension ("GL_EXT_multisampled_render_to_texture"))
-	    dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT;
-	else if (_cairo_gl_has_extension ("GL_IMG_multisampled_render_to_texture"))
-	    dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
-    }
-    _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr,
-				     dispatch_multisampling_entries,
-				     dispatch_name);
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_status_t
-_cairo_gl_dispatch_init (cairo_gl_dispatch_t *dispatch,
-			 cairo_gl_get_proc_addr_func_t get_proc_addr)
-{
-    cairo_status_t status;
-    int gl_version;
-    cairo_gl_flavor_t gl_flavor;
-
-    gl_version = _cairo_gl_get_version ();
-    gl_flavor = _cairo_gl_get_flavor ();
-
-    status = _cairo_gl_dispatch_init_buffers (dispatch, get_proc_addr,
-					      gl_version, gl_flavor);
-    if (status != CAIRO_STATUS_SUCCESS)
-	return status;
-
-    status = _cairo_gl_dispatch_init_shaders (dispatch, get_proc_addr,
-					      gl_version, gl_flavor);
-    if (status != CAIRO_STATUS_SUCCESS)
-	return status;
-
-    status = _cairo_gl_dispatch_init_fbo (dispatch, get_proc_addr,
-					  gl_version, gl_flavor);
-    if (status != CAIRO_STATUS_SUCCESS)
-	return status;
-
-    status = _cairo_gl_dispatch_init_multisampling (dispatch, get_proc_addr,
-						    gl_version, gl_flavor);
-    if (status != CAIRO_STATUS_SUCCESS)
-	return status;
-
-    return CAIRO_STATUS_SUCCESS;
-}
diff --git a/src/cairo-gl-ext-def-private.h b/src/cairo-gl-ext-def-private.h
deleted file mode 100644
index a261947be..000000000
--- a/src/cairo-gl-ext-def-private.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2010 Linaro Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * Contributor(s):
- *      Alexandros Frantzis <alexandros.frantzis at linaro.org>
- */
-
-#ifndef CAIRO_GL_EXT_DEF_PRIVATE_H
-#define CAIRO_GL_EXT_DEF_PRIVATE_H
-
-#ifndef GL_TEXTURE_RECTANGLE
-#define GL_TEXTURE_RECTANGLE 0x84F5
-#endif
-
-#ifndef GL_ARRAY_BUFFER
-#define GL_ARRAY_BUFFER 0x8892
-#endif
-
-#ifndef GL_STREAM_DRAW
-#define GL_STREAM_DRAW 0x88E0
-#endif
-
-#ifndef GL_WRITE_ONLY
-#define GL_WRITE_ONLY 0x88B9
-#endif
-
-#ifndef GL_PIXEL_UNPACK_BUFFER
-#define GL_PIXEL_UNPACK_BUFFER 0x88EC
-#endif
-
-#ifndef GL_FRAMEBUFFER
-#define GL_FRAMEBUFFER 0x8D40
-#endif
-
-#ifndef GL_COLOR_ATTACHMENT0
-#define GL_COLOR_ATTACHMENT0 0x8CE0
-#endif
-
-#ifndef GL_FRAMEBUFFER_COMPLETE
-#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
-#endif
-
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
-#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
-#endif
-
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
-#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
-#endif
-
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
-#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
-#endif
-
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
-#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS 0x8CDA
-#endif
-
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
-#endif
-
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
-#endif
-
-#ifndef GL_FRAMEBUFFER_UNSUPPORTED
-#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
-#endif
-
-#ifndef GL_PACK_INVERT_MESA
-#define GL_PACK_INVERT_MESA 0x8758
-#endif
-
-#ifndef GL_CLAMP_TO_BORDER
-#define GL_CLAMP_TO_BORDER 0x812D
-#endif
-
-#ifndef GL_BGR
-#define GL_BGR 0x80E0
-#endif
-
-#ifndef GL_BGRA
-#define GL_BGRA 0x80E1
-#endif
-
-#ifndef GL_RGBA8
-#define GL_RGBA8 0x8058
-#endif
-
-#ifndef GL_UNSIGNED_INT_8_8_8_8
-#define GL_UNSIGNED_INT_8_8_8_8 0x8035
-#endif
-
-#ifndef GL_UNSIGNED_SHORT_5_6_5_REV
-#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
-#endif
-
-#ifndef GL_UNSIGNED_SHORT_1_5_5_5_REV
-#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
-#endif
-
-#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
-#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
-#endif
-
-#ifndef GL_PACK_ROW_LENGTH
-#define GL_PACK_ROW_LENGTH 0x0D02
-#endif
-
-#ifndef GL_UNPACK_ROW_LENGTH
-#define GL_UNPACK_ROW_LENGTH 0x0CF2
-#endif
-
-#ifndef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
-#endif
-
-#endif /* CAIRO_GL_EXT_DEF_PRIVATE_H */
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
deleted file mode 100644
index f6f5ec096..000000000
--- a/src/cairo-gl-glyphs.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
-/* Cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Chris Wilson
- * Copyright © 2010 Intel Corporation
- * Copyright © 2010 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Chris Wilson.
- *
- * Contributors:
- *      Benjamin Otte <otte at gnome.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-compositor-private.h"
-#include "cairo-composite-rectangles-private.h"
-#include "cairo-error-private.h"
-#include "cairo-image-surface-private.h"
-#include "cairo-rtree-private.h"
-
-#define GLYPH_CACHE_WIDTH 1024
-#define GLYPH_CACHE_HEIGHT 1024
-#define GLYPH_CACHE_MIN_SIZE 4
-#define GLYPH_CACHE_MAX_SIZE 128
-
-typedef struct _cairo_gl_glyph {
-    cairo_rtree_node_t node;
-    cairo_scaled_glyph_private_t base;
-    cairo_scaled_glyph_t *glyph;
-    cairo_gl_glyph_cache_t *cache;
-    struct { float x, y; } p1, p2;
-} cairo_gl_glyph_t;
-
-static void
-_cairo_gl_node_destroy (cairo_rtree_node_t *node)
-{
-    cairo_gl_glyph_t *priv = cairo_container_of (node, cairo_gl_glyph_t, node);
-    cairo_scaled_glyph_t *glyph;
-
-    glyph = priv->glyph;
-    if (glyph == NULL)
-	    return;
-
-    if (glyph->dev_private_key == priv->cache) {
-	    glyph->dev_private = NULL;
-	    glyph->dev_private_key = NULL;
-    }
-    cairo_list_del (&priv->base.link);
-    priv->glyph = NULL;
-}
-
-static void
-_cairo_gl_glyph_fini (cairo_scaled_glyph_private_t *glyph_private,
-		      cairo_scaled_glyph_t *scaled_glyph,
-		      cairo_scaled_font_t  *scaled_font)
-{
-    cairo_gl_glyph_t *priv = cairo_container_of (glyph_private,
-						 cairo_gl_glyph_t,
-						 base);
-
-    assert (priv->glyph);
-
-    _cairo_gl_node_destroy (&priv->node);
-
-    /* XXX thread-safety? Probably ok due to the frozen scaled-font. */
-    if (! priv->node.pinned)
-	_cairo_rtree_node_remove (&priv->cache->rtree, &priv->node);
-
-    assert (priv->glyph == NULL);
-}
-
-static cairo_int_status_t
-_cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
-				 cairo_gl_glyph_cache_t *cache,
-				 cairo_scaled_glyph_t  *scaled_glyph)
-{
-    cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
-    cairo_gl_glyph_t *glyph_private;
-    cairo_rtree_node_t *node = NULL;
-    cairo_int_status_t status;
-    int width, height;
-
-    width = glyph_surface->width;
-    if (width < GLYPH_CACHE_MIN_SIZE)
-	width = GLYPH_CACHE_MIN_SIZE;
-    height = glyph_surface->height;
-    if (height < GLYPH_CACHE_MIN_SIZE)
-	height = GLYPH_CACHE_MIN_SIZE;
-
-    /* search for an available slot */
-    status = _cairo_rtree_insert (&cache->rtree, width, height, &node);
-    /* search for an unlocked slot */
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	status = _cairo_rtree_evict_random (&cache->rtree,
-					    width, height, &node);
-	if (status == CAIRO_INT_STATUS_SUCCESS) {
-	    status = _cairo_rtree_node_insert (&cache->rtree,
-					       node, width, height, &node);
-	}
-    }
-    if (status)
-	return status;
-
-    /* XXX: Make sure we use the mask texture. This should work automagically somehow */
-    glActiveTexture (GL_TEXTURE1);
-    status = _cairo_gl_surface_draw_image (cache->surface, glyph_surface,
-					   0, 0,
-					   glyph_surface->width, glyph_surface->height,
-					   node->x, node->y, FALSE);
-    if (unlikely (status))
-	return status;
-
-    glyph_private = (cairo_gl_glyph_t *) node;
-    glyph_private->cache = cache;
-    glyph_private->glyph = scaled_glyph;
-    _cairo_scaled_glyph_attach_private (scaled_glyph,
-					&glyph_private->base,
-					cache,
-					_cairo_gl_glyph_fini);
-
-    scaled_glyph->dev_private = glyph_private;
-    scaled_glyph->dev_private_key = cache;
-
-    /* compute tex coords */
-    glyph_private->p1.x = node->x;
-    glyph_private->p1.y = node->y;
-    glyph_private->p2.x = node->x + glyph_surface->width;
-    glyph_private->p2.y = node->y + glyph_surface->height;
-    if (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base)) {
-	glyph_private->p1.x /= GLYPH_CACHE_WIDTH;
-	glyph_private->p2.x /= GLYPH_CACHE_WIDTH;
-	glyph_private->p1.y /= GLYPH_CACHE_HEIGHT;
-	glyph_private->p2.y /= GLYPH_CACHE_HEIGHT;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_gl_glyph_t *
-_cairo_gl_glyph_cache_lock (cairo_gl_glyph_cache_t *cache,
-			    cairo_scaled_glyph_t *scaled_glyph)
-{
-    return _cairo_rtree_pin (&cache->rtree, scaled_glyph->dev_private);
-}
-
-static cairo_status_t
-cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
-				  cairo_format_t format,
-				  cairo_gl_glyph_cache_t **cache_out)
-{
-    cairo_gl_glyph_cache_t *cache;
-    cairo_content_t content;
-
-    switch (format) {
-    case CAIRO_FORMAT_RGBA128F:
-    case CAIRO_FORMAT_RGB96F:
-    case CAIRO_FORMAT_RGB30:
-    case CAIRO_FORMAT_RGB16_565:
-    case CAIRO_FORMAT_ARGB32:
-    case CAIRO_FORMAT_RGB24:
-	cache = &ctx->glyph_cache[0];
-	content = CAIRO_CONTENT_COLOR_ALPHA;
-	break;
-    case CAIRO_FORMAT_A8:
-    case CAIRO_FORMAT_A1:
-	cache = &ctx->glyph_cache[1];
-	content = CAIRO_CONTENT_ALPHA;
-	break;
-    default:
-    case CAIRO_FORMAT_INVALID:
-	ASSERT_NOT_REACHED;
-	return _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
-    }
-
-    if (unlikely (cache->surface == NULL)) {
-	cairo_surface_t *surface;
-
-	surface = _cairo_gl_surface_create_scratch_for_caching (ctx,
-								content,
-								GLYPH_CACHE_WIDTH,
-								GLYPH_CACHE_HEIGHT);
-	if (unlikely (surface->status))
-	    return surface->status;
-
-	_cairo_surface_release_device_reference (surface);
-
-	cache->surface = (cairo_gl_surface_t *)surface;
-	cache->surface->operand.texture.attributes.has_component_alpha =
-	    content == CAIRO_CONTENT_COLOR_ALPHA;
-    }
-
-    *cache_out = cache;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-render_glyphs (cairo_gl_surface_t *dst,
-	       int dst_x, int dst_y,
-	       cairo_operator_t op,
-	       cairo_surface_t *source,
-	       cairo_composite_glyphs_info_t *info,
-	       cairo_bool_t *has_component_alpha,
-	       cairo_clip_t *clip)
-{
-    cairo_format_t last_format = CAIRO_FORMAT_INVALID;
-    cairo_gl_glyph_cache_t *cache = NULL;
-    cairo_gl_context_t *ctx;
-    cairo_gl_emit_glyph_t emit = NULL;
-    cairo_gl_composite_t setup;
-    cairo_int_status_t status;
-    int i = 0;
-
-    TRACE ((stderr, "%s (%d, %d)x(%d, %d)\n", __FUNCTION__,
-	    info->extents.x, info->extents.y,
-	    info->extents.width, info->extents.height));
-
-    *has_component_alpha = FALSE;
-
-    status = _cairo_gl_context_acquire (dst->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    status = _cairo_gl_composite_init (&setup, op, dst, TRUE);
-    if (unlikely (status))
-	goto FINISH;
-
-    if (source == NULL) {
-	    _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_WHITE);
-    } else {
-	    _cairo_gl_composite_set_source_operand (&setup,
-						    source_to_operand (source));
-
-    }
-
-    _cairo_gl_composite_set_clip (&setup, clip);
-
-    for (i = 0; i < info->num_glyphs; i++) {
-	cairo_scaled_glyph_t *scaled_glyph;
-	cairo_gl_glyph_t *glyph;
-	double x_offset, y_offset;
-	double x1, x2, y1, y2;
-
-	status = _cairo_scaled_glyph_lookup (info->font,
-					     info->glyphs[i].index,
-					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
-					     NULL, /* foreground color */
-					     &scaled_glyph);
-	if (unlikely (status))
-	    goto FINISH;
-
-	if (scaled_glyph->surface->width  == 0 ||
-	    scaled_glyph->surface->height == 0)
-	{
-	    continue;
-	}
-	if (scaled_glyph->surface->format != last_format) {
-	    status = cairo_gl_context_get_glyph_cache (ctx,
-						       scaled_glyph->surface->format,
-						       &cache);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    last_format = scaled_glyph->surface->format;
-
-	    _cairo_gl_composite_set_mask_operand (&setup, &cache->surface->operand);
-	    *has_component_alpha |= cache->surface->operand.texture.attributes.has_component_alpha;
-
-	    /* XXX Shoot me. */
-	    status = _cairo_gl_composite_begin (&setup, &ctx);
-	    status = _cairo_gl_context_release (ctx, status);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    emit = _cairo_gl_context_choose_emit_glyph (ctx);
-	}
-
-	if (scaled_glyph->dev_private_key != cache) {
-	    cairo_scaled_glyph_private_t *priv;
-
-	    priv = _cairo_scaled_glyph_find_private (scaled_glyph, cache);
-	    if (priv) {
-		scaled_glyph->dev_private_key = cache;
-		scaled_glyph->dev_private = cairo_container_of (priv,
-								cairo_gl_glyph_t,
-								base);
-	    } else {
-		status = _cairo_gl_glyph_cache_add_glyph (ctx, cache, scaled_glyph);
-
-		if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-		    /* Cache is full, so flush existing prims and try again. */
-		    _cairo_gl_composite_flush (ctx);
-		    _cairo_gl_glyph_cache_unlock (cache);
-		    status = _cairo_gl_glyph_cache_add_glyph (ctx, cache, scaled_glyph);
-		}
-
-		if (unlikely (_cairo_int_status_is_error (status)))
-		    goto FINISH;
-	    }
-	}
-
-	x_offset = scaled_glyph->surface->base.device_transform.x0;
-	y_offset = scaled_glyph->surface->base.device_transform.y0;
-
-	x1 = _cairo_lround (info->glyphs[i].x - x_offset - dst_x);
-	y1 = _cairo_lround (info->glyphs[i].y - y_offset - dst_y);
-	x2 = x1 + scaled_glyph->surface->width;
-	y2 = y1 + scaled_glyph->surface->height;
-
-	glyph = _cairo_gl_glyph_cache_lock (cache, scaled_glyph);
-	assert (emit);
-	emit (ctx,
-	      x1, y1, x2, y2,
-	      glyph->p1.x, glyph->p1.y,
-	      glyph->p2.x, glyph->p2.y);
-    }
-
-    status = CAIRO_STATUS_SUCCESS;
-  FINISH:
-    status = _cairo_gl_context_release (ctx, status);
-
-    _cairo_gl_composite_fini (&setup);
-    return status;
-}
-
-static cairo_int_status_t
-render_glyphs_via_mask (cairo_gl_surface_t *dst,
-			int dst_x, int dst_y,
-			cairo_operator_t  op,
-			cairo_surface_t *source,
-			cairo_composite_glyphs_info_t *info,
-			cairo_clip_t *clip)
-{
-    cairo_surface_t *mask;
-    cairo_status_t status;
-    cairo_bool_t has_component_alpha;
-
-    TRACE ((stderr, "%s\n", __FUNCTION__));
-
-    /* XXX: For non-CA, this should be CAIRO_CONTENT_ALPHA to save memory */
-    mask = cairo_gl_surface_create (dst->base.device,
-				    CAIRO_CONTENT_COLOR_ALPHA,
-				    info->extents.width,
-				    info->extents.height);
-    if (unlikely (mask->status))
-	return mask->status;
-
-    status = render_glyphs ((cairo_gl_surface_t *) mask,
-			    info->extents.x, info->extents.y,
-			    CAIRO_OPERATOR_ADD, NULL,
-			    info, &has_component_alpha, NULL);
-    if (likely (status == CAIRO_STATUS_SUCCESS)) {
-	cairo_surface_pattern_t mask_pattern;
-	cairo_surface_pattern_t source_pattern;
-	cairo_rectangle_int_t clip_extents;
-
-	mask->is_clear = FALSE;
-	_cairo_pattern_init_for_surface (&mask_pattern, mask);
-	mask_pattern.base.has_component_alpha = has_component_alpha;
-	mask_pattern.base.filter = CAIRO_FILTER_NEAREST;
-	mask_pattern.base.extend = CAIRO_EXTEND_NONE;
-
-	cairo_matrix_init_translate (&mask_pattern.base.matrix,
-				     dst_x-info->extents.x, dst_y-info->extents.y);
-
-	_cairo_pattern_init_for_surface (&source_pattern, source);
-	cairo_matrix_init_translate (&source_pattern.base.matrix,
-				     dst_x-info->extents.x, dst_y-info->extents.y);
-
-	clip = _cairo_clip_copy (clip);
-	clip_extents.x = info->extents.x - dst_x;
-	clip_extents.y = info->extents.y - dst_y;
-	clip_extents.width = info->extents.width;
-	clip_extents.height = info->extents.height;
-	clip = _cairo_clip_intersect_rectangle (clip, &clip_extents);
-
-	status = _cairo_surface_mask (&dst->base, op,
-				      &source_pattern.base,
-				      &mask_pattern.base,
-				      clip);
-
-	_cairo_clip_destroy (clip);
-
-	_cairo_pattern_fini (&mask_pattern.base);
-	_cairo_pattern_fini (&source_pattern.base);
-    }
-
-    cairo_surface_destroy (mask);
-
-    return status;
-}
-
-cairo_int_status_t
-_cairo_gl_check_composite_glyphs (const cairo_composite_rectangles_t *extents,
-				  cairo_scaled_font_t *scaled_font,
-				  cairo_glyph_t *glyphs,
-				  int *num_glyphs)
-{
-    if (! _cairo_gl_operator_is_supported (extents->op))
-	return UNSUPPORTED ("unsupported operator");
-
-    /* XXX use individual masks for large glyphs? */
-    if (ceil (scaled_font->max_scale) >= GLYPH_CACHE_MAX_SIZE)
-	return UNSUPPORTED ("glyphs too large");
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_int_status_t
-_cairo_gl_composite_glyphs_with_clip (void			    *_dst,
-				      cairo_operator_t		     op,
-				      cairo_surface_t		    *_src,
-				      int			     src_x,
-				      int			     src_y,
-				      int			     dst_x,
-				      int			     dst_y,
-				      cairo_composite_glyphs_info_t *info,
-				      cairo_clip_t		    *clip)
-{
-    cairo_gl_surface_t *dst = _dst;
-    cairo_bool_t has_component_alpha;
-
-    TRACE ((stderr, "%s\n", __FUNCTION__));
-
-    /* If any of the glyphs require component alpha, we have to go through
-     * a mask, since only _cairo_gl_surface_composite() currently supports
-     * component alpha.
-     */
-    if (!dst->base.is_clear && ! info->use_mask && op != CAIRO_OPERATOR_OVER &&
-	(info->font->options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ||
-	 info->font->options.antialias == CAIRO_ANTIALIAS_BEST))
-    {
-	info->use_mask = TRUE;
-    }
-
-    if (info->use_mask) {
-	return render_glyphs_via_mask (dst, dst_x, dst_y,
-				       op, _src, info, clip);
-    } else {
-	return render_glyphs (dst, dst_x, dst_y,
-			      op, _src, info,
-			      &has_component_alpha,
-			      clip);
-    }
-
-}
-
-cairo_int_status_t
-_cairo_gl_composite_glyphs (void			*_dst,
-			    cairo_operator_t		 op,
-			    cairo_surface_t		*_src,
-			    int				 src_x,
-			    int				 src_y,
-			    int				 dst_x,
-			    int				 dst_y,
-			    cairo_composite_glyphs_info_t *info)
-{
-    return _cairo_gl_composite_glyphs_with_clip (_dst, op, _src, src_x, src_y,
-						 dst_x, dst_y, info, NULL);
-}
-
-void
-_cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache)
-{
-    _cairo_rtree_init (&cache->rtree,
-		       GLYPH_CACHE_WIDTH,
-		       GLYPH_CACHE_HEIGHT,
-		       GLYPH_CACHE_MIN_SIZE,
-		       sizeof (cairo_gl_glyph_t),
-		       _cairo_gl_node_destroy);
-}
-
-void
-_cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
-			    cairo_gl_glyph_cache_t *cache)
-{
-    _cairo_rtree_fini (&cache->rtree);
-    cairo_surface_destroy (&cache->surface->base);
-}
diff --git a/src/cairo-gl-gradient-private.h b/src/cairo-gl-gradient-private.h
deleted file mode 100644
index 0d9f41f54..000000000
--- a/src/cairo-gl-gradient-private.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- */
-
-#ifndef CAIRO_GL_GRADIENT_PRIVATE_H
-#define CAIRO_GL_GRADIENT_PRIVATE_H
-
-#define GL_GLEXT_PROTOTYPES
-
-#include "cairo-cache-private.h"
-#include "cairo-device-private.h"
-#include "cairo-reference-count-private.h"
-#include "cairo-pattern-private.h"
-#include "cairo-types-private.h"
-
-#include "cairo-gl.h"
-
-#if CAIRO_HAS_GLESV3_SURFACE
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#elif CAIRO_HAS_GLESV2_SURFACE
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#elif CAIRO_HAS_GL_SURFACE
-#include <GL/gl.h>
-#include <GL/glext.h>
-#endif
-
-#define CAIRO_GL_GRADIENT_CACHE_SIZE 4096
-
-/* XXX: Declare in a better place */
-typedef struct _cairo_gl_context cairo_gl_context_t;
-
-typedef struct _cairo_gl_gradient {
-    cairo_cache_entry_t           cache_entry;
-    cairo_reference_count_t       ref_count;
-    cairo_device_t               *device; /* NB: we don't hold a reference */
-    GLuint                        tex;
-    unsigned int	          n_stops;
-    const cairo_gradient_stop_t  *stops;
-    cairo_gradient_stop_t         stops_embedded[1];
-} cairo_gl_gradient_t;
-
-cairo_private cairo_int_status_t
-_cairo_gl_gradient_create (cairo_gl_context_t           *ctx,
-                           unsigned int                  n_stops,
-                           const cairo_gradient_stop_t  *stops,
-                           cairo_gl_gradient_t         **gradient_out);
-
-cairo_private_no_warn cairo_gl_gradient_t *
-_cairo_gl_gradient_reference (cairo_gl_gradient_t *gradient);
-
-cairo_private void
-_cairo_gl_gradient_destroy (cairo_gl_gradient_t *gradient);
-
-cairo_private cairo_bool_t
-_cairo_gl_gradient_equal (const void *key_a, const void *key_b);
-
-
-#endif /* CAIRO_GL_GRADIENT_PRIVATE_H */
diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
deleted file mode 100644
index 293d4e30e..000000000
--- a/src/cairo-gl-gradient.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- */
-
-#include "cairoint.h"
-#include <stdint.h>
-#include "cairo-error-private.h"
-#include "cairo-gl-gradient-private.h"
-#include "cairo-gl-private.h"
-
-
-static int
-_cairo_gl_gradient_sample_width (unsigned int                 n_stops,
-				 const cairo_gradient_stop_t *stops)
-{
-    unsigned int n;
-    int width;
-
-    width = 8;
-    for (n = 1; n < n_stops; n++) {
-	double dx = stops[n].offset - stops[n-1].offset;
-	double delta, max;
-	int ramp;
-
-	if (dx == 0)
-	    return 1024; /* we need to emulate an infinitely sharp step */
-
-	max = fabs (stops[n].color.red - stops[n-1].color.red);
-
-	delta = fabs (stops[n].color.green - stops[n-1].color.green);
-	if (delta > max)
-	    max = delta;
-
-	delta = fabs (stops[n].color.blue - stops[n-1].color.blue);
-	if (delta > max)
-	    max = delta;
-
-	delta = fabs (stops[n].color.alpha - stops[n-1].color.alpha);
-	if (delta > max)
-	    max = delta;
-
-	ramp = 128 * max / dx;
-	if (ramp > width)
-	    width = ramp;
-    }
-
-    return (width + 7) & -8;
-}
-
-static uint8_t premultiply(double c, double a)
-{
-    int v = c * a * 256;
-    return v - (v >> 8);
-}
-
-static uint32_t color_stop_to_pixel(const cairo_gradient_stop_t *stop)
-{
-    uint8_t a, r, g, b;
-
-    a = stop->color.alpha_short >> 8;
-    r = premultiply(stop->color.red,   stop->color.alpha);
-    g = premultiply(stop->color.green, stop->color.alpha);
-    b = premultiply(stop->color.blue,  stop->color.alpha);
-
-    if (_cairo_is_little_endian ())
-	return (uint32_t)a << 24 | r << 16 | g << 8 | b << 0;
-    else
-	return a << 0 | r << 8 | g << 16 | (uint32_t)b << 24;
-}
-
-static cairo_status_t
-_cairo_gl_gradient_render (const cairo_gl_context_t    *ctx,
-			   unsigned int                 n_stops,
-			   const cairo_gradient_stop_t *stops,
-			   void                        *bytes,
-			   int                          width)
-{
-    pixman_image_t *gradient, *image;
-    pixman_gradient_stop_t pixman_stops_stack[32];
-    pixman_gradient_stop_t *pixman_stops;
-    pixman_point_fixed_t p1, p2;
-    unsigned int i;
-    pixman_format_code_t gradient_pixman_format;
-
-    /*
-     * Ensure that the order of the gradient's components in memory is BGRA.
-     * This is done so that the gradient's pixel data is always suitable for
-     * texture upload using format=GL_BGRA and type=GL_UNSIGNED_BYTE.
-     */
-    if (_cairo_is_little_endian ())
-	gradient_pixman_format = PIXMAN_a8r8g8b8;
-    else
-	gradient_pixman_format = PIXMAN_b8g8r8a8;
-
-    pixman_stops = pixman_stops_stack;
-    if (unlikely (n_stops > ARRAY_LENGTH (pixman_stops_stack))) {
-	pixman_stops = _cairo_malloc_ab (n_stops,
-					 sizeof (pixman_gradient_stop_t));
-	if (unlikely (pixman_stops == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    for (i = 0; i < n_stops; i++) {
-	pixman_stops[i].x = _cairo_fixed_16_16_from_double (stops[i].offset);
-	pixman_stops[i].color.red   = stops[i].color.red_short;
-	pixman_stops[i].color.green = stops[i].color.green_short;
-	pixman_stops[i].color.blue  = stops[i].color.blue_short;
-	pixman_stops[i].color.alpha = stops[i].color.alpha_short;
-    }
-
-    p1.x = _cairo_fixed_16_16_from_double (0.5);
-    p1.y = 0;
-    p2.x = _cairo_fixed_16_16_from_double (width - 0.5);
-    p2.y = 0;
-
-    gradient = pixman_image_create_linear_gradient (&p1, &p2,
-						    pixman_stops,
-						    n_stops);
-    if (pixman_stops != pixman_stops_stack)
-	free (pixman_stops);
-
-    if (unlikely (gradient == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    pixman_image_set_filter (gradient, PIXMAN_FILTER_BILINEAR, NULL, 0);
-    pixman_image_set_repeat (gradient, PIXMAN_REPEAT_PAD);
-
-    image = pixman_image_create_bits (gradient_pixman_format, width, 1,
-				      bytes, sizeof(uint32_t)*width);
-    if (unlikely (image == NULL)) {
-	pixman_image_unref (gradient);
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    pixman_image_composite32 (PIXMAN_OP_SRC,
-			      gradient, NULL, image,
-			      0, 0,
-			      0, 0,
-			      0, 0,
-			      width, 1);
-
-    pixman_image_unref (gradient);
-    pixman_image_unref (image);
-
-    /* We need to fudge pixel 0 to hold the left-most color stop and not
-     * the neareset stop to the zeroth pixel centre in order to correctly
-     * populate the border color. For completeness, do both edges.
-     */
-    ((uint32_t*)bytes)[0] = color_stop_to_pixel(&stops[0]);
-    ((uint32_t*)bytes)[width-1] = color_stop_to_pixel(&stops[n_stops-1]);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static uintptr_t
-_cairo_gl_gradient_hash (unsigned int                  n_stops,
-			 const cairo_gradient_stop_t  *stops)
-{
-    return _cairo_hash_bytes (n_stops,
-			      stops,
-			      sizeof (cairo_gradient_stop_t) * n_stops);
-}
-
-static cairo_gl_gradient_t *
-_cairo_gl_gradient_lookup (cairo_gl_context_t           *ctx,
-			   uintptr_t                     hash,
-			   unsigned int                  n_stops,
-			   const cairo_gradient_stop_t  *stops)
-{
-    cairo_gl_gradient_t lookup;
-
-    lookup.cache_entry.hash = hash,
-    lookup.n_stops = n_stops;
-    lookup.stops = stops;
-
-    return _cairo_cache_lookup (&ctx->gradients, &lookup.cache_entry);
-}
-
-cairo_bool_t
-_cairo_gl_gradient_equal (const void *key_a, const void *key_b)
-{
-    const cairo_gl_gradient_t *a = key_a;
-    const cairo_gl_gradient_t *b = key_b;
-
-    if (a->n_stops != b->n_stops)
-	return FALSE;
-
-    return memcmp (a->stops, b->stops, a->n_stops * sizeof (cairo_gradient_stop_t)) == 0;
-}
-
-cairo_int_status_t
-_cairo_gl_gradient_create (cairo_gl_context_t           *ctx,
-			   unsigned int                  n_stops,
-			   const cairo_gradient_stop_t  *stops,
-			   cairo_gl_gradient_t         **gradient_out)
-{
-    uintptr_t hash;
-    cairo_gl_gradient_t *gradient;
-    cairo_status_t status;
-    int tex_width;
-    GLint internal_format;
-    void *data;
-
-    if ((unsigned int) ctx->max_texture_size / 2 <= n_stops)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    hash = _cairo_gl_gradient_hash (n_stops, stops);
-
-    gradient = _cairo_gl_gradient_lookup (ctx, hash, n_stops, stops);
-    if (gradient) {
-	*gradient_out = _cairo_gl_gradient_reference (gradient);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    gradient = _cairo_malloc (sizeof (cairo_gl_gradient_t) + sizeof (cairo_gradient_stop_t) * (n_stops - 1));
-    if (gradient == NULL)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    tex_width = _cairo_gl_gradient_sample_width (n_stops, stops);
-    if (tex_width > ctx->max_texture_size)
-	tex_width = ctx->max_texture_size;
-
-    CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 2);
-    gradient->cache_entry.hash = hash;
-    gradient->cache_entry.size = tex_width;
-    gradient->device = &ctx->base;
-    gradient->n_stops = n_stops;
-    gradient->stops = gradient->stops_embedded;
-    memcpy (gradient->stops_embedded, stops, n_stops * sizeof (cairo_gradient_stop_t));
-
-    glGenTextures (1, &gradient->tex);
-    _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
-    glBindTexture (ctx->tex_target, gradient->tex);
-
-    data = _cairo_malloc_ab (tex_width, sizeof (uint32_t));
-    if (unlikely (data == NULL)) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto cleanup_gradient;
-    }
-
-    status = _cairo_gl_gradient_render (ctx, n_stops, stops, data, tex_width);
-    if (unlikely (status))
-	goto cleanup_data;
-
-    /*
-     * In OpenGL ES 2.0 no format conversion is allowed i.e. 'internalFormat'
-     * must match 'format' in glTexImage2D.
-     */
-    if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES3 ||
-	_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2)
-	internal_format = GL_BGRA;
-    else
-	internal_format = GL_RGBA;
-
-    glTexImage2D (ctx->tex_target, 0, internal_format, tex_width, 1, 0,
-		  GL_BGRA, GL_UNSIGNED_BYTE, data);
-
-    free (data);
-
-    /* we ignore errors here and just return an uncached gradient */
-    if (unlikely (_cairo_cache_insert (&ctx->gradients, &gradient->cache_entry)))
-	CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 1);
-
-    *gradient_out = gradient;
-    return CAIRO_STATUS_SUCCESS;
-
-cleanup_data:
-    free (data);
-cleanup_gradient:
-    free (gradient);
-    return status;
-}
-
-cairo_gl_gradient_t *
-_cairo_gl_gradient_reference (cairo_gl_gradient_t *gradient)
-{
-    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count));
-
-    _cairo_reference_count_inc (&gradient->ref_count);
-
-    return gradient;
-}
-
-void
-_cairo_gl_gradient_destroy (cairo_gl_gradient_t *gradient)
-{
-    cairo_gl_context_t *ctx;
-    cairo_status_t ignore;
-
-    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count));
-
-    if (! _cairo_reference_count_dec_and_test (&gradient->ref_count))
-	return;
-
-    if (_cairo_gl_context_acquire (gradient->device, &ctx) == CAIRO_STATUS_SUCCESS) {
-	/* The gradient my still be active in the last operation, so flush */
-	_cairo_gl_composite_flush (ctx);
-	glDeleteTextures (1, &gradient->tex);
-	ignore = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-    }
-
-    free (gradient);
-}
diff --git a/src/cairo-gl-info.c b/src/cairo-gl-info.c
deleted file mode 100644
index c655b962e..000000000
--- a/src/cairo-gl-info.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2010 Linaro Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * Contributor(s):
- *      Alexandros Frantzis <alexandros.frantzis at linaro.org>
- *      Heiko Lewin <heiko.lewin at gmx.de>
- */
-
-#include "cairoint.h"
-#include "cairo-gl-private.h"
-
-#include <errno.h>
-
-int
-_cairo_gl_get_version (void)
-{
-    int major, minor;
-    const char *version = (const char *) glGetString (GL_VERSION);
-    const char *dot = version == NULL ? NULL : strchr (version, '.');
-    const char *major_start = dot;
-
-    /* Sanity check */
-    if (dot == NULL || dot == version || *(dot + 1) == '\0') {
-	major = 0;
-	minor = 0;
-    } else {
-	/* Find the start of the major version in the string */
-	while (major_start > version && *major_start != ' ')
-	    --major_start;
-	major = strtol (major_start, NULL, 10);
-	minor = strtol (dot + 1, NULL, 10);
-    }
-
-    return CAIRO_GL_VERSION_ENCODE (major, minor);
-}
-
-
-static cairo_gl_flavor_t
-_cairo_gl_degrade_flavor_by_build_features (cairo_gl_flavor_t flavor)
-{
-    switch(flavor) {
-    case CAIRO_GL_FLAVOR_DESKTOP:
-#if CAIRO_HAS_GL_SURFACE
-	return CAIRO_GL_FLAVOR_DESKTOP;
-#else
-	return CAIRO_GL_FLAVOR_NONE;
-#endif
-
-    case CAIRO_GL_FLAVOR_ES3:
-#if CAIRO_HAS_GLESV3_SURFACE
-	return CAIRO_GL_FLAVOR_ES3;
-#else
-	/* intentional fall through: degrade to GLESv2 if GLESv3-surfaces are not available */
-#endif
-
-    case CAIRO_GL_FLAVOR_ES2:
-#if CAIRO_HAS_GLESV2_SURFACE
-	return CAIRO_GL_FLAVOR_ES2;
-#else
-	/* intentional fall through: no OpenGL in first place or no surfaces for it's version */
-#endif
-
-    case CAIRO_GL_FLAVOR_NONE:
-    default:
-	return CAIRO_GL_FLAVOR_NONE;
-    }
-}
-
-cairo_gl_flavor_t
-_cairo_gl_get_flavor (void)
-{
-    const char *version = (const char *) glGetString (GL_VERSION);
-    cairo_gl_flavor_t flavor;
-
-    if (version == NULL) {
-	flavor = CAIRO_GL_FLAVOR_NONE;
-    } else if (strstr (version, "OpenGL ES 3") != NULL) {
-	flavor = CAIRO_GL_FLAVOR_ES3;
-    } else if (strstr (version, "OpenGL ES 2") != NULL) {
-	flavor = CAIRO_GL_FLAVOR_ES2;
-    } else {
-	flavor = CAIRO_GL_FLAVOR_DESKTOP;
-    }
-
-    return _cairo_gl_degrade_flavor_by_build_features(flavor);
-}
-
-unsigned long
-_cairo_gl_get_vbo_size (void)
-{
-    unsigned long vbo_size;
-
-    const char *env = getenv ("CAIRO_GL_VBO_SIZE");
-    if (env == NULL) {
-	vbo_size = CAIRO_GL_VBO_SIZE_DEFAULT;
-    } else {
-	errno = 0;
-	vbo_size = strtol (env, NULL, 10);
-	assert (errno == 0);
-	assert (vbo_size > 0);
-    }
-
-    return vbo_size;
-}
-
-cairo_bool_t
-_cairo_gl_has_extension (const char *ext)
-{
-    const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
-    size_t len = strlen (ext);
-    const char *ext_ptr = extensions;
-
-    if (unlikely (ext_ptr == NULL))
-	return 0;
-
-    while ((ext_ptr = strstr (ext_ptr, ext)) != NULL) {
-	if (ext_ptr[len] == ' ' || ext_ptr[len] == '\0')
-	    break;
-	ext_ptr += len;
-    }
-
-    return (ext_ptr != NULL);
-}
diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c
deleted file mode 100644
index 7a83dd219..000000000
--- a/src/cairo-gl-msaa-compositor.c
+++ /dev/null
@@ -1,956 +0,0 @@
-/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2002 University of Southern California
- * Copyright © 2005 Red Hat, Inc.
- * Copyright © 2011 Intel Corporation
- * Copyright © 2011 Samsung Electronics
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is University of Southern
- * California.
- *
- * Contributor(s):
- *	Henry Song <hsong at sisa.samsung.com>
- *	Martin Robinson <mrobinson at igalia.com>
- */
-
-#include "cairoint.h"
-
-#include "cairo-clip-inline.h"
-#include "cairo-composite-rectangles-private.h"
-#include "cairo-compositor-private.h"
-#include "cairo-gl-private.h"
-#include "cairo-path-private.h"
-#include "cairo-traps-private.h"
-
-static cairo_bool_t
-can_use_msaa_compositor (cairo_gl_surface_t *surface,
-			 cairo_antialias_t antialias);
-
-static void
-query_surface_capabilities (cairo_gl_surface_t *surface);
-
-struct _tristrip_composite_info {
-    cairo_gl_composite_t	setup;
-    cairo_gl_context_t		*ctx;
-};
-
-static cairo_int_status_t
-_draw_trap (cairo_gl_context_t		*ctx,
-	    cairo_gl_composite_t	*setup,
-	    cairo_trapezoid_t		*trap)
-{
-    cairo_point_t quad[4];
-
-    quad[0].x = _cairo_edge_compute_intersection_x_for_y (&trap->left.p1,
-							  &trap->left.p2,
-							  trap->top);
-    quad[0].y = trap->top;
-
-    quad[1].x = _cairo_edge_compute_intersection_x_for_y (&trap->left.p1,
-						      &trap->left.p2,
-						      trap->bottom);
-    quad[1].y = trap->bottom;
-
-    quad[2].x = _cairo_edge_compute_intersection_x_for_y (&trap->right.p1,
-						      &trap->right.p2,
-						      trap->bottom);
-    quad[2].y = trap->bottom;
-
-    quad[3].x = _cairo_edge_compute_intersection_x_for_y (&trap->right.p1,
-						      &trap->right.p2,
-						      trap->top);
-    quad[3].y = trap->top;
-    return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad);
-}
-
-static cairo_int_status_t
-_draw_traps (cairo_gl_context_t		*ctx,
-	     cairo_gl_composite_t	*setup,
-	     cairo_traps_t		*traps)
-{
-    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
-    int i;
-
-    for (i = 0; i < traps->num_traps; i++) {
-	cairo_trapezoid_t *trap = traps->traps + i;
-	if (unlikely ((status = _draw_trap (ctx, setup, trap))))
-	    return status;
-    }
-
-   return status;
-}
-
-static cairo_int_status_t
-_draw_int_rect (cairo_gl_context_t	*ctx,
-		cairo_gl_composite_t	*setup,
-		cairo_rectangle_int_t	*rect)
-{
-    cairo_box_t box;
-    cairo_point_t quad[4];
-
-    _cairo_box_from_rectangle (&box, rect);
-    quad[0].x = box.p1.x;
-    quad[0].y = box.p1.y;
-    quad[1].x = box.p1.x;
-    quad[1].y = box.p2.y;
-    quad[2].x = box.p2.x;
-    quad[2].y = box.p2.y;
-    quad[3].x = box.p2.x;
-    quad[3].y = box.p1.y;
-
-    return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad);
-}
-
-static cairo_int_status_t
-_draw_triangle_fan (cairo_gl_context_t		*ctx,
-		    cairo_gl_composite_t	*setup,
-		    const cairo_point_t		*midpt,
-		    const cairo_point_t		*points,
-		    int				 npoints)
-{
-    int i;
-
-    /* Our strategy here is to not even try to build a triangle fan, but to
-       draw each triangle as if it was an unconnected member of a triangle strip. */
-    for (i = 1; i < npoints; i++) {
-	cairo_int_status_t status;
-	cairo_point_t triangle[3];
-
-	triangle[0] = *midpt;
-	triangle[1] = points[i - 1];
-	triangle[2] = points[i];
-
-	status = _cairo_gl_composite_emit_triangle_as_tristrip (ctx, setup, triangle);
-	if (unlikely (status))
-	    return status;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-_clip_to_traps (cairo_clip_t *clip,
-		cairo_traps_t *traps)
-{
-    cairo_int_status_t status;
-    cairo_polygon_t polygon;
-    cairo_antialias_t antialias;
-    cairo_fill_rule_t fill_rule;
-
-    _cairo_traps_init (traps);
-
-    if (clip->num_boxes == 1 && clip->path == NULL) {
-	cairo_boxes_t boxes;
-	_cairo_boxes_init_for_array (&boxes, clip->boxes, clip->num_boxes);
-	return _cairo_traps_init_boxes (traps, &boxes);
-    }
-
-    status = _cairo_clip_get_polygon (clip, &polygon, &fill_rule, &antialias);
-    if (unlikely (status))
-	return status;
-
-    /* We ignore the antialias mode of the clip here, since the user requested
-     * unantialiased rendering of their path and we expect that this stencil
-     * based rendering of the clip to be a reasonable approximation to
-     * the intersection between that clip and the path.
-     *
-     * In other words, what the user expects when they try to perform
-     * a geometric intersection between an unantialiased polygon and an
-     * antialiased polygon is open to interpretation. And we choose the fast
-     * option.
-     */
-
-    _cairo_traps_init (traps);
-    status = _cairo_bentley_ottmann_tessellate_polygon (traps,
-							&polygon,
-							fill_rule);
-    _cairo_polygon_fini (&polygon);
-
-    return status;
-}
-
-cairo_int_status_t
-_cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx,
-				     cairo_gl_composite_t *setup,
-				     cairo_clip_t *clip)
-{
-    cairo_int_status_t status;
-    cairo_traps_t traps;
-
-    status = _clip_to_traps (clip, &traps);
-    if (unlikely (status))
-	return status;
-    status = _draw_traps (ctx, setup, &traps);
-
-    _cairo_traps_fini (&traps);
-    return status;
-}
-
-static cairo_bool_t
-_should_use_unbounded_surface (cairo_composite_rectangles_t *composite)
-{
-    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
-    cairo_rectangle_int_t *source = &composite->source;
-
-    if (composite->is_bounded)
-	return FALSE;
-
-    /* This isn't just an optimization. It also detects when painting is used
-       to paint back the unbounded surface, preventing infinite recursion. */
-    return ! (source->x <= 0 && source->y <= 0 &&
-	      source->height + source->y >= dst->height &&
-	      source->width + source->x >= dst->width);
-}
-
-static cairo_surface_t*
-_prepare_unbounded_surface (cairo_gl_surface_t *dst)
-{
-
-    cairo_surface_t* surface = cairo_gl_surface_create (dst->base.device,
-							dst->base.content,
-							dst->width,
-							dst->height);
-    if (surface == NULL)
-	return NULL;
-    if (unlikely (surface->status)) {
-	cairo_surface_destroy (surface);
-	return NULL;
-    }
-    return surface;
-}
-
-static cairo_int_status_t
-_paint_back_unbounded_surface (const cairo_compositor_t		*compositor,
-			       cairo_composite_rectangles_t	*composite,
-			       cairo_surface_t			*surface)
-{
-    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
-    cairo_int_status_t status;
-
-    cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
-    if (unlikely (pattern->status)) {
-	status = pattern->status;
-	goto finish;
-    }
-
-    status = _cairo_compositor_paint (compositor, &dst->base,
-				      composite->op, pattern,
-				      composite->clip);
-
-finish:
-    cairo_pattern_destroy (pattern);
-    cairo_surface_destroy (surface);
-    return status;
-}
-
-static cairo_bool_t
-can_use_msaa_compositor (cairo_gl_surface_t *surface,
-			 cairo_antialias_t antialias)
-{
-    cairo_gl_flavor_t gl_flavor = ((cairo_gl_context_t *) surface->base.device)->gl_flavor;
-
-    query_surface_capabilities (surface);
-    if (! surface->supports_stencil)
-	return FALSE;
-
-    /* Multisampling OpenGL ES surfaces only maintain one multisampling
-       framebuffer and thus must use the spans compositor to do non-antialiased
-       rendering. */
-    if ((gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	 gl_flavor == CAIRO_GL_FLAVOR_ES2)
-	 && surface->supports_msaa
-	 && surface->num_samples > 1
-	 && antialias == CAIRO_ANTIALIAS_NONE)
-	return FALSE;
-
-    /* The MSAA compositor has a single-sample mode, so we can
-       support non-antialiased rendering. */
-    if (antialias == CAIRO_ANTIALIAS_NONE)
-	return TRUE;
-
-    if (antialias == CAIRO_ANTIALIAS_FAST || antialias == CAIRO_ANTIALIAS_DEFAULT)
-	return surface->supports_msaa;
-    return FALSE;
-}
-
-static void
-_cairo_gl_msaa_compositor_set_clip (cairo_composite_rectangles_t *composite,
-				    cairo_gl_composite_t *setup)
-{
-    if (_cairo_composite_rectangles_can_reduce_clip (composite, composite->clip))
-	return;
-    _cairo_gl_composite_set_clip (setup, composite->clip);
-}
-
-/* Masking with the SOURCE operator requires two passes. In the first
- * pass we use the mask as the source to get:
- * result = (1 - ma) * dst
- * In the second pass we use the add operator to achieve:
- * result = (src * ma) + dst
- * Combined this produces:
- * result = (src * ma) + (1 - ma) * dst
- */
-static cairo_int_status_t
-_cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compositor,
-						cairo_composite_rectangles_t *composite)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
-    cairo_gl_context_t *ctx = NULL;
-    cairo_int_status_t status;
-
-    cairo_clip_t *clip = composite->clip;
-    cairo_traps_t traps;
-
-    /* If we have a non-rectangular clip, we can avoid using the stencil buffer
-     * for clipping and just draw the clip polygon. */
-    if (clip) {
-	status = _clip_to_traps (clip, &traps);
-	if (unlikely (status)) {
-	    _cairo_traps_fini (&traps);
-	    return status;
-	}
-    }
-
-    status = _cairo_gl_composite_init (&setup,
-				       CAIRO_OPERATOR_DEST_OUT,
-				       dst,
-				       FALSE /* assume_component_alpha */);
-    if (unlikely (status))
-	return status;
-    status = _cairo_gl_composite_set_source (&setup,
-					     &composite->mask_pattern.base,
-					     &composite->mask_sample_area,
-					     &composite->bounded,
-					     FALSE);
-    if (unlikely (status))
-	goto finish;
-    _cairo_gl_composite_set_multisample (&setup);
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto finish;
-
-    if (! clip)
-	status = _draw_int_rect (ctx, &setup, &composite->bounded);
-    else
-	status = _draw_traps (ctx, &setup, &traps);
-    if (unlikely (status))
-	goto finish;
-
-    /* Now draw the second pass. */
-    status = _cairo_gl_composite_set_operator (&setup, CAIRO_OPERATOR_ADD,
-					       FALSE /* assume_component_alpha */);
-    if (unlikely (status))
-	goto finish;
-    status = _cairo_gl_composite_set_source (&setup,
-					     &composite->source_pattern.base,
-					     &composite->source_sample_area,
-					     &composite->bounded,
-					     FALSE);
-    if (unlikely (status))
-	goto finish;
-    status = _cairo_gl_composite_set_mask (&setup,
-					   &composite->mask_pattern.base,
-					   &composite->source_sample_area,
-					   &composite->bounded,
-					   FALSE);
-    if (unlikely (status))
-	goto finish;
-
-    _cairo_gl_context_set_destination (ctx, dst, setup.multisample);
-
-    status = _cairo_gl_set_operands_and_operator (&setup, ctx);
-    if (unlikely (status))
-	goto finish;
-
-    if (! clip)
-	status = _draw_int_rect (ctx, &setup, &composite->bounded);
-    else
-	status = _draw_traps (ctx, &setup, &traps);
-
-finish:
-    _cairo_gl_composite_fini (&setup);
-    if (ctx)
-	status = _cairo_gl_context_release (ctx, status);
-    if (clip)
-	_cairo_traps_fini (&traps);
-
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_gl_msaa_compositor_mask (const cairo_compositor_t	*compositor,
-				cairo_composite_rectangles_t	*composite)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
-    cairo_gl_context_t *ctx = NULL;
-    cairo_int_status_t status;
-    cairo_operator_t op = composite->op;
-    cairo_clip_t *clip = composite->clip;
-
-    if (! can_use_msaa_compositor (dst, CAIRO_ANTIALIAS_DEFAULT))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (composite->op == CAIRO_OPERATOR_CLEAR &&
-	composite->original_mask_pattern != NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    /* GL compositing operators cannot properly represent a mask operation
-       using the SOURCE compositing operator in one pass. This only matters if
-       there actually is a mask (there isn't in a paint operation) and if the
-       mask isn't totally opaque. */
-    if (op == CAIRO_OPERATOR_SOURCE &&
-	 composite->original_mask_pattern != NULL &&
-	! _cairo_pattern_is_opaque (&composite->mask_pattern.base,
-				    &composite->mask_sample_area)) {
-
-	if (! _cairo_pattern_is_opaque (&composite->source_pattern.base,
-				      &composite->source_sample_area)) {
-	    return _cairo_gl_msaa_compositor_mask_source_operator (compositor, composite);
-	}
-
-	/* If the source is opaque the operation reduces to OVER. */
-	op = CAIRO_OPERATOR_OVER;
-    }
-
-    if (_should_use_unbounded_surface (composite)) {
-	cairo_surface_t* surface = _prepare_unbounded_surface (dst);
-
-	if (unlikely (surface == NULL))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
-	/* This may be a paint operation. */
-	if (composite->original_mask_pattern == NULL) {
-	    status = _cairo_compositor_paint (compositor, surface,
-					      CAIRO_OPERATOR_SOURCE,
-					      &composite->source_pattern.base,
-					      NULL);
-	} else {
-	    status = _cairo_compositor_mask (compositor, surface,
-					     CAIRO_OPERATOR_SOURCE,
-					     &composite->source_pattern.base,
-					     &composite->mask_pattern.base,
-					     NULL);
-	}
-
-	if (unlikely (status)) {
-	    cairo_surface_destroy (surface);
-	    return status;
-	}
-
-	return _paint_back_unbounded_surface (compositor, composite, surface);
-    }
-
-    status = _cairo_gl_composite_init (&setup,
-				       op,
-				       dst,
-				       FALSE /* assume_component_alpha */);
-    if (unlikely (status))
-	return status;
-
-    status = _cairo_gl_composite_set_source (&setup,
-					     &composite->source_pattern.base,
-					     &composite->source_sample_area,
-					     &composite->bounded,
-					     FALSE);
-    if (unlikely (status))
-	goto finish;
-
-    if (composite->original_mask_pattern != NULL) {
-	status = _cairo_gl_composite_set_mask (&setup,
-					       &composite->mask_pattern.base,
-					       &composite->mask_sample_area,
-					       &composite->bounded,
-					       FALSE);
-    }
-    if (unlikely (status))
-	goto finish;
-
-    /* We always use multisampling here, because we do not yet have the smarts
-       to calculate when the clip or the source requires it. */
-     _cairo_gl_composite_set_multisample (&setup);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto finish;
-
-    if (! clip)
-	status = _draw_int_rect (ctx, &setup, &composite->bounded);
-    else
-	status = _cairo_gl_msaa_compositor_draw_clip (ctx, &setup, clip);
-
-finish:
-    _cairo_gl_composite_fini (&setup);
-
-    if (ctx)
-	status = _cairo_gl_context_release (ctx, status);
-
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_gl_msaa_compositor_paint (const cairo_compositor_t	*compositor,
-				 cairo_composite_rectangles_t	*composite)
-{
-    return _cairo_gl_msaa_compositor_mask (compositor, composite);
-}
-
-static cairo_status_t
-_stroke_shaper_add_triangle (void			*closure,
-			     const cairo_point_t	 triangle[3])
-{
-    struct _tristrip_composite_info *info = closure;
-    return _cairo_gl_composite_emit_triangle_as_tristrip (info->ctx,
-							  &info->setup,
-							  triangle);
-}
-
-static cairo_status_t
-_stroke_shaper_add_triangle_fan (void			*closure,
-				 const cairo_point_t	*midpoint,
-				 const cairo_point_t	*points,
-				 int			 npoints)
-{
-    struct _tristrip_composite_info *info = closure;
-    return _draw_triangle_fan (info->ctx, &info->setup,
-			       midpoint, points, npoints);
-}
-
-static cairo_status_t
-_stroke_shaper_add_quad (void			*closure,
-			 const cairo_point_t	 quad[4])
-{
-    struct _tristrip_composite_info *info = closure;
-    return _cairo_gl_composite_emit_quad_as_tristrip (info->ctx, &info->setup,
-						      quad);
-}
-
-static cairo_int_status_t
-_prevent_overlapping_strokes (cairo_gl_context_t		*ctx,
-			      cairo_gl_composite_t		*setup,
-			      cairo_composite_rectangles_t	*composite,
-			      const cairo_path_fixed_t		*path,
-			      const cairo_stroke_style_t	*style,
-			      const cairo_matrix_t		*ctm)
-{
-    cairo_rectangle_int_t stroke_extents;
-
-    if (! _cairo_gl_ensure_stencil (ctx, setup->dst))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (_cairo_pattern_is_opaque (&composite->source_pattern.base,
-				  &composite->source_sample_area))
-	return CAIRO_INT_STATUS_SUCCESS;
-
-   if (glIsEnabled (GL_STENCIL_TEST) == FALSE) {
-	cairo_bool_t scissor_was_enabled;
-
-       /* In case we have pending operations we have to flush before
-	  adding the stencil buffer. */
-       _cairo_gl_composite_flush (ctx);
-
-	/* Enable the stencil buffer, even if we are not using it for clipping,
-	   so we can use it below to prevent overlapping shapes. We initialize
-	   it all to one here which represents infinite clip. */
-	glDepthMask (GL_TRUE);
-	glEnable (GL_STENCIL_TEST);
-
-	/* We scissor here so that we don't have to clear the entire stencil
-	 * buffer. If the scissor test is already enabled, it was enabled
-	 * for clipping. In that case, instead of calculating an intersection,
-	 * we just reuse it, and risk clearing too much. */
-	scissor_was_enabled = glIsEnabled (GL_SCISSOR_TEST);
-	if (! scissor_was_enabled) {
-	    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm,
-							  FALSE, /* is_vector */
-							  &stroke_extents);
-	    _cairo_gl_scissor_to_rectangle (setup->dst, &stroke_extents);
-	}
-	glClearStencil (1);
-	glClear (GL_STENCIL_BUFFER_BIT);
-	if (! scissor_was_enabled)
-	    glDisable (GL_SCISSOR_TEST);
-
-	glStencilFunc (GL_EQUAL, 1, 1);
-    }
-
-    /* This means that once we draw to a particular pixel nothing else can
-       be drawn there until the stencil buffer is reset or the stencil test
-       is disabled. */
-    glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO);
-
-    _cairo_clip_destroy (setup->dst->clip_on_stencil_buffer);
-    setup->dst->clip_on_stencil_buffer = NULL;
-
-    return CAIRO_INT_STATUS_SUCCESS;
-}
-
-static void
-query_surface_capabilities (cairo_gl_surface_t *surface)
-{
-    GLint samples, stencil_bits;
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-
-    /* Texture surfaces are create in such a way that they always
-       have stencil and multisample bits if possible, so we don't
-       need to query their capabilities lazily. */
-    if (_cairo_gl_surface_is_texture (surface))
-	return;
-    if (surface->stencil_and_msaa_caps_initialized)
-	return;
-
-    surface->stencil_and_msaa_caps_initialized = TRUE;
-    surface->supports_stencil = FALSE;
-    surface->supports_msaa = FALSE;
-
-    status = _cairo_gl_context_acquire (surface->base.device, &ctx);
-    if (unlikely (status))
-	return;
-
-    _cairo_gl_context_set_destination (ctx, surface, FALSE);
-
-    glGetIntegerv(GL_SAMPLES, &samples);
-    glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
-    surface->supports_stencil = stencil_bits > 0;
-    surface->supports_msaa = samples > 1;
-    surface->num_samples = samples;
-
-    status = _cairo_gl_context_release (ctx, status);
-}
-
-static cairo_int_status_t
-_cairo_gl_msaa_compositor_stroke (const cairo_compositor_t	*compositor,
-				  cairo_composite_rectangles_t	*composite,
-				  const cairo_path_fixed_t	*path,
-				  const cairo_stroke_style_t	*style,
-				  const cairo_matrix_t		*ctm,
-				  const cairo_matrix_t		*ctm_inverse,
-				  double			 tolerance,
-				  cairo_antialias_t		 antialias)
-{
-    cairo_int_status_t status;
-    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
-    struct _tristrip_composite_info info;
-
-    if (! can_use_msaa_compositor (dst, antialias))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (composite->is_bounded == FALSE) {
-	cairo_surface_t* surface = _prepare_unbounded_surface (dst);
-
-	if (unlikely (surface == NULL))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
-	status = _cairo_compositor_stroke (compositor, surface,
-					   CAIRO_OPERATOR_SOURCE,
-					   &composite->source_pattern.base,
-					   path, style, ctm, ctm_inverse,
-					   tolerance, antialias, NULL);
-	if (unlikely (status)) {
-	    cairo_surface_destroy (surface);
-	    return status;
-	}
-
-	return _paint_back_unbounded_surface (compositor, composite, surface);
-    }
-
-    status = _cairo_gl_composite_init (&info.setup,
-				       composite->op,
-				       dst,
-				       FALSE /* assume_component_alpha */);
-    if (unlikely (status))
-	return status;
-
-    info.ctx = NULL;
-
-    status = _cairo_gl_composite_set_source (&info.setup,
-					     &composite->source_pattern.base,
-					     &composite->source_sample_area,
-					     &composite->bounded,
-					     FALSE);
-    if (unlikely (status))
-	goto finish;
-
-    _cairo_gl_msaa_compositor_set_clip (composite, &info.setup);
-    if (antialias != CAIRO_ANTIALIAS_NONE)
-	_cairo_gl_composite_set_multisample (&info.setup);
-
-    status = _cairo_gl_composite_begin (&info.setup, &info.ctx);
-    if (unlikely (status))
-	goto finish;
-
-    status = _prevent_overlapping_strokes (info.ctx, &info.setup,
-					   composite, path, style, ctm);
-    if (unlikely (status))
-	goto finish;
-
-    status = _cairo_path_fixed_stroke_to_shaper ((cairo_path_fixed_t *) path,
-						 style,
-						 ctm,
-						 ctm_inverse,
-						 tolerance,
-						 _stroke_shaper_add_triangle,
-						 _stroke_shaper_add_triangle_fan,
-						 _stroke_shaper_add_quad,
-						 &info);
-    if (unlikely (status))
-	goto finish;
-
-finish:
-    _cairo_gl_composite_fini (&info.setup);
-
-    if (info.ctx)
-	status = _cairo_gl_context_release (info.ctx, status);
-
-    return status;
-}
-
-static cairo_int_status_t
-_draw_simple_quad_path (cairo_gl_context_t *ctx,
-			cairo_gl_composite_t *setup,
-			const cairo_path_fixed_t *path)
-{
-    cairo_point_t triangle[3];
-    cairo_int_status_t status;
-    const cairo_point_t *points;
-
-    points = cairo_path_head (path)->points;
-    triangle[0] = points[0];
-    triangle[1] = points[1];
-    triangle[2] = points[2];
-    status = _cairo_gl_composite_emit_triangle_as_tristrip (ctx, setup, triangle);
-    if (status)
-	return status;
-
-    triangle[0] = points[2];
-    triangle[1] = points[3];
-    triangle[2] = points[0];
-    return _cairo_gl_composite_emit_triangle_as_tristrip (ctx, setup, triangle);
-}
-
-static cairo_int_status_t
-_cairo_gl_msaa_compositor_fill (const cairo_compositor_t	*compositor,
-				cairo_composite_rectangles_t	*composite,
-				const cairo_path_fixed_t	*path,
-				cairo_fill_rule_t		 fill_rule,
-				double				 tolerance,
-				cairo_antialias_t		 antialias)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
-    cairo_gl_context_t *ctx = NULL;
-    cairo_int_status_t status;
-    cairo_traps_t traps;
-    cairo_bool_t draw_path_with_traps;
-
-    if (! can_use_msaa_compositor (dst, antialias))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (composite->is_bounded == FALSE) {
-	cairo_surface_t* surface = _prepare_unbounded_surface (dst);
-
-	if (unlikely (surface == NULL))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
-
-	status = _cairo_compositor_fill (compositor, surface,
-					 CAIRO_OPERATOR_SOURCE,
-					 &composite->source_pattern.base,
-					 path, fill_rule, tolerance,
-					 antialias, NULL);
-
-	if (unlikely (status)) {
-	    cairo_surface_destroy (surface);
-	    return status;
-	}
-
-	return _paint_back_unbounded_surface (compositor, composite, surface);
-    }
-
-    draw_path_with_traps = ! _cairo_path_fixed_is_simple_quad (path);
-
-    if (draw_path_with_traps) {
-	_cairo_traps_init (&traps);
-	status = _cairo_path_fixed_fill_to_traps (path, fill_rule, tolerance, &traps);
-	if (unlikely (status))
-	    goto cleanup_traps;
-    }
-
-    status = _cairo_gl_composite_init (&setup,
-				       composite->op,
-				       dst,
-				       FALSE /* assume_component_alpha */);
-    if (unlikely (status))
-	goto cleanup_traps;
-
-    status = _cairo_gl_composite_set_source (&setup,
-					     &composite->source_pattern.base,
-					     &composite->source_sample_area,
-					     &composite->bounded,
-					     FALSE);
-    if (unlikely (status))
-	goto cleanup_setup;
-
-    _cairo_gl_msaa_compositor_set_clip (composite, &setup);
-    if (antialias != CAIRO_ANTIALIAS_NONE)
-	_cairo_gl_composite_set_multisample (&setup);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto cleanup_setup;
-
-    if (! draw_path_with_traps)
-	status = _draw_simple_quad_path (ctx, &setup, path);
-    else
-	status = _draw_traps (ctx, &setup, &traps);
-    if (unlikely (status))
-	goto cleanup_setup;
-
-cleanup_setup:
-    _cairo_gl_composite_fini (&setup);
-
-    if (ctx)
-	status = _cairo_gl_context_release (ctx, status);
-
-cleanup_traps:
-    if (draw_path_with_traps)
-	_cairo_traps_fini (&traps);
-
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_gl_msaa_compositor_glyphs (const cairo_compositor_t	*compositor,
-				  cairo_composite_rectangles_t	*composite,
-				  cairo_scaled_font_t		*scaled_font,
-				  cairo_glyph_t			*glyphs,
-				  int				 num_glyphs,
-				  cairo_bool_t			 overlap)
-{
-    cairo_int_status_t status;
-    cairo_surface_t *src = NULL;
-    int src_x, src_y;
-    cairo_composite_glyphs_info_t info;
-
-    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
-
-    query_surface_capabilities (dst);
-    if (! dst->supports_stencil)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (composite->op == CAIRO_OPERATOR_CLEAR)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (composite->is_bounded == FALSE) {
-	cairo_surface_t* surface = _prepare_unbounded_surface (dst);
-
-	if (unlikely (surface == NULL))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
-	status = _cairo_compositor_glyphs (compositor, surface,
-					   CAIRO_OPERATOR_SOURCE,
-					   &composite->source_pattern.base,
-					   glyphs, num_glyphs,
-					   scaled_font, composite->clip);
-
-	if (unlikely (status)) {
-	    cairo_surface_destroy (surface);
-	    return status;
-	}
-
-	return _paint_back_unbounded_surface (compositor, composite, surface);
-    }
-
-    src = _cairo_gl_pattern_to_source (&dst->base,
-				       &composite->source_pattern.base,
-				       FALSE,
-				       &composite->bounded,
-				       &composite->source_sample_area,
-				       &src_x, &src_y);
-    if (unlikely (src->status)) {
-	status = src->status;
-	goto finish;
-    }
-
-    status = _cairo_gl_check_composite_glyphs (composite,
-					       scaled_font, glyphs,
-					       &num_glyphs);
-    if (unlikely (status != CAIRO_INT_STATUS_SUCCESS))
-	goto finish;
-
-    info.font = scaled_font;
-    info.glyphs = glyphs;
-    info.num_glyphs = num_glyphs;
-    info.use_mask = overlap || ! composite->is_bounded ||
-		    composite->op == CAIRO_OPERATOR_SOURCE;
-    info.extents = composite->bounded;
-
-    _cairo_scaled_font_freeze_cache (scaled_font);
-    status = _cairo_gl_composite_glyphs_with_clip (dst, composite->op,
-						   src, src_x, src_y,
-						   0, 0, &info,
-						   composite->clip);
-
-    _cairo_scaled_font_thaw_cache (scaled_font);
-
-finish:
-    if (src)
-	cairo_surface_destroy (src);
-
-    return status;
-}
-
-static void
-_cairo_gl_msaa_compositor_init (cairo_compositor_t	 *compositor,
-				const cairo_compositor_t *delegate)
-{
-    compositor->delegate = delegate;
-
-    compositor->paint = _cairo_gl_msaa_compositor_paint;
-    compositor->mask = _cairo_gl_msaa_compositor_mask;
-    compositor->fill = _cairo_gl_msaa_compositor_fill;
-    compositor->stroke = _cairo_gl_msaa_compositor_stroke;
-    compositor->glyphs = _cairo_gl_msaa_compositor_glyphs;
-}
-
-const cairo_compositor_t *
-_cairo_gl_msaa_compositor_get (void)
-{
-    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
-    static cairo_compositor_t compositor;
-    if (_cairo_atomic_init_once_enter(&once)) {
-	_cairo_gl_msaa_compositor_init (&compositor,
-					_cairo_gl_span_compositor_get ());
-	_cairo_atomic_init_once_leave(&once);
-    }
-
-    return &compositor;
-}
diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
deleted file mode 100644
index a754bde2f..000000000
--- a/src/cairo-gl-operand.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- * Copyright © 2011 Intel Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-composite-rectangles-private.h"
-#include "cairo-compositor-private.h"
-#include "cairo-default-context-private.h"
-#include "cairo-error-private.h"
-#include "cairo-image-surface-private.h"
-#include "cairo-surface-backend-private.h"
-#include "cairo-surface-offset-private.h"
-#include "cairo-surface-subsurface-inline.h"
-
-static cairo_int_status_t
-_cairo_gl_create_gradient_texture (cairo_gl_surface_t *dst,
-				   const cairo_gradient_pattern_t *pattern,
-				   cairo_gl_gradient_t **gradient)
-{
-    cairo_gl_context_t *ctx;
-    cairo_status_t status;
-
-    status = _cairo_gl_context_acquire (dst->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    status = _cairo_gl_gradient_create (ctx, pattern->n_stops, pattern->stops, gradient);
-
-    return _cairo_gl_context_release (ctx, status);
-}
-
-static cairo_status_t
-_cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
-					 const cairo_pattern_t *_src,
-					 cairo_gl_surface_t *dst,
-					 const cairo_rectangle_int_t *sample,
-					 const cairo_rectangle_int_t *extents,
-					 cairo_bool_t use_texgen)
-{
-    const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
-    cairo_surface_pattern_t local_pattern;
-    cairo_surface_subsurface_t *sub;
-    cairo_gl_surface_t *surface;
-    cairo_gl_context_t *ctx;
-    cairo_surface_attributes_t *attributes;
-    cairo_status_t status;
-
-    sub = (cairo_surface_subsurface_t *) src->surface;
-
-    if (sub->snapshot &&
-	sub->snapshot->type == CAIRO_SURFACE_TYPE_GL &&
-	sub->snapshot->device == dst->base.device)
-    {
-	surface = (cairo_gl_surface_t *)
-	    cairo_surface_reference (sub->snapshot);
-    }
-    else
-    {
-	status = _cairo_gl_context_acquire (dst->base.device, &ctx);
-	if (unlikely (status))
-	    return status;
-
-	/* XXX Trim surface to the sample area within the subsurface? */
-	surface = (cairo_gl_surface_t *)
-	    _cairo_gl_surface_create_scratch (ctx,
-					      sub->target->content,
-					      sub->extents.width,
-					      sub->extents.height);
-	if (surface->base.status)
-	    return _cairo_gl_context_release (ctx, surface->base.status);
-
-	_cairo_pattern_init_for_surface (&local_pattern, sub->target);
-	cairo_matrix_init_translate (&local_pattern.base.matrix,
-				     sub->extents.x, sub->extents.y);
-	local_pattern.base.filter = CAIRO_FILTER_NEAREST;
-	status = _cairo_surface_paint (&surface->base,
-				       CAIRO_OPERATOR_SOURCE,
-				       &local_pattern.base,
-				       NULL);
-	_cairo_pattern_fini (&local_pattern.base);
-
-	status = _cairo_gl_context_release (ctx, status);
-	if (unlikely (status)) {
-	    cairo_surface_destroy (&surface->base);
-	    return status;
-	}
-
-	_cairo_surface_subsurface_set_snapshot (&sub->base, &surface->base);
-    }
-
-    status = _cairo_gl_surface_resolve_multisampling (surface);
-    if (unlikely (status))
-	return status;
-
-    attributes = &operand->texture.attributes;
-
-    operand->type = CAIRO_GL_OPERAND_TEXTURE;
-    operand->texture.surface = surface;
-    operand->texture.owns_surface = surface;
-    operand->texture.tex = surface->tex;
-
-    if (_cairo_gl_device_requires_power_of_two_textures (dst->base.device)) {
-	attributes->matrix = src->base.matrix;
-    } else {
-	cairo_matrix_t m;
-
-	cairo_matrix_init_scale (&m,
-				 1.0 / surface->width,
-				 1.0 / surface->height);
-	cairo_matrix_multiply (&attributes->matrix, &src->base.matrix, &m);
-    }
-
-    attributes->extend = src->base.extend;
-    attributes->filter = src->base.filter;
-    attributes->has_component_alpha = src->base.has_component_alpha;
-
-    operand->texture.texgen = use_texgen;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
-				   const cairo_pattern_t *_src,
-				   cairo_gl_surface_t *dst,
-				   const cairo_rectangle_int_t *sample,
-				   const cairo_rectangle_int_t *extents,
-				   cairo_bool_t use_texgen)
-{
-    const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
-    cairo_surface_subsurface_t *sub;
-    cairo_gl_surface_t *surface;
-    cairo_surface_attributes_t *attributes;
-    cairo_int_status_t status;
-
-    sub = (cairo_surface_subsurface_t *) src->surface;
-
-    if (sample->x < 0 || sample->y < 0 ||
-	sample->x + sample->width  > sub->extents.width ||
-	sample->y + sample->height > sub->extents.height)
-    {
-	return _cairo_gl_subsurface_clone_operand_init (operand, _src,
-							dst, sample, extents,
-							use_texgen);
-    }
-
-    surface = (cairo_gl_surface_t *) sub->target;
-    if (surface->base.device && surface->base.device != dst->base.device)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (! _cairo_gl_surface_is_texture (surface))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    status = _cairo_gl_surface_resolve_multisampling (surface);
-    if (unlikely (status))
-	return status;
-
-    /* Translate the matrix from
-     * (unnormalized src -> unnormalized src) to
-     * (unnormalized dst -> unnormalized src)
-     */
-    _cairo_gl_operand_copy(operand, &surface->operand);
-
-    attributes = &operand->texture.attributes;
-    attributes->matrix = src->base.matrix;
-    attributes->matrix.x0 += sub->extents.x;
-    attributes->matrix.y0 += sub->extents.y;
-    cairo_matrix_multiply (&attributes->matrix,
-			   &attributes->matrix,
-			   &surface->operand.texture.attributes.matrix);
-
-    attributes->extend = src->base.extend;
-    attributes->filter = src->base.filter;
-    attributes->has_component_alpha = src->base.has_component_alpha;
-
-    operand->texture.texgen = use_texgen;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
-				const cairo_pattern_t *_src,
-				cairo_gl_surface_t *dst,
-				const cairo_rectangle_int_t *sample,
-				const cairo_rectangle_int_t *extents,
-				cairo_bool_t use_texgen)
-{
-    const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
-    cairo_gl_surface_t *surface;
-    cairo_surface_attributes_t *attributes;
-    cairo_int_status_t status;
-
-    surface = (cairo_gl_surface_t *) src->surface;
-    if (surface->base.type != CAIRO_SURFACE_TYPE_GL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (surface->base.backend->type != CAIRO_SURFACE_TYPE_GL) {
-	if (_cairo_surface_is_subsurface (&surface->base))
-	    return _cairo_gl_subsurface_operand_init (operand, _src, dst,
-						      sample, extents,
-						      use_texgen);
-
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
-
-    if (surface->base.device && surface->base.device != dst->base.device)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (surface->base.device && ! _cairo_gl_surface_is_texture (surface))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    status = _cairo_gl_surface_resolve_multisampling (surface);
-    if (unlikely (status))
-	return status;
-
-    _cairo_gl_operand_copy(operand, &surface->operand);
-
-    attributes = &operand->texture.attributes;
-    cairo_matrix_multiply (&attributes->matrix,
-			   &src->base.matrix,
-			   &attributes->matrix);
-
-    attributes->extend = src->base.extend;
-    attributes->filter = src->base.filter;
-    attributes->has_component_alpha = src->base.has_component_alpha;
-
-    operand->texture.texgen = use_texgen;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand,
-				 const cairo_pattern_t *_src,
-				 cairo_gl_surface_t *dst,
-				 const cairo_rectangle_int_t *extents)
-{
-    cairo_status_t status;
-    cairo_gl_surface_t *surface;
-    cairo_gl_context_t *ctx;
-    cairo_image_surface_t *image;
-    cairo_bool_t src_is_gl_surface = FALSE;
-    cairo_rectangle_int_t map_extents;
-
-    if (_src->type == CAIRO_PATTERN_TYPE_SURFACE) {
-	cairo_surface_t* src_surface = ((cairo_surface_pattern_t *) _src)->surface;
-	src_is_gl_surface = src_surface->type == CAIRO_SURFACE_TYPE_GL;
-    }
-
-    status = _cairo_gl_context_acquire (dst->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    surface = (cairo_gl_surface_t *)
-	_cairo_gl_surface_create_scratch (ctx,
-					  CAIRO_CONTENT_COLOR_ALPHA,
-					  extents->width, extents->height);
-    map_extents = *extents;
-    map_extents.x = map_extents.y = 0;
-    image = _cairo_surface_map_to_image (&surface->base, &map_extents);
-
-    /* If the pattern is a GL surface, it belongs to some other GL context,
-       so we need to release this device while we paint it to the image. */
-    if (src_is_gl_surface) {
-	status = _cairo_gl_context_release (ctx, status);
-	if (unlikely (status)) {
-	    _cairo_surface_unmap_image (&surface->base, image);
-	    goto fail;
-	}
-    }
-
-    status = _cairo_surface_offset_paint (&image->base, extents->x, extents->y,
-					  CAIRO_OPERATOR_SOURCE, _src, NULL);
-
-    if (src_is_gl_surface) {
-	status = _cairo_gl_context_acquire (dst->base.device, &ctx);
-	if (unlikely (status)) {
-	    _cairo_surface_unmap_image (&surface->base, image);
-	    goto fail;
-	}
-    }
-
-    status = _cairo_surface_unmap_image (&surface->base, image);
-    status = _cairo_gl_context_release (ctx, status);
-    if (unlikely (status))
-	goto fail;
-
-    *operand = surface->operand;
-    operand->texture.owns_surface = surface;
-    operand->texture.attributes.matrix.x0 -= extents->x * operand->texture.attributes.matrix.xx;
-    operand->texture.attributes.matrix.y0 -= extents->y * operand->texture.attributes.matrix.yy;
-    return CAIRO_STATUS_SUCCESS;
-
-fail:
-    cairo_surface_destroy (&surface->base);
-    return status;
-}
-
-void
-_cairo_gl_solid_operand_init (cairo_gl_operand_t *operand,
-			      const cairo_color_t *color)
-{
-    operand->type = CAIRO_GL_OPERAND_CONSTANT;
-    operand->constant.color[0] = color->red   * color->alpha;
-    operand->constant.color[1] = color->green * color->alpha;
-    operand->constant.color[2] = color->blue  * color->alpha;
-    operand->constant.color[3] = color->alpha;
-}
-
-void
-_cairo_gl_operand_translate (cairo_gl_operand_t *operand,
-			     double tx, double ty)
-{
-    switch (operand->type) {
-    case CAIRO_GL_OPERAND_TEXTURE:
-	operand->texture.attributes.matrix.x0 -= tx * operand->texture.attributes.matrix.xx;
-	operand->texture.attributes.matrix.y0 -= ty * operand->texture.attributes.matrix.yy;
-	break;
-
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	operand->gradient.m.x0 -= tx * operand->gradient.m.xx;
-	operand->gradient.m.y0 -= ty * operand->gradient.m.yy;
-	break;
-
-    case CAIRO_GL_OPERAND_NONE:
-    case CAIRO_GL_OPERAND_CONSTANT:
-    case CAIRO_GL_OPERAND_COUNT:
-    default:
-	break;
-    }
-}
-
-static cairo_status_t
-_cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand,
-				 const cairo_pattern_t *pattern,
-				 cairo_gl_surface_t *dst,
-				 cairo_bool_t use_texgen)
-{
-    const cairo_gradient_pattern_t *gradient = (const cairo_gradient_pattern_t *)pattern;
-    cairo_status_t status;
-
-    assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR ||
-	    gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL);
-
-    if (! _cairo_gl_device_has_glsl (dst->base.device))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    status = _cairo_gl_create_gradient_texture (dst,
-						gradient,
-						&operand->gradient.gradient);
-    if (unlikely (status))
-	return status;
-
-    if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
-	cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient;
-	double x0, y0, dx, dy, sf, offset;
-
-	dx = linear->pd2.x - linear->pd1.x;
-	dy = linear->pd2.y - linear->pd1.y;
-	sf = 1.0 / (dx * dx + dy * dy);
-	dx *= sf;
-	dy *= sf;
-
-	x0 = linear->pd1.x;
-	y0 = linear->pd1.y;
-	offset = dx * x0 + dy * y0;
-
-	operand->type = CAIRO_GL_OPERAND_LINEAR_GRADIENT;
-
-	cairo_matrix_init (&operand->gradient.m, dx, 0, dy, 1, -offset, 0);
-	if (! _cairo_matrix_is_identity (&pattern->matrix)) {
-	    cairo_matrix_multiply (&operand->gradient.m,
-				   &pattern->matrix,
-				   &operand->gradient.m);
-	}
-    } else {
-	cairo_matrix_t m;
-	cairo_circle_double_t circles[2];
-	double x0, y0, r0, dx, dy, dr;
-
-	/*
-	 * Some fragment shader implementations use half-floats to
-	 * represent numbers, so the maximum number they can represent
-	 * is about 2^14. Some intermediate computations used in the
-	 * radial gradient shaders can produce results of up to 2*k^4.
-	 * Setting k=8 makes the maximum result about 8192 (assuming
-	 * that the extreme circles are not much smaller than the
-	 * destination image).
-	 */
-	_cairo_gradient_pattern_fit_to_range (gradient, 8.,
-					      &operand->gradient.m, circles);
-
-	x0 = circles[0].center.x;
-	y0 = circles[0].center.y;
-	r0 = circles[0].radius;
-	dx = circles[1].center.x - x0;
-	dy = circles[1].center.y - y0;
-	dr = circles[1].radius   - r0;
-
-	operand->gradient.a = dx * dx + dy * dy - dr * dr;
-	operand->gradient.radius_0 = r0;
-	operand->gradient.circle_d.center.x = dx;
-	operand->gradient.circle_d.center.y = dy;
-	operand->gradient.circle_d.radius   = dr;
-
-	if (operand->gradient.a == 0)
-	    operand->type = CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0;
-	else if (pattern->extend == CAIRO_EXTEND_NONE)
-	    operand->type = CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE;
-	else
-	    operand->type = CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT;
-
-	cairo_matrix_init_translate (&m, -x0, -y0);
-	cairo_matrix_multiply (&operand->gradient.m,
-			       &operand->gradient.m,
-			       &m);
-    }
-
-    operand->gradient.extend = pattern->extend;
-    operand->gradient.texgen = use_texgen;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-void
-_cairo_gl_operand_copy (cairo_gl_operand_t *dst,
-			const cairo_gl_operand_t *src)
-{
-    *dst = *src;
-    switch (dst->type) {
-    case CAIRO_GL_OPERAND_CONSTANT:
-	break;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	_cairo_gl_gradient_reference (dst->gradient.gradient);
-	break;
-    case CAIRO_GL_OPERAND_TEXTURE:
-	cairo_surface_reference (&dst->texture.owns_surface->base);
-	break;
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-	break;
-    }
-}
-
-void
-_cairo_gl_operand_destroy (cairo_gl_operand_t *operand)
-{
-    switch (operand->type) {
-    case CAIRO_GL_OPERAND_CONSTANT:
-	break;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	_cairo_gl_gradient_destroy (operand->gradient.gradient);
-	break;
-    case CAIRO_GL_OPERAND_TEXTURE:
-	cairo_surface_destroy (&operand->texture.owns_surface->base);
-	break;
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-	break;
-    }
-
-    operand->type = CAIRO_GL_OPERAND_NONE;
-}
-
-cairo_int_status_t
-_cairo_gl_operand_init (cairo_gl_operand_t *operand,
-			const cairo_pattern_t *pattern,
-			cairo_gl_surface_t *dst,
-			const cairo_rectangle_int_t *sample,
-			const cairo_rectangle_int_t *extents,
-			cairo_bool_t use_texgen)
-{
-    cairo_int_status_t status;
-
-    TRACE ((stderr, "%s: type=%d\n", __FUNCTION__, pattern->type));
-    switch (pattern->type) {
-    case CAIRO_PATTERN_TYPE_SOLID:
-	_cairo_gl_solid_operand_init (operand,
-				      &((cairo_solid_pattern_t *) pattern)->color);
-	return CAIRO_STATUS_SUCCESS;
-    case CAIRO_PATTERN_TYPE_SURFACE:
-	status = _cairo_gl_surface_operand_init (operand, pattern, dst,
-						 sample, extents, use_texgen);
-	if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-	    break;
-
-	return status;
-
-    case CAIRO_PATTERN_TYPE_LINEAR:
-    case CAIRO_PATTERN_TYPE_RADIAL:
-	status = _cairo_gl_gradient_operand_init (operand, pattern, dst,
-						  use_texgen);
-	if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-	    break;
-
-	return status;
-
-    default:
-    case CAIRO_PATTERN_TYPE_MESH:
-    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
-	break;
-    }
-
-    return _cairo_gl_pattern_texture_setup (operand, pattern, dst, extents);
-}
-
-cairo_filter_t
-_cairo_gl_operand_get_filter (cairo_gl_operand_t *operand)
-{
-    cairo_filter_t filter;
-
-    switch ((int) operand->type) {
-    case CAIRO_GL_OPERAND_TEXTURE:
-	filter = operand->texture.attributes.filter;
-	break;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	filter = CAIRO_FILTER_BILINEAR;
-	break;
-    default:
-	filter = CAIRO_FILTER_DEFAULT;
-	break;
-    }
-
-    return filter;
-}
-
-GLint
-_cairo_gl_operand_get_gl_filter (cairo_gl_operand_t *operand)
-{
-    cairo_filter_t filter = _cairo_gl_operand_get_filter (operand);
-
-    return filter != CAIRO_FILTER_FAST && filter != CAIRO_FILTER_NEAREST ?
-	   GL_LINEAR :
-	   GL_NEAREST;
-}
-
-cairo_extend_t
-_cairo_gl_operand_get_extend (cairo_gl_operand_t *operand)
-{
-    cairo_extend_t extend;
-
-    switch ((int) operand->type) {
-    case CAIRO_GL_OPERAND_TEXTURE:
-	extend = operand->texture.attributes.extend;
-	break;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	extend = operand->gradient.extend;
-	break;
-    default:
-	extend = CAIRO_EXTEND_NONE;
-	break;
-    }
-
-    return extend;
-}
-
-
-void
-_cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
-				  cairo_gl_operand_t *operand,
-				  cairo_gl_tex_t      tex_unit)
-{
-    const cairo_matrix_t *texgen = NULL;
-
-    switch (operand->type) {
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-	return;
-
-    case CAIRO_GL_OPERAND_CONSTANT:
-	_cairo_gl_shader_bind_vec4 (ctx,
-				    ctx->current_shader->constant_location[tex_unit],
-				    operand->constant.color[0],
-				    operand->constant.color[1],
-				    operand->constant.color[2],
-				    operand->constant.color[3]);
-	return;
-
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	_cairo_gl_shader_bind_float  (ctx,
-				      ctx->current_shader->a_location[tex_unit],
-				      operand->gradient.a);
-	/* fall through */
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-	_cairo_gl_shader_bind_vec3   (ctx,
-				      ctx->current_shader->circle_d_location[tex_unit],
-				      operand->gradient.circle_d.center.x,
-				      operand->gradient.circle_d.center.y,
-				      operand->gradient.circle_d.radius);
-	_cairo_gl_shader_bind_float  (ctx,
-				      ctx->current_shader->radius_0_location[tex_unit],
-				      operand->gradient.radius_0);
-	/* fall through */
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_TEXTURE:
-	/*
-	 * For GLES2 we use shaders to implement GL_CLAMP_TO_BORDER (used
-	 * with CAIRO_EXTEND_NONE). When bilinear filtering is enabled,
-	 * these shaders need the texture dimensions for their calculations.
-	 */
-	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
-	    _cairo_gl_operand_get_extend (operand) == CAIRO_EXTEND_NONE &&
-	    _cairo_gl_operand_get_gl_filter (operand) == GL_LINEAR)
-	{
-	    float width, height;
-	    if (operand->type == CAIRO_GL_OPERAND_TEXTURE) {
-		width = operand->texture.surface->width;
-		height = operand->texture.surface->height;
-	    }
-	    else {
-		width = operand->gradient.gradient->cache_entry.size,
-		height = 1;
-	    }
-	    _cairo_gl_shader_bind_vec2 (ctx,
-					ctx->current_shader->texdims_location[tex_unit],
-					width, height);
-	}
-	break;
-    }
-
-    if (operand->type == CAIRO_GL_OPERAND_TEXTURE) {
-	    if (operand->texture.texgen)
-		    texgen = &operand->texture.attributes.matrix;
-    } else {
-	    if (operand->gradient.texgen)
-		    texgen = &operand->gradient.m;
-    }
-    if (texgen) {
-	    _cairo_gl_shader_bind_matrix(ctx,
-					 ctx->current_shader->texgen_location[tex_unit],
-					 texgen);
-    }
-}
-
-
-cairo_bool_t
-_cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest,
-			       cairo_gl_operand_t *source,
-			       unsigned int        vertex_offset)
-{
-    if (dest->type != source->type)
-	return TRUE;
-    if (dest->vertex_offset != vertex_offset)
-	return TRUE;
-
-    switch (source->type) {
-    case CAIRO_GL_OPERAND_NONE:
-	return FALSE;
-    case CAIRO_GL_OPERAND_CONSTANT:
-	return dest->constant.color[0] != source->constant.color[0] ||
-	       dest->constant.color[1] != source->constant.color[1] ||
-	       dest->constant.color[2] != source->constant.color[2] ||
-	       dest->constant.color[3] != source->constant.color[3];
-    case CAIRO_GL_OPERAND_TEXTURE:
-	return dest->texture.surface != source->texture.surface ||
-	       dest->texture.attributes.extend != source->texture.attributes.extend ||
-	       dest->texture.attributes.filter != source->texture.attributes.filter ||
-	       dest->texture.attributes.has_component_alpha != source->texture.attributes.has_component_alpha;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	/* XXX: improve this */
-	return TRUE;
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-	break;
-    }
-    return TRUE;
-}
-
-unsigned int
-_cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand)
-{
-    switch (operand->type) {
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-    case CAIRO_GL_OPERAND_CONSTANT:
-	return 0;
-    case CAIRO_GL_OPERAND_TEXTURE:
-	return operand->texture.texgen ? 0 : 2 * sizeof (GLfloat);
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	return operand->gradient.texgen ? 0 : 2 * sizeof (GLfloat);
-    }
-}
-
-void
-_cairo_gl_operand_emit (cairo_gl_operand_t *operand,
-			GLfloat ** vb,
-			GLfloat x,
-			GLfloat y)
-{
-    switch (operand->type) {
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-    case CAIRO_GL_OPERAND_CONSTANT:
-	break;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	if (! operand->gradient.texgen) {
-	    double s = x;
-	    double t = y;
-
-	    cairo_matrix_transform_point (&operand->gradient.m, &s, &t);
-
-	    *(*vb)++ = s;
-	    *(*vb)++ = t;
-	}
-	break;
-    case CAIRO_GL_OPERAND_TEXTURE:
-	if (! operand->texture.texgen) {
-	    cairo_surface_attributes_t *src_attributes = &operand->texture.attributes;
-	    double s = x;
-	    double t = y;
-
-	    cairo_matrix_transform_point (&src_attributes->matrix, &s, &t);
-	    *(*vb)++ = s;
-	    *(*vb)++ = t;
-	}
-	break;
-    }
-}
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
deleted file mode 100644
index f02a58763..000000000
--- a/src/cairo-gl-private.h
+++ /dev/null
@@ -1,865 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- * Copyright © 2011 Linaro Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- *	T. Zachary Laine <whatwasthataddress at gmail.com>
- *	Alexandros Frantzis <alexandros.frantzis at linaro.org>
- */
-
-#ifndef CAIRO_GL_PRIVATE_H
-#define CAIRO_GL_PRIVATE_H
-
-#define GL_GLEXT_PROTOTYPES
-
-#include "cairoint.h"
-
-#include "cairo-gl.h"
-#include "cairo-gl-gradient-private.h"
-
-#include "cairo-device-private.h"
-#include "cairo-error-private.h"
-#include "cairo-rtree-private.h"
-#include "cairo-scaled-font-private.h"
-#include "cairo-spans-compositor-private.h"
-#include "cairo-array-private.h"
-
-#include <assert.h>
-
-#if CAIRO_HAS_GLESV3_SURFACE
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#elif CAIRO_HAS_GLESV2_SURFACE
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#elif CAIRO_HAS_GL_SURFACE
-#include <GL/gl.h>
-#include <GL/glext.h>
-#endif
-
-#include "cairo-gl-ext-def-private.h"
-
-#define DEBUG_GL 0
-
-#if DEBUG_GL && __GNUC__
-#define UNSUPPORTED(reason) ({ \
-    fprintf (stderr, \
-	     "cairo-gl: hit unsupported operation in %s(), line %d: %s\n", \
-	     __FUNCTION__, __LINE__, reason); \
-    CAIRO_INT_STATUS_UNSUPPORTED; \
-})
-#else
-#define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
-#endif
-
-#define CAIRO_GL_VERSION_ENCODE(major, minor) (	\
-	  ((major) * 256)			\
-	+ ((minor) *   1))
-
-/* maximal number of shaders we keep in the cache.
- * Random number that is hopefully big enough to not cause many cache evictions. */
-#define CAIRO_GL_MAX_SHADERS_PER_CONTEXT 64
-
-/* VBO size that we allocate, smaller size means we gotta flush more often,
- * but larger means hogging more memory and can cause trouble for drivers
- * (especially on embedded devices). Use the CAIRO_GL_VBO_SIZE environment
- * variable to set this to a different size. */
-#define CAIRO_GL_VBO_SIZE_DEFAULT (1024*1024)
-
-typedef struct _cairo_gl_surface cairo_gl_surface_t;
-
-/* GL flavor is the type of GL supported by the underlying platform. */
-typedef enum cairo_gl_flavor {
-    CAIRO_GL_FLAVOR_NONE = 0,
-    CAIRO_GL_FLAVOR_DESKTOP = 1,
-    CAIRO_GL_FLAVOR_ES2 = 2,
-    CAIRO_GL_FLAVOR_ES3 = 3
-} cairo_gl_flavor_t;
-
-/* Indices for vertex attributes used by BindAttribLocation, etc. */
-enum {
-    CAIRO_GL_VERTEX_ATTRIB_INDEX = 0,
-    CAIRO_GL_COLOR_ATTRIB_INDEX  = 1,
-    CAIRO_GL_TEXCOORD0_ATTRIB_INDEX = 2,
-    CAIRO_GL_TEXCOORD1_ATTRIB_INDEX = CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + 1
-};
-
-typedef enum cairo_gl_operand_type {
-    CAIRO_GL_OPERAND_NONE,
-    CAIRO_GL_OPERAND_CONSTANT,
-    CAIRO_GL_OPERAND_TEXTURE,
-    CAIRO_GL_OPERAND_LINEAR_GRADIENT,
-    CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0,
-    CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE,
-    CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT,
-
-    CAIRO_GL_OPERAND_COUNT
-} cairo_gl_operand_type_t;
-
-/* This union structure describes a potential source or mask operand to the
- * compositing equation.
- */
-typedef struct cairo_gl_operand {
-    cairo_gl_operand_type_t type;
-    union {
-	struct {
-	    GLuint tex;
-	    cairo_gl_surface_t *surface;
-	    cairo_gl_surface_t *owns_surface;
-	    cairo_surface_attributes_t attributes;
-	    int texgen;
-	} texture;
-	struct {
-	    GLfloat color[4];
-	} constant;
-	struct {
-	    cairo_gl_gradient_t *gradient;
-	    cairo_matrix_t m;
-	    cairo_circle_double_t circle_d;
-	    double radius_0, a;
-	    cairo_extend_t extend;
-	    int texgen;
-	} gradient;
-    };
-    unsigned int vertex_offset;
-} cairo_gl_operand_t;
-
-typedef struct cairo_gl_source {
-    cairo_surface_t base;
-    cairo_gl_operand_t operand;
-} cairo_gl_source_t;
-
-struct _cairo_gl_surface {
-    cairo_surface_t base;
-    cairo_gl_operand_t operand;
-
-    int width, height;
-
-    GLuint tex; /* GL texture object containing our data. */
-    GLuint fb; /* GL framebuffer object wrapping our data. */
-    GLuint depth_stencil; /* GL renderbuffer object for holding stencil buffer clip. */
-
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-    GLuint msaa_rb; /* The ARB MSAA path uses a renderbuffer. */
-    GLuint msaa_fb;
-#endif
-    GLuint msaa_depth_stencil;
-
-    cairo_bool_t stencil_and_msaa_caps_initialized;
-    cairo_bool_t supports_stencil; /* Stencil support for for non-texture surfaces. */
-    cairo_bool_t supports_msaa;
-    GLint        num_samples;
-    cairo_bool_t msaa_active; /* Whether the multisampling
-			         framebuffer is active or not. */
-    cairo_bool_t content_in_texture; /* whether we just uploaded image
-					to texture, used for certain
-					gles2 extensions and glesv3 */
-    cairo_clip_t *clip_on_stencil_buffer;
-
-    int owns_tex;
-    cairo_bool_t needs_update;
-
-    cairo_region_t *clip_region;
-};
-
-typedef struct cairo_gl_glyph_cache {
-    cairo_rtree_t rtree;
-    cairo_gl_surface_t *surface;
-} cairo_gl_glyph_cache_t;
-
-typedef enum cairo_gl_tex {
-    CAIRO_GL_TEX_SOURCE = 0,
-    CAIRO_GL_TEX_MASK = 1,
-    CAIRO_GL_TEX_TEMP = 2
-} cairo_gl_tex_t;
-
-typedef struct cairo_gl_shader {
-    GLuint fragment_shader;
-    GLuint program;
-    GLint mvp_location;
-    GLint constant_location[2];
-    GLint a_location[2];
-    GLint circle_d_location[2];
-    GLint radius_0_location[2];
-    GLint texdims_location[2];
-    GLint texgen_location[2];
-} cairo_gl_shader_t;
-
-typedef enum cairo_gl_shader_in {
-    CAIRO_GL_SHADER_IN_NORMAL,
-    CAIRO_GL_SHADER_IN_CA_SOURCE,
-    CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
-
-    CAIRO_GL_SHADER_IN_COUNT
-} cairo_gl_shader_in_t;
-
-typedef enum cairo_gl_var_type {
-  CAIRO_GL_VAR_NONE,
-  CAIRO_GL_VAR_TEXCOORDS,
-  CAIRO_GL_VAR_TEXGEN,
-} cairo_gl_var_type_t;
-
-typedef enum cairo_gl_primitive_type {
-    CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES,
-    CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS
-} cairo_gl_primitive_type_t;
-
-typedef void (*cairo_gl_emit_rect_t) (cairo_gl_context_t *ctx,
-				      GLfloat x1, GLfloat y1,
-				      GLfloat x2, GLfloat y2);
-
-typedef void (*cairo_gl_emit_span_t) (cairo_gl_context_t *ctx,
-				      GLfloat x1, GLfloat y1,
-				      GLfloat x2, GLfloat y2,
-				      uint8_t alpha);
-
-typedef void (*cairo_gl_emit_glyph_t) (cairo_gl_context_t *ctx,
-				       GLfloat x1, GLfloat y1,
-				       GLfloat x2, GLfloat y2,
-				       GLfloat glyph_x1, GLfloat glyph_y1,
-				       GLfloat glyph_x2, GLfloat glyph_y2);
-
-#define cairo_gl_var_type_hash(src,mask,spans,dest) ((spans) << 5) | ((mask) << 3 | (src << 1) | (dest))
-#define CAIRO_GL_VAR_TYPE_MAX (1 << 6)
-
-typedef void (*cairo_gl_generic_func_t)(void);
-typedef cairo_gl_generic_func_t (*cairo_gl_get_proc_addr_func_t)(const char *procname);
-
-typedef struct _cairo_gl_dispatch {
-    /* Buffers */
-    void (*GenBuffers) (GLsizei n, GLuint *buffers);
-    void (*BindBuffer) (GLenum target, GLuint buffer);
-    void (*BufferData) (GLenum target, GLsizeiptr size,
-			  const GLvoid* data, GLenum usage);
-    GLvoid *(*MapBuffer) (GLenum target, GLenum access);
-    GLboolean (*UnmapBuffer) (GLenum target);
-
-    /* Shaders */
-    GLuint (*CreateShader) (GLenum type);
-    void (*ShaderSource) (GLuint shader, GLsizei count,
-			    const GLchar** string, const GLint* length);
-    void (*CompileShader) (GLuint shader);
-    void (*GetShaderiv) (GLuint shader, GLenum pname, GLint *params);
-    void (*GetShaderInfoLog) (GLuint shader, GLsizei bufSize,
-				GLsizei *length, GLchar *infoLog);
-    void (*DeleteShader) (GLuint shader);
-
-    /* Programs */
-    GLuint (*CreateProgram) (void);
-    void (*AttachShader) (GLuint program, GLuint shader);
-    void (*DeleteProgram) (GLuint program);
-    void (*LinkProgram) (GLuint program);
-    void (*UseProgram) (GLuint program);
-    void (*GetProgramiv) (GLuint program, GLenum pname, GLint *params);
-    void (*GetProgramInfoLog) (GLuint program, GLsizei bufSize,
-				 GLsizei *length, GLchar *infoLog);
-
-    /* Uniforms */
-    GLint (*GetUniformLocation) (GLuint program, const GLchar* name);
-    void (*Uniform1f) (GLint location, GLfloat x);
-    void (*Uniform2f) (GLint location, GLfloat x, GLfloat y);
-    void (*Uniform3f) (GLint location, GLfloat x, GLfloat y, GLfloat z);
-    void (*Uniform4f) (GLint location, GLfloat x, GLfloat y, GLfloat z,
-			 GLfloat w);
-    void (*UniformMatrix3fv) (GLint location, GLsizei count,
-				GLboolean transpose, const GLfloat *value);
-    void (*UniformMatrix4fv) (GLint location, GLsizei count,
-			      GLboolean transpose, const GLfloat *value);
-    void (*Uniform1i) (GLint location, GLint x);
-
-    /* Attributes */
-    void (*BindAttribLocation) (GLuint program, GLuint index,
-				const GLchar *name);
-    void (*VertexAttribPointer) (GLuint index, GLint size, GLenum type,
-				 GLboolean normalized, GLsizei stride,
-				 const GLvoid *pointer);
-    void (*EnableVertexAttribArray) (GLuint index);
-    void (*DisableVertexAttribArray) (GLuint index);
-
-    /* Framebuffer objects */
-    void (*GenFramebuffers) (GLsizei n, GLuint* framebuffers);
-    void (*BindFramebuffer) (GLenum target, GLuint framebuffer);
-    void (*FramebufferTexture2D) (GLenum target, GLenum attachment,
-				    GLenum textarget, GLuint texture,
-				    GLint level);
-    GLenum (*CheckFramebufferStatus) (GLenum target);
-    void (*DeleteFramebuffers) (GLsizei n, const GLuint* framebuffers);
-    void (*GenRenderbuffers) (GLsizei n, GLuint *renderbuffers);
-    void (*BindRenderbuffer) (GLenum target, GLuint renderbuffer);
-    void (*RenderbufferStorage) (GLenum target, GLenum internal_format,
-				 GLsizei width, GLsizei height);
-    void (*FramebufferRenderbuffer) (GLenum target, GLenum attachment,
-				     GLenum renderbuffer_ttarget, GLuint renderbuffer);
-    void (*DeleteRenderbuffers) (GLsizei n, GLuint *renderbuffers);
-    void (*BlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-			     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-			     GLbitfield mask, GLenum filter);
-    void (*RenderbufferStorageMultisample) (GLenum target, GLsizei samples,
-					    GLenum internalformat,
-					    GLsizei width, GLsizei height);
-    void (*FramebufferTexture2DMultisample) (GLenum target, GLenum attachment,
-					     GLenum textarget, GLuint texture,
-					     GLint level, GLsizei samples);
-} cairo_gl_dispatch_t;
-
-struct _cairo_gl_context {
-    cairo_device_t base;
-
-    const cairo_compositor_t *compositor;
-
-    GLuint texture_load_pbo;
-    GLint max_framebuffer_size;
-    GLint max_texture_size;
-    GLint max_textures;
-    GLenum tex_target;
-
-    GLint num_samples;
-    cairo_bool_t supports_msaa;
-    char *vb;
-
-    cairo_bool_t has_shader_support;
-
-    GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX];
-    cairo_gl_shader_t fill_rectangles_shader;
-    cairo_cache_t shaders;
-
-    cairo_cache_t gradients;
-
-    cairo_gl_glyph_cache_t glyph_cache[2];
-    cairo_list_t fonts;
-
-    cairo_gl_surface_t *current_target;
-    cairo_operator_t current_operator;
-    cairo_gl_shader_t *pre_shader; /* for component alpha */
-    cairo_gl_shader_t *current_shader;
-
-    cairo_gl_operand_t operands[2];
-    cairo_bool_t spans;
-
-    unsigned int vbo_size;
-    unsigned int vb_offset;
-    unsigned int vertex_size;
-    cairo_region_t *clip_region;
-    cairo_clip_t *clip;
-
-    cairo_gl_primitive_type_t primitive_type;
-    cairo_array_t tristrip_indices;
-
-    cairo_bool_t has_mesa_pack_invert;
-    cairo_gl_dispatch_t dispatch;
-    GLfloat modelviewprojection_matrix[16];
-    cairo_gl_flavor_t gl_flavor;
-    cairo_bool_t has_map_buffer;
-    cairo_bool_t has_packed_depth_stencil;
-    cairo_bool_t has_npot_repeat;
-    cairo_bool_t can_read_bgra;
-
-    cairo_bool_t thread_aware;
-
-    void (*acquire) (void *ctx);
-    void (*release) (void *ctx);
-
-    void (*make_current) (void *ctx, cairo_gl_surface_t *surface);
-    void (*swap_buffers)(void *ctx, cairo_gl_surface_t *surface);
-    void (*destroy) (void *ctx);
-};
-
-typedef struct _cairo_gl_composite {
-    cairo_gl_surface_t *dst;
-    cairo_operator_t op;
-    cairo_region_t *clip_region;
-
-    cairo_gl_operand_t src;
-    cairo_gl_operand_t mask;
-    cairo_bool_t spans;
-
-    cairo_clip_t *clip;
-    cairo_bool_t multisample;
-} cairo_gl_composite_t;
-
-typedef struct _cairo_gl_font {
-    cairo_scaled_font_private_t		base;
-    cairo_device_t			*device;
-    cairo_list_t			link;
-} cairo_gl_font_t;
-
-static cairo_always_inline GLenum
-_cairo_gl_get_error (void)
-{
-    GLenum err = glGetError();
-
-    if (unlikely (err))
-        while (glGetError ());
-
-    return err;
-}
-
-static inline cairo_device_t *
-_cairo_gl_context_create_in_error (cairo_status_t status)
-{
-    return (cairo_device_t *) _cairo_device_create_in_error (status);
-}
-
-cairo_private cairo_status_t
-_cairo_gl_context_init (cairo_gl_context_t *ctx);
-
-cairo_private void
-_cairo_gl_surface_init (cairo_device_t *device,
-			cairo_gl_surface_t *surface,
-			cairo_content_t content,
-			int width, int height);
-
-static cairo_always_inline cairo_bool_t cairo_warn
-_cairo_gl_surface_is_texture (cairo_gl_surface_t *surface)
-{
-    return surface->tex != 0;
-}
-
-cairo_private cairo_status_t
-_cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
-			      cairo_image_surface_t *src,
-			      int src_x, int src_y,
-			      int width, int height,
-			      int dst_x, int dst_y,
-			      cairo_bool_t force_flush);
-
-cairo_private cairo_int_status_t
-_cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface);
-
-static cairo_always_inline cairo_bool_t
-_cairo_gl_device_has_glsl (cairo_device_t *device)
-{
-    return ((cairo_gl_context_t *) device)->has_shader_support;
-}
-
-static cairo_always_inline cairo_bool_t
-_cairo_gl_device_requires_power_of_two_textures (cairo_device_t *device)
-{
-    return ((cairo_gl_context_t *) device)->tex_target == GL_TEXTURE_RECTANGLE;
-}
-
-static cairo_always_inline cairo_status_t cairo_warn
-_cairo_gl_context_acquire (cairo_device_t *device,
-			   cairo_gl_context_t **ctx)
-{
-    cairo_status_t status;
-
-    status = cairo_device_acquire (device);
-    if (unlikely (status))
-	return status;
-
-    /* clear potential previous GL errors */
-    _cairo_gl_get_error ();
-
-    *ctx = (cairo_gl_context_t *) device;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_always_inline cairo_warn cairo_status_t
-_cairo_gl_context_release (cairo_gl_context_t *ctx, cairo_status_t status)
-{
-    GLenum err;
-
-    err = _cairo_gl_get_error ();
-
-    if (unlikely (err)) {
-        cairo_status_t new_status;
-	new_status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
-        if (status == CAIRO_STATUS_SUCCESS)
-            status = new_status;
-    }
-
-    cairo_device_release (&(ctx)->base);
-
-    return status;
-}
-
-cairo_private void
-_cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
-				   cairo_gl_surface_t *surface,
-				   cairo_bool_t multisampling);
-
-cairo_private void
-_cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx,
-				    cairo_gl_surface_t *surface,
-				    cairo_bool_t multisampling);
-
-cairo_private cairo_gl_emit_rect_t
-_cairo_gl_context_choose_emit_rect (cairo_gl_context_t *ctx);
-
-cairo_private void
-_cairo_gl_context_emit_rect (cairo_gl_context_t *ctx,
-			     GLfloat x1, GLfloat y1,
-			     GLfloat x2, GLfloat y2);
-
-cairo_private cairo_gl_emit_span_t
-_cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx);
-
-cairo_private cairo_gl_emit_glyph_t
-_cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx);
-
-cairo_private void
-_cairo_gl_context_activate (cairo_gl_context_t *ctx,
-                            cairo_gl_tex_t      tex_unit);
-
-cairo_private cairo_bool_t
-_cairo_gl_operator_is_supported (cairo_operator_t op);
-
-cairo_private cairo_bool_t
-_cairo_gl_ensure_stencil (cairo_gl_context_t *ctx,
-			  cairo_gl_surface_t *surface);
-
-cairo_private cairo_status_t
-_cairo_gl_composite_init (cairo_gl_composite_t *setup,
-                          cairo_operator_t op,
-                          cairo_gl_surface_t *dst,
-                          cairo_bool_t has_component_alpha);
-
-cairo_private void
-_cairo_gl_composite_fini (cairo_gl_composite_t *setup);
-
-cairo_private cairo_status_t
-_cairo_gl_composite_set_operator (cairo_gl_composite_t *setup,
-				  cairo_operator_t op,
-				  cairo_bool_t assume_component_alpha);
-
-cairo_private void
-_cairo_gl_composite_set_clip_region (cairo_gl_composite_t *setup,
-                                     cairo_region_t *clip_region);
-
-cairo_private void
-_cairo_gl_composite_set_clip(cairo_gl_composite_t *setup,
-			     cairo_clip_t *clip);
-
-cairo_private cairo_int_status_t
-_cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
-				const cairo_pattern_t *pattern,
-				const cairo_rectangle_int_t *sample,
-				const cairo_rectangle_int_t *extents,
-				cairo_bool_t use_texgen);
-
-cairo_private void
-_cairo_gl_composite_set_solid_source (cairo_gl_composite_t *setup,
-				      const cairo_color_t *color);
-
-cairo_private void
-_cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup,
-					const cairo_gl_operand_t *source);
-
-cairo_private cairo_int_status_t
-_cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
-			      const cairo_pattern_t *pattern,
-			      const cairo_rectangle_int_t *sample,
-			      const cairo_rectangle_int_t *extents,
-			      cairo_bool_t use_texgen);
-
-cairo_private void
-_cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
-				      const cairo_gl_operand_t *mask);
-
-cairo_private void
-_cairo_gl_composite_set_spans (cairo_gl_composite_t *setup);
-
-cairo_private void
-_cairo_gl_composite_set_multisample (cairo_gl_composite_t *setup);
-
-cairo_private cairo_status_t
-_cairo_gl_composite_begin (cairo_gl_composite_t *setup,
-                           cairo_gl_context_t **ctx);
-
-cairo_private cairo_status_t
-_cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup,
-				     cairo_gl_context_t *ctx);
-
-cairo_private void
-_cairo_gl_composite_flush (cairo_gl_context_t *ctx);
-
-cairo_private cairo_int_status_t
-_cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t	*ctx,
-					   cairo_gl_composite_t	*setup,
-					   const cairo_point_t	 quad[4]);
-
-cairo_private cairo_int_status_t
-_cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t	*ctx,
-					       cairo_gl_composite_t	*setup,
-					       const cairo_point_t	 triangle[3]);
-
-cairo_private void
-_cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
-                                   cairo_gl_tex_t tex_unit);
-
-cairo_private cairo_bool_t
-_cairo_gl_get_image_format_and_type (cairo_gl_flavor_t flavor,
-				     pixman_format_code_t pixman_format,
-				     GLenum *internal_format, GLenum *format,
-				     GLenum *type, cairo_bool_t *has_alpha,
-				     cairo_bool_t *needs_swap);
-
-cairo_private void
-_cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache);
-
-cairo_private void
-_cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
-			    cairo_gl_glyph_cache_t *cache);
-
-cairo_private cairo_int_status_t
-_cairo_gl_surface_show_glyphs (void			*abstract_dst,
-			       cairo_operator_t		 op,
-			       const cairo_pattern_t	*source,
-			       cairo_glyph_t		*glyphs,
-			       int			 num_glyphs,
-			       cairo_scaled_font_t	*scaled_font,
-			       const cairo_clip_t	*clip,
-			       int			*remaining_glyphs);
-
-cairo_private cairo_status_t
-_cairo_gl_context_init_shaders (cairo_gl_context_t *ctx);
-
-cairo_private void
-_cairo_gl_context_fini_shaders (cairo_gl_context_t *ctx);
-
-static cairo_always_inline cairo_bool_t
-_cairo_gl_context_is_flushed (cairo_gl_context_t *ctx)
-{
-    return ctx->vb_offset == 0;
-}
-
-cairo_private cairo_status_t
-_cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
-                              cairo_gl_operand_t *source,
-                              cairo_gl_operand_t *mask,
-			      cairo_bool_t use_coverage,
-                              cairo_gl_shader_in_t in,
-                              cairo_gl_shader_t **shader);
-
-cairo_private void
-_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
-			     GLint location,
-			     float value);
-
-cairo_private void
-_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
-			    GLint location,
-			    float value0, float value1);
-
-cairo_private void
-_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
-			    GLint location,
-			    float value0,
-			    float value1,
-			    float value2);
-
-cairo_private void
-_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
-			    GLint location,
-			    float value0, float value1,
-			    float value2, float value3);
-
-cairo_private void
-_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
-			      GLint location,
-			      const cairo_matrix_t* m);
-
-cairo_private void
-_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
-				GLint location,
-				GLfloat* gl_m);
-
-cairo_private void
-_cairo_gl_set_shader (cairo_gl_context_t *ctx,
-		      cairo_gl_shader_t *shader);
-
-cairo_private void
-_cairo_gl_shader_fini (cairo_gl_context_t *ctx, cairo_gl_shader_t *shader);
-
-cairo_private int
-_cairo_gl_get_version (void);
-
-cairo_private cairo_gl_flavor_t
-_cairo_gl_get_flavor (void);
-
-cairo_private unsigned long
-_cairo_gl_get_vbo_size (void);
-
-cairo_private cairo_bool_t
-_cairo_gl_has_extension (const char *ext);
-
-cairo_private cairo_status_t
-_cairo_gl_dispatch_init(cairo_gl_dispatch_t *dispatch,
-			cairo_gl_get_proc_addr_func_t get_proc_addr);
-
-cairo_private cairo_int_status_t
-_cairo_gl_operand_init (cairo_gl_operand_t *operand,
-		        const cairo_pattern_t *pattern,
-		        cairo_gl_surface_t *dst,
-			const cairo_rectangle_int_t *sample,
-			const cairo_rectangle_int_t *extents,
-			cairo_bool_t use_texgen);
-
-cairo_private void
-_cairo_gl_solid_operand_init (cairo_gl_operand_t *operand,
-	                      const cairo_color_t *color);
-
-cairo_private cairo_filter_t
-_cairo_gl_operand_get_filter (cairo_gl_operand_t *operand);
-
-cairo_private GLint
-_cairo_gl_operand_get_gl_filter (cairo_gl_operand_t *operand);
-
-cairo_private cairo_extend_t
-_cairo_gl_operand_get_extend (cairo_gl_operand_t *operand);
-
-cairo_private unsigned int
-_cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand);
-
-cairo_private cairo_bool_t
-_cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest,
-                               cairo_gl_operand_t *source,
-                               unsigned int        vertex_offset);
-
-cairo_private void
-_cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
-                                  cairo_gl_operand_t *operand,
-                                  cairo_gl_tex_t      tex_unit);
-
-cairo_private void
-_cairo_gl_operand_emit (cairo_gl_operand_t *operand,
-                        GLfloat ** vb,
-                        GLfloat x,
-                        GLfloat y);
-
-cairo_private void
-_cairo_gl_operand_copy (cairo_gl_operand_t *dst,
-			const cairo_gl_operand_t *src);
-
-cairo_private void
-_cairo_gl_operand_translate (cairo_gl_operand_t *operand,
-			     double tx, double ty);
-
-cairo_private void
-_cairo_gl_operand_destroy (cairo_gl_operand_t *operand);
-
-cairo_private const cairo_compositor_t *
-_cairo_gl_msaa_compositor_get (void);
-
-cairo_private const cairo_compositor_t *
-_cairo_gl_span_compositor_get (void);
-
-cairo_private const cairo_compositor_t *
-_cairo_gl_traps_compositor_get (void);
-
-cairo_private cairo_int_status_t
-_cairo_gl_check_composite_glyphs (const cairo_composite_rectangles_t *extents,
-				  cairo_scaled_font_t *scaled_font,
-				  cairo_glyph_t *glyphs,
-				  int *num_glyphs);
-
-cairo_private cairo_int_status_t
-_cairo_gl_composite_glyphs (void			*_dst,
-			    cairo_operator_t		 op,
-			    cairo_surface_t		*_src,
-			    int				 src_x,
-			    int				 src_y,
-			    int				 dst_x,
-			    int				 dst_y,
-			    cairo_composite_glyphs_info_t *info);
-
-cairo_private cairo_int_status_t
-_cairo_gl_composite_glyphs_with_clip (void			    *_dst,
-				      cairo_operator_t		     op,
-				      cairo_surface_t		    *_src,
-				      int			     src_x,
-				      int			     src_y,
-				      int			     dst_x,
-				      int			     dst_y,
-				      cairo_composite_glyphs_info_t *info,
-				      cairo_clip_t		    *clip);
-
-cairo_private void
-_cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
-                              cairo_gl_surface_t *surface);
-
-cairo_private cairo_surface_t *
-_cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
-				  cairo_content_t	content,
-				  int			width,
-				  int			height);
-
-cairo_private cairo_surface_t *
-_cairo_gl_surface_create_scratch_for_caching (cairo_gl_context_t *ctx,
-					      cairo_content_t content,
-					      int width,
-					      int height);
-
-cairo_private cairo_surface_t *
-_cairo_gl_pattern_to_source (cairo_surface_t *dst,
-			     const cairo_pattern_t *pattern,
-			     cairo_bool_t is_mask,
-			     const cairo_rectangle_int_t *extents,
-			     const cairo_rectangle_int_t *sample,
-			     int *src_x, int *src_y);
-
-cairo_private cairo_int_status_t
-_cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx,
-				     cairo_gl_composite_t *setup,
-				     cairo_clip_t *clip);
-
-cairo_private cairo_surface_t *
-_cairo_gl_white_source (void);
-
-cairo_private void
-_cairo_gl_scissor_to_rectangle (cairo_gl_surface_t *surface,
-				const cairo_rectangle_int_t *r);
-
-static inline cairo_gl_operand_t *
-source_to_operand (cairo_surface_t *surface)
-{
-    cairo_gl_source_t *source = (cairo_gl_source_t *)surface;
-    return source ? &source->operand : NULL;
-}
-
-static inline void
-_cairo_gl_glyph_cache_unlock (cairo_gl_glyph_cache_t *cache)
-{
-    _cairo_rtree_unpin (&cache->rtree);
-}
-
-
-slim_hidden_proto (cairo_gl_surface_create);
-slim_hidden_proto (cairo_gl_surface_create_for_texture);
-
-#endif /* CAIRO_GL_PRIVATE_H */
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
deleted file mode 100644
index b70c177f2..000000000
--- a/src/cairo-gl-shaders.c
+++ /dev/null
@@ -1,1111 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 T. Zachary Laine
- * Copyright © 2010 Eric Anholt
- * Copyright © 2010 Red Hat, Inc
- * Copyright © 2010 Linaro Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is T. Zachary Laine.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Eric Anholt <eric at anholt.net>
- *	T. Zachary Laine <whatwasthataddress at gmail.com>
- *	Alexandros Frantzis <alexandros.frantzis at linaro.org>
- *  H. Lewin <heiko.lewin at gmx.de>
- */
-
-#include "cairoint.h"
-#include "cairo-gl-private.h"
-#include "cairo-error-private.h"
-#include "cairo-output-stream-private.h"
-
-static cairo_status_t
-_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
-				   cairo_gl_shader_t *shader,
-				   cairo_gl_var_type_t src,
-				   cairo_gl_var_type_t mask,
-				   cairo_bool_t use_coverage,
-				   const char *fragment_text);
-
-typedef struct _cairo_shader_cache_entry {
-    cairo_cache_entry_t base;
-
-    unsigned vertex;
-
-    cairo_gl_operand_type_t src;
-    cairo_gl_operand_type_t mask;
-    cairo_gl_operand_type_t dest;
-    cairo_bool_t use_coverage;
-
-    cairo_gl_shader_in_t in;
-    GLint src_gl_filter;
-    cairo_bool_t src_border_fade;
-    cairo_extend_t src_extend;
-    GLint mask_gl_filter;
-    cairo_bool_t mask_border_fade;
-    cairo_extend_t mask_extend;
-
-    cairo_gl_context_t *ctx; /* XXX: needed to destroy the program */
-    cairo_gl_shader_t shader;
-} cairo_shader_cache_entry_t;
-
-static cairo_bool_t
-_cairo_gl_shader_cache_equal_desktop (const void *key_a, const void *key_b)
-{
-    const cairo_shader_cache_entry_t *a = key_a;
-    const cairo_shader_cache_entry_t *b = key_b;
-    cairo_bool_t both_have_npot_repeat =
-	a->ctx->has_npot_repeat && b->ctx->has_npot_repeat;
-
-    return (a->vertex == b->vertex &&
-	    a->src  == b->src  &&
-	    a->mask == b->mask &&
-	    a->dest == b->dest &&
-	    a->use_coverage == b->use_coverage &&
-	    a->in   == b->in &&
-	    (both_have_npot_repeat || a->src_extend == b->src_extend) &&
-	    (both_have_npot_repeat || a->mask_extend == b->mask_extend));
-}
-
-/*
- * For GLES2 we use more complicated shaders to implement missing GL
- * features. In this case we need more parameters to uniquely identify
- * a shader (vs _cairo_gl_shader_cache_equal_desktop()).
- */
-static cairo_bool_t
-_cairo_gl_shader_cache_equal_gles2 (const void *key_a, const void *key_b)
-{
-    const cairo_shader_cache_entry_t *a = key_a;
-    const cairo_shader_cache_entry_t *b = key_b;
-    cairo_bool_t both_have_npot_repeat =
-	a->ctx->has_npot_repeat && b->ctx->has_npot_repeat;
-
-    return (a->vertex == b->vertex &&
-	    a->src  == b->src  &&
-	    a->mask == b->mask &&
-	    a->dest == b->dest &&
-	    a->use_coverage == b->use_coverage &&
-	    a->in   == b->in   &&
-	    a->src_gl_filter == b->src_gl_filter &&
-	    a->src_border_fade == b->src_border_fade &&
-	    (both_have_npot_repeat || a->src_extend == b->src_extend) &&
-	    a->mask_gl_filter == b->mask_gl_filter &&
-	    a->mask_border_fade == b->mask_border_fade &&
-	    (both_have_npot_repeat || a->mask_extend == b->mask_extend));
-}
-
-static unsigned long
-_cairo_gl_shader_cache_hash (const cairo_shader_cache_entry_t *entry)
-{
-    return (((uint32_t)entry->src << 24) | (entry->mask << 16) | (entry->dest << 8) | (entry->in << 1) | entry->use_coverage) ^ entry->vertex;
-}
-
-static void
-_cairo_gl_shader_cache_destroy (void *data)
-{
-    cairo_shader_cache_entry_t *entry = data;
-
-    _cairo_gl_shader_fini (entry->ctx, &entry->shader);
-    if (entry->ctx->current_shader == &entry->shader)
-	entry->ctx->current_shader = NULL;
-    free (entry);
-}
-
-static void
-_cairo_gl_shader_init (cairo_gl_shader_t *shader)
-{
-    shader->fragment_shader = 0;
-    shader->program = 0;
-}
-
-cairo_status_t
-_cairo_gl_context_init_shaders (cairo_gl_context_t *ctx)
-{
-    static const char *fill_fs_source =
-	"#ifdef GL_ES\n"
-	"precision mediump float;\n"
-	"#endif\n"
-	"uniform vec4 color;\n"
-	"void main()\n"
-	"{\n"
-	"	gl_FragColor = color;\n"
-	"}\n";
-    cairo_status_t status;
-
-    if (_cairo_gl_get_version () >= CAIRO_GL_VERSION_ENCODE (2, 0) ||
-	(_cairo_gl_has_extension ("GL_ARB_shader_objects") &&
-	 _cairo_gl_has_extension ("GL_ARB_fragment_shader") &&
-	 _cairo_gl_has_extension ("GL_ARB_vertex_shader"))) {
-	ctx->has_shader_support = TRUE;
-    } else {
-	ctx->has_shader_support = FALSE;
-	fprintf (stderr, "Error: The cairo gl backend requires shader support!\n");
-	return CAIRO_STATUS_DEVICE_ERROR;
-    }
-
-    memset (ctx->vertex_shaders, 0, sizeof (ctx->vertex_shaders));
-
-    status = _cairo_cache_init (&ctx->shaders,
-				ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ?
-				    _cairo_gl_shader_cache_equal_desktop :
-				    _cairo_gl_shader_cache_equal_gles2,
-				NULL,
-				_cairo_gl_shader_cache_destroy,
-				CAIRO_GL_MAX_SHADERS_PER_CONTEXT);
-    if (unlikely (status))
-	return status;
-
-    _cairo_gl_shader_init (&ctx->fill_rectangles_shader);
-    status = _cairo_gl_shader_compile_and_link (ctx,
-						&ctx->fill_rectangles_shader,
-						CAIRO_GL_VAR_NONE,
-						CAIRO_GL_VAR_NONE,
-						FALSE,
-						fill_fs_source);
-    if (unlikely (status))
-	return status;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-void
-_cairo_gl_context_fini_shaders (cairo_gl_context_t *ctx)
-{
-    int i;
-
-    for (i = 0; i < CAIRO_GL_VAR_TYPE_MAX; i++) {
-	if (ctx->vertex_shaders[i])
-	    ctx->dispatch.DeleteShader (ctx->vertex_shaders[i]);
-    }
-
-    _cairo_gl_shader_fini(ctx, &ctx->fill_rectangles_shader);
-    _cairo_cache_fini (&ctx->shaders);
-}
-
-void
-_cairo_gl_shader_fini (cairo_gl_context_t *ctx,
-		       cairo_gl_shader_t *shader)
-{
-    if (shader->fragment_shader)
-	ctx->dispatch.DeleteShader (shader->fragment_shader);
-
-    if (shader->program)
-	ctx->dispatch.DeleteProgram (shader->program);
-}
-
-static const char *operand_names[] = { "source", "mask", "dest" };
-
-static cairo_gl_var_type_t
-cairo_gl_operand_get_var_type (cairo_gl_operand_t *operand)
-{
-    switch (operand->type) {
-    default:
-    case CAIRO_GL_OPERAND_COUNT:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_OPERAND_NONE:
-    case CAIRO_GL_OPERAND_CONSTANT:
-	return CAIRO_GL_VAR_NONE;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	return operand->gradient.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
-    case CAIRO_GL_OPERAND_TEXTURE:
-	return operand->texture.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
-    }
-}
-
-static void
-cairo_gl_shader_emit_variable (cairo_output_stream_t *stream,
-			       cairo_gl_var_type_t type,
-			       cairo_gl_tex_t name)
-{
-    switch (type) {
-    default:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_VAR_NONE:
-	break;
-    case CAIRO_GL_VAR_TEXCOORDS:
-	_cairo_output_stream_printf (stream,
-				     "attribute vec4 MultiTexCoord%d;\n"
-				     "varying vec2 %s_texcoords;\n",
-				     name,
-				     operand_names[name]);
-	break;
-    case CAIRO_GL_VAR_TEXGEN:
-	_cairo_output_stream_printf (stream,
-				     "uniform mat3 %s_texgen;\n"
-				     "varying vec2 %s_texcoords;\n",
-				     operand_names[name],
-				     operand_names[name]);
-	break;
-    }
-}
-
-static void
-cairo_gl_shader_emit_vertex (cairo_output_stream_t *stream,
-			     cairo_gl_var_type_t type,
-			     cairo_gl_tex_t name)
-{
-    switch (type) {
-    default:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_VAR_NONE:
-	break;
-    case CAIRO_GL_VAR_TEXCOORDS:
-	_cairo_output_stream_printf (stream,
-				     "    %s_texcoords = MultiTexCoord%d.xy;\n",
-				     operand_names[name], name);
-	break;
-
-    case CAIRO_GL_VAR_TEXGEN:
-	_cairo_output_stream_printf (stream,
-				     "    %s_texcoords = (%s_texgen * Vertex.xyw).xy;\n",
-				     operand_names[name], operand_names[name]);
-	break;
-    }
-}
-
-static void
-cairo_gl_shader_dcl_coverage (cairo_output_stream_t *stream)
-{
-    _cairo_output_stream_printf (stream, "varying float coverage;\n");
-}
-
-static void
-cairo_gl_shader_def_coverage (cairo_output_stream_t *stream)
-{
-    _cairo_output_stream_printf (stream, "    coverage = Color.a;\n");
-}
-
-static cairo_status_t
-cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
-				   cairo_gl_var_type_t mask,
-				   cairo_bool_t use_coverage,
-				   cairo_gl_var_type_t dest,
-				   char **out)
-{
-    cairo_output_stream_t *stream = _cairo_memory_stream_create ();
-    unsigned char *source;
-    unsigned long length;
-    cairo_status_t status;
-
-    cairo_gl_shader_emit_variable (stream, src, CAIRO_GL_TEX_SOURCE);
-    cairo_gl_shader_emit_variable (stream, mask, CAIRO_GL_TEX_MASK);
-    if (use_coverage)
-	cairo_gl_shader_dcl_coverage (stream);
-
-    _cairo_output_stream_printf (stream,
-				 "attribute vec4 Vertex;\n"
-				 "attribute vec4 Color;\n"
-				 "uniform mat4 ModelViewProjectionMatrix;\n"
-				 "void main()\n"
-				 "{\n"
-				 "    gl_Position = ModelViewProjectionMatrix * Vertex;\n");
-
-    cairo_gl_shader_emit_vertex (stream, src, CAIRO_GL_TEX_SOURCE);
-    cairo_gl_shader_emit_vertex (stream, mask, CAIRO_GL_TEX_MASK);
-    if (use_coverage)
-	cairo_gl_shader_def_coverage (stream);
-
-    _cairo_output_stream_write (stream,
-				"}\n\0", 3);
-
-    status = _cairo_memory_stream_destroy (stream, &source, &length);
-    if (unlikely (status))
-	return status;
-
-    *out = (char *) source;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-/*
- * Returns whether an operand needs a special border fade fragment shader
- * to simulate the GL_CLAMP_TO_BORDER wrapping method that is missing in GLES2.
- */
-static cairo_bool_t
-_cairo_gl_shader_needs_border_fade (cairo_gl_operand_t *operand)
-{
-    cairo_extend_t extend =_cairo_gl_operand_get_extend (operand);
-
-    return extend == CAIRO_EXTEND_NONE &&
-	   (operand->type == CAIRO_GL_OPERAND_TEXTURE ||
-	    operand->type == CAIRO_GL_OPERAND_LINEAR_GRADIENT ||
-	    operand->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE ||
-	    operand->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0);
-}
-
-static void
-cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
-			    cairo_gl_context_t *ctx,
-			    cairo_gl_operand_t *op,
-			    cairo_gl_tex_t name)
-{
-    const char *namestr = operand_names[name];
-    const char *rectstr = (ctx->tex_target == GL_TEXTURE_RECTANGLE ? "Rect" : "");
-
-    switch (op->type) {
-    case CAIRO_GL_OPERAND_COUNT:
-    default:
-	ASSERT_NOT_REACHED;
-	break;
-    case CAIRO_GL_OPERAND_NONE:
-	_cairo_output_stream_printf (stream,
-	    "vec4 get_%s()\n"
-	    "{\n"
-	    "    return vec4 (0, 0, 0, 1);\n"
-	    "}\n",
-	    namestr);
-	break;
-    case CAIRO_GL_OPERAND_CONSTANT:
-	_cairo_output_stream_printf (stream,
-	    "uniform vec4 %s_constant;\n"
-	    "vec4 get_%s()\n"
-	    "{\n"
-	    "    return %s_constant;\n"
-	    "}\n",
-	    namestr, namestr, namestr);
-	break;
-    case CAIRO_GL_OPERAND_TEXTURE:
-	_cairo_output_stream_printf (stream,
-	     "uniform sampler2D%s %s_sampler;\n"
-	     "uniform vec2 %s_texdims;\n"
-	     "varying vec2 %s_texcoords;\n"
-	     "vec4 get_%s()\n"
-	     "{\n",
-	     rectstr, namestr, namestr, namestr, namestr);
-	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
-	    _cairo_gl_shader_needs_border_fade (op))
-	{
-	    _cairo_output_stream_printf (stream,
-		"    vec2 border_fade = %s_border_fade (%s_texcoords, %s_texdims);\n"
-		"    vec4 texel = texture2D%s (%s_sampler, %s_texcoords);\n"
-		"    return texel * border_fade.x * border_fade.y;\n"
-		"}\n",
-		namestr, namestr, namestr, rectstr, namestr, namestr);
-	}
-	else
-	{
-	    _cairo_output_stream_printf (stream,
-		"    return texture2D%s (%s_sampler, %s_wrap (%s_texcoords));\n"
-		"}\n",
-		rectstr, namestr, namestr, namestr);
-	}
-	break;
-    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
-	_cairo_output_stream_printf (stream,
-	    "varying vec2 %s_texcoords;\n"
-	    "uniform vec2 %s_texdims;\n"
-	    "uniform sampler2D%s %s_sampler;\n"
-	    "\n"
-	    "vec4 get_%s()\n"
-	    "{\n",
-	    namestr, namestr, rectstr, namestr, namestr);
-	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
-	    _cairo_gl_shader_needs_border_fade (op))
-	{
-	    _cairo_output_stream_printf (stream,
-		"    float border_fade = %s_border_fade (%s_texcoords.x, %s_texdims.x);\n"
-		"    vec4 texel = texture2D%s (%s_sampler, vec2 (%s_texcoords.x, 0.5));\n"
-		"    return texel * border_fade;\n"
-		"}\n",
-		namestr, namestr, namestr, rectstr, namestr, namestr);
-	}
-	else
-	{
-	    _cairo_output_stream_printf (stream,
-		"    return texture2D%s (%s_sampler, %s_wrap (vec2 (%s_texcoords.x, 0.5)));\n"
-		"}\n",
-		rectstr, namestr, namestr, namestr);
-	}
-	break;
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
-	_cairo_output_stream_printf (stream,
-	    "varying vec2 %s_texcoords;\n"
-	    "uniform vec2 %s_texdims;\n"
-	    "uniform sampler2D%s %s_sampler;\n"
-	    "uniform vec3 %s_circle_d;\n"
-	    "uniform float %s_radius_0;\n"
-	    "\n"
-	    "vec4 get_%s()\n"
-	    "{\n"
-	    "    vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
-	    "    \n"
-	    "    float B = dot (pos, %s_circle_d);\n"
-	    "    float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
-	    "    \n"
-	    "    float t = 0.5 * C / B;\n"
-	    "    float is_valid = step (-%s_radius_0, t * %s_circle_d.z);\n",
-	    namestr, namestr, rectstr, namestr, namestr, namestr, namestr,
-	    namestr, namestr, namestr, namestr, namestr);
-	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
-	    _cairo_gl_shader_needs_border_fade (op))
-	{
-	    _cairo_output_stream_printf (stream,
-		"    float border_fade = %s_border_fade (t, %s_texdims.x);\n"
-		"    vec4 texel = texture2D%s (%s_sampler, vec2 (t, 0.5));\n"
-		"    return mix (vec4 (0.0), texel * border_fade, is_valid);\n"
-		"}\n",
-		namestr, namestr, rectstr, namestr);
-	}
-	else
-	{
-	    _cairo_output_stream_printf (stream,
-		"    vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2 (t, 0.5)));\n"
-		"    return mix (vec4 (0.0), texel, is_valid);\n"
-		"}\n",
-		rectstr, namestr, namestr);
-	}
-	break;
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
-	_cairo_output_stream_printf (stream,
-	    "varying vec2 %s_texcoords;\n"
-	    "uniform vec2 %s_texdims;\n"
-	    "uniform sampler2D%s %s_sampler;\n"
-	    "uniform vec3 %s_circle_d;\n"
-	    "uniform float %s_a;\n"
-	    "uniform float %s_radius_0;\n"
-	    "\n"
-	    "vec4 get_%s()\n"
-	    "{\n"
-	    "    vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
-	    "    \n"
-	    "    float B = dot (pos, %s_circle_d);\n"
-	    "    float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
-	    "    \n"
-	    "    float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
-	    "    float sqrtdet = sqrt (abs (det));\n"
-	    "    vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
-	    "    \n"
-	    "    vec2 is_valid = step (vec2 (0.0), t) * step (t, vec2(1.0));\n"
-	    "    float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
-	    "    \n"
-	    "    float upper_t = mix (t.y, t.x, is_valid.x);\n",
-	    namestr, namestr, rectstr, namestr, namestr, namestr, namestr,
-	    namestr, namestr, namestr, namestr, namestr, namestr);
-	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
-	    _cairo_gl_shader_needs_border_fade (op))
-	{
-	    _cairo_output_stream_printf (stream,
-		"    float border_fade = %s_border_fade (upper_t, %s_texdims.x);\n"
-		"    vec4 texel = texture2D%s (%s_sampler, vec2 (upper_t, 0.5));\n"
-		"    return mix (vec4 (0.0), texel * border_fade, has_color);\n"
-		"}\n",
-		namestr, namestr, rectstr, namestr);
-	}
-	else
-	{
-	    _cairo_output_stream_printf (stream,
-		"    vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
-		"    return mix (vec4 (0.0), texel, has_color);\n"
-		"}\n",
-		rectstr, namestr, namestr);
-	}
-	break;
-    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-	_cairo_output_stream_printf (stream,
-	    "varying vec2 %s_texcoords;\n"
-	    "uniform sampler2D%s %s_sampler;\n"
-	    "uniform vec3 %s_circle_d;\n"
-	    "uniform float %s_a;\n"
-	    "uniform float %s_radius_0;\n"
-	    "\n"
-	    "vec4 get_%s()\n"
-	    "{\n"
-	    "    vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
-	    "    \n"
-	    "    float B = dot (pos, %s_circle_d);\n"
-	    "    float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
-	    "    \n"
-	    "    float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
-	    "    float sqrtdet = sqrt (abs (det));\n"
-	    "    vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
-	    "    \n"
-	    "    vec2 is_valid = step (vec2 (-%s_radius_0), t * %s_circle_d.z);\n"
-	    "    float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
-	    "    \n"
-	    "    float upper_t = mix (t.y, t.x, is_valid.x);\n"
-	    "    vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
-	    "    return mix (vec4 (0.0), texel, has_color);\n"
-	    "}\n",
-	    namestr, rectstr, namestr, namestr, namestr, namestr,
-	    namestr, namestr, namestr, namestr, namestr,
-	    namestr, namestr, namestr, rectstr, namestr, namestr);
-	break;
-    }
-}
-
-/*
- * Emits the border fade functions used by an operand.
- *
- * If bilinear filtering is used, the emitted function performs a linear
- * fade to transparency effect in the intervals [-1/2n, 1/2n] and
- * [1 - 1/2n, 1 + 1/2n] (n: texture size).
- *
- * If nearest filtering is used, the emitted function just returns
- * 0.0 for all values outside [0, 1).
- */
-static void
-_cairo_gl_shader_emit_border_fade (cairo_output_stream_t *stream,
-				   cairo_gl_operand_t *operand,
-				   cairo_gl_tex_t name)
-{
-    const char *namestr = operand_names[name];
-    GLint gl_filter = _cairo_gl_operand_get_gl_filter (operand);
-
-    /* 2D version */
-    _cairo_output_stream_printf (stream,
-	"vec2 %s_border_fade (vec2 coords, vec2 dims)\n"
-	"{\n",
-	namestr);
-
-    if (gl_filter == GL_LINEAR)
-	_cairo_output_stream_printf (stream,
-	    "    return clamp(-abs(dims * (coords - 0.5)) + (dims + vec2(1.0)) * 0.5, 0.0, 1.0);\n");
-    else
-	_cairo_output_stream_printf (stream,
-	    "    bvec2 in_tex1 = greaterThanEqual (coords, vec2 (0.0));\n"
-	    "    bvec2 in_tex2 = lessThan (coords, vec2 (1.0));\n"
-	    "    return vec2 (float (all (in_tex1) && all (in_tex2)));\n");
-
-    _cairo_output_stream_printf (stream, "}\n");
-
-    /* 1D version */
-    _cairo_output_stream_printf (stream,
-	"float %s_border_fade (float x, float dim)\n"
-	"{\n",
-	namestr);
-    if (gl_filter == GL_LINEAR)
-	_cairo_output_stream_printf (stream,
-	    "    return clamp(-abs(dim * (x - 0.5)) + (dim + 1.0) * 0.5, 0.0, 1.0);\n");
-    else
-	_cairo_output_stream_printf (stream,
-	    "    bool in_tex = x >= 0.0 && x < 1.0;\n"
-	    "    return float (in_tex);\n");
-
-    _cairo_output_stream_printf (stream, "}\n");
-}
-
-/*
- * Emits the wrap function used by an operand.
- *
- * In OpenGL ES 2.0, repeat wrap modes (GL_REPEAT and GL_MIRRORED REPEAT) are
- * only available for NPOT textures if the GL_OES_texture_npot is supported.
- * If GL_OES_texture_npot is not supported, we need to implement the wrapping
- * functionality in the shader.
- */
-static void
-_cairo_gl_shader_emit_wrap (cairo_gl_context_t *ctx,
-			    cairo_output_stream_t *stream,
-			    cairo_gl_operand_t *operand,
-			    cairo_gl_tex_t name)
-{
-    const char *namestr = operand_names[name];
-    cairo_extend_t extend = _cairo_gl_operand_get_extend (operand);
-
-    _cairo_output_stream_printf (stream,
-	"vec2 %s_wrap(vec2 coords)\n"
-	"{\n",
-	namestr);
-
-    if (! ctx->has_npot_repeat &&
-	(extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT))
-    {
-	if (extend == CAIRO_EXTEND_REPEAT) {
-	    _cairo_output_stream_printf (stream,
-		"    return fract(coords);\n");
-	} else { /* CAIRO_EXTEND_REFLECT */
-	    _cairo_output_stream_printf (stream,
-		"    return mix(fract(coords), 1.0 - fract(coords), floor(mod(coords, 2.0)));\n");
-	}
-    }
-    else
-    {
-	_cairo_output_stream_printf (stream, "    return coords;\n");
-    }
-
-    _cairo_output_stream_printf (stream, "}\n");
-}
-
-static cairo_status_t
-cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
-				     cairo_gl_shader_in_t in,
-				     cairo_gl_operand_t *src,
-				     cairo_gl_operand_t *mask,
-				     cairo_bool_t use_coverage,
-				     cairo_gl_operand_type_t dest_type,
-				     char **out)
-{
-    cairo_output_stream_t *stream = _cairo_memory_stream_create ();
-    unsigned char *source;
-    unsigned long length;
-    cairo_status_t status;
-    const char *coverage_str;
-
-    _cairo_output_stream_printf (stream,
-	"#ifdef GL_ES\n"
-	"precision mediump float;\n"
-	"#endif\n");
-
-    _cairo_gl_shader_emit_wrap (ctx, stream, src, CAIRO_GL_TEX_SOURCE);
-    _cairo_gl_shader_emit_wrap (ctx, stream, mask, CAIRO_GL_TEX_MASK);
-
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
-	if (_cairo_gl_shader_needs_border_fade (src))
-	    _cairo_gl_shader_emit_border_fade (stream, src, CAIRO_GL_TEX_SOURCE);
-	if (_cairo_gl_shader_needs_border_fade (mask))
-	    _cairo_gl_shader_emit_border_fade (stream, mask, CAIRO_GL_TEX_MASK);
-    }
-
-    cairo_gl_shader_emit_color (stream, ctx, src, CAIRO_GL_TEX_SOURCE);
-    cairo_gl_shader_emit_color (stream, ctx, mask, CAIRO_GL_TEX_MASK);
-
-    coverage_str = "";
-    if (use_coverage) {
-	_cairo_output_stream_printf (stream, "varying float coverage;\n");
-	coverage_str = " * coverage";
-    }
-
-    _cairo_output_stream_printf (stream,
-	"void main()\n"
-	"{\n");
-    switch (in) {
-    case CAIRO_GL_SHADER_IN_COUNT:
-    default:
-	ASSERT_NOT_REACHED;
-    case CAIRO_GL_SHADER_IN_NORMAL:
-	_cairo_output_stream_printf (stream,
-	    "    gl_FragColor = get_source() * get_mask().a%s;\n",
-	    coverage_str);
-	break;
-    case CAIRO_GL_SHADER_IN_CA_SOURCE:
-	_cairo_output_stream_printf (stream,
-	    "    gl_FragColor = get_source() * get_mask()%s;\n",
-	    coverage_str);
-	break;
-    case CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA:
-	_cairo_output_stream_printf (stream,
-	    "    gl_FragColor = get_source().a * get_mask()%s;\n",
-	    coverage_str);
-	break;
-    }
-
-    _cairo_output_stream_write (stream,
-				"}\n\0", 3);
-
-    status = _cairo_memory_stream_destroy (stream, &source, &length);
-    if (unlikely (status))
-	return status;
-
-    *out = (char *) source;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-compile_shader (cairo_gl_context_t *ctx,
-		GLuint *shader,
-		GLenum type,
-		const char *source)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    GLint success, log_size, num_chars;
-    char *log;
-
-    *shader = dispatch->CreateShader (type);
-    dispatch->ShaderSource (*shader, 1, &source, 0);
-    dispatch->CompileShader (*shader);
-    dispatch->GetShaderiv (*shader, GL_COMPILE_STATUS, &success);
-
-    if (success)
-	return;
-
-    dispatch->GetShaderiv (*shader, GL_INFO_LOG_LENGTH, &log_size);
-    if (log_size < 0) {
-	printf ("OpenGL shader compilation failed.\n");
-	ASSERT_NOT_REACHED;
-	return;
-    }
-
-    log = _cairo_malloc (log_size + 1);
-    dispatch->GetShaderInfoLog (*shader, log_size, &num_chars, log);
-    log[num_chars] = '\0';
-
-    printf ("OpenGL shader compilation failed.  Shader:\n%s\n", source);
-    printf ("OpenGL compilation log:\n%s\n", log);
-
-    free (log);
-    ASSERT_NOT_REACHED;
-}
-
-static void
-link_shader_program (cairo_gl_context_t *ctx,
-		     GLuint *program,
-		     GLuint vert,
-		     GLuint frag)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    GLint success, log_size, num_chars;
-    char *log;
-
-    *program = dispatch->CreateProgram ();
-    dispatch->AttachShader (*program, vert);
-    dispatch->AttachShader (*program, frag);
-
-    dispatch->BindAttribLocation (*program, CAIRO_GL_VERTEX_ATTRIB_INDEX,
-				  "Vertex");
-    dispatch->BindAttribLocation (*program, CAIRO_GL_COLOR_ATTRIB_INDEX,
-				  "Color");
-    dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD0_ATTRIB_INDEX,
-				  "MultiTexCoord0");
-    dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD1_ATTRIB_INDEX,
-				  "MultiTexCoord1");
-
-    dispatch->LinkProgram (*program);
-    dispatch->GetProgramiv (*program, GL_LINK_STATUS, &success);
-    if (success)
-	return;
-
-    dispatch->GetProgramiv (*program, GL_INFO_LOG_LENGTH, &log_size);
-    if (log_size < 0) {
-	printf ("OpenGL shader link failed.\n");
-	ASSERT_NOT_REACHED;
-	return;
-    }
-
-    log = _cairo_malloc (log_size + 1);
-    dispatch->GetProgramInfoLog (*program, log_size, &num_chars, log);
-    log[num_chars] = '\0';
-
-    printf ("OpenGL shader link failed:\n%s\n", log);
-    free (log);
-    ASSERT_NOT_REACHED;
-}
-
-static GLint
-_cairo_gl_get_op_uniform_location(cairo_gl_context_t *ctx,
-				  cairo_gl_shader_t  *shader,
-				  cairo_gl_tex_t      tex_unit,
-				  const char         *suffix)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    char uniform_name[100];
-    const char *unit_name[2] = { "source", "mask" };
-
-    snprintf (uniform_name, sizeof (uniform_name), "%s_%s",
-	      unit_name[tex_unit], suffix);
-
-    return dispatch->GetUniformLocation (shader->program, uniform_name);
-}
-
-static cairo_status_t
-_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
-				   cairo_gl_shader_t *shader,
-				   cairo_gl_var_type_t src,
-				   cairo_gl_var_type_t mask,
-				   cairo_bool_t use_coverage,
-				   const char *fragment_text)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    unsigned int vertex_shader;
-    cairo_status_t status;
-    int i;
-
-    assert (shader->program == 0);
-
-    vertex_shader = cairo_gl_var_type_hash (src, mask, use_coverage,
-					    CAIRO_GL_VAR_NONE);
-    if (ctx->vertex_shaders[vertex_shader] == 0) {
-	char *source;
-
-	status = cairo_gl_shader_get_vertex_source (src,
-						    mask,
-						    use_coverage,
-						    CAIRO_GL_VAR_NONE,
-						    &source);
-	if (unlikely (status))
-	    goto FAILURE;
-
-	compile_shader (ctx, &ctx->vertex_shaders[vertex_shader],
-			GL_VERTEX_SHADER, source);
-	free (source);
-    }
-
-    compile_shader (ctx, &shader->fragment_shader,
-		    GL_FRAGMENT_SHADER, fragment_text);
-
-    link_shader_program (ctx, &shader->program,
-			 ctx->vertex_shaders[vertex_shader],
-			 shader->fragment_shader);
-
-    shader->mvp_location =
-	dispatch->GetUniformLocation (shader->program,
-				      "ModelViewProjectionMatrix");
-
-    for (i = 0; i < 2; i++) {
-	shader->constant_location[i] =
-	    _cairo_gl_get_op_uniform_location (ctx, shader, i, "constant");
-	shader->a_location[i] =
-	    _cairo_gl_get_op_uniform_location (ctx, shader, i, "a");
-	shader->circle_d_location[i] =
-	    _cairo_gl_get_op_uniform_location (ctx, shader, i, "circle_d");
-	shader->radius_0_location[i] =
-	    _cairo_gl_get_op_uniform_location (ctx, shader, i, "radius_0");
-	shader->texdims_location[i] =
-	    _cairo_gl_get_op_uniform_location (ctx, shader, i, "texdims");
-	shader->texgen_location[i] =
-	    _cairo_gl_get_op_uniform_location (ctx, shader, i, "texgen");
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-
- FAILURE:
-    _cairo_gl_shader_fini (ctx, shader);
-    shader->fragment_shader = 0;
-    shader->program = 0;
-
-    return status;
-}
-
-/* We always bind the source to texture unit 0 if present, and mask to
- * texture unit 1 if present, so we can just initialize these once at
- * compile time.
- */
-static cairo_status_t
-_cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx,
-			       cairo_gl_shader_t *shader)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    GLint location;
-    GLint saved_program;
-
-    /* We have to save/restore the current program because we might be
-     * asked for a different program while a shader is bound.  This shouldn't
-     * be a performance issue, since this is only called once per compile.
-     */
-    glGetIntegerv (GL_CURRENT_PROGRAM, &saved_program);
-    dispatch->UseProgram (shader->program);
-
-    location = dispatch->GetUniformLocation (shader->program, "source_sampler");
-    if (location != -1) {
-	dispatch->Uniform1i (location, CAIRO_GL_TEX_SOURCE);
-    }
-
-    location = dispatch->GetUniformLocation (shader->program, "mask_sampler");
-    if (location != -1) {
-	dispatch->Uniform1i (location, CAIRO_GL_TEX_MASK);
-    }
-    if(_cairo_gl_get_error()) return CAIRO_STATUS_DEVICE_ERROR;
-    dispatch->UseProgram (saved_program);
-    /* Pop and ignore a possible gl-error when restoring the previous program.
-     * It may be that being selected in the gl-context was the last reference
-     * to the shader.
-     */
-    _cairo_gl_get_error(); 
-    return CAIRO_STATUS_SUCCESS;
-}
-
-void
-_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
-			     GLint location,
-			     float value)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    assert (location != -1);
-    dispatch->Uniform1f (location, value);
-}
-
-void
-_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
-			    GLint location,
-			    float value0,
-			    float value1)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    assert (location != -1);
-    dispatch->Uniform2f (location, value0, value1);
-}
-
-void
-_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
-			    GLint location,
-			    float value0,
-			    float value1,
-			    float value2)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    assert (location != -1);
-    dispatch->Uniform3f (location, value0, value1, value2);
-}
-
-void
-_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
-			    GLint location,
-			    float value0, float value1,
-			    float value2, float value3)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    assert (location != -1);
-    dispatch->Uniform4f (location, value0, value1, value2, value3);
-}
-
-void
-_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
-			      GLint location,
-			      const cairo_matrix_t* m)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    float gl_m[9] = {
-	m->xx, m->yx, 0,
-	m->xy, m->yy, 0,
-	m->x0, m->y0, 1
-    };
-    assert (location != -1);
-    dispatch->UniformMatrix3fv (location, 1, GL_FALSE, gl_m);
-}
-
-void
-_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
-				GLint location, GLfloat* gl_m)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    assert (location != -1);
-    dispatch->UniformMatrix4fv (location, 1, GL_FALSE, gl_m);
-}
-
-void
-_cairo_gl_set_shader (cairo_gl_context_t *ctx,
-		      cairo_gl_shader_t *shader)
-{
-    if (ctx->current_shader == shader)
-	return;
-
-    if (shader)
-	ctx->dispatch.UseProgram (shader->program);
-    else
-	ctx->dispatch.UseProgram (0);
-
-    ctx->current_shader = shader;
-}
-
-cairo_status_t
-_cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
-			      cairo_gl_operand_t *source,
-			      cairo_gl_operand_t *mask,
-			      cairo_bool_t use_coverage,
-			      cairo_gl_shader_in_t in,
-			      cairo_gl_shader_t **shader)
-{
-    cairo_shader_cache_entry_t lookup, *entry;
-    char *fs_source;
-    cairo_status_t status;
-
-    lookup.ctx = ctx;
-
-    lookup.vertex = cairo_gl_var_type_hash (cairo_gl_operand_get_var_type (source),
-					    cairo_gl_operand_get_var_type (mask),
-					    use_coverage,
-					    CAIRO_GL_VAR_NONE);
-
-    lookup.src = source->type;
-    lookup.mask = mask->type;
-    lookup.dest = CAIRO_GL_OPERAND_NONE;
-    lookup.use_coverage = use_coverage;
-    lookup.in = in;
-    lookup.src_gl_filter = _cairo_gl_operand_get_gl_filter (source);
-    lookup.src_border_fade = _cairo_gl_shader_needs_border_fade (source);
-    lookup.src_extend = _cairo_gl_operand_get_extend (source);
-    lookup.mask_gl_filter = _cairo_gl_operand_get_gl_filter (mask);
-    lookup.mask_border_fade = _cairo_gl_shader_needs_border_fade (mask);
-    lookup.mask_extend = _cairo_gl_operand_get_extend (mask);
-    lookup.base.hash = _cairo_gl_shader_cache_hash (&lookup);
-    lookup.base.size = 1;
-
-    entry = _cairo_cache_lookup (&ctx->shaders, &lookup.base);
-    if (entry) {
-	assert (entry->shader.program);
-	*shader = &entry->shader;
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    status = cairo_gl_shader_get_fragment_source (ctx,
-						  in,
-						  source,
-						  mask,
-						  use_coverage,
-						  CAIRO_GL_OPERAND_NONE,
-						  &fs_source);
-    if (unlikely (status))
-	return status;
-
-    entry = _cairo_malloc (sizeof (cairo_shader_cache_entry_t));
-    if (unlikely (entry == NULL)) {
-	free (fs_source);
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    memcpy (entry, &lookup, sizeof (cairo_shader_cache_entry_t));
-
-    entry->ctx = ctx;
-    _cairo_gl_shader_init (&entry->shader);
-    status = _cairo_gl_shader_compile_and_link (ctx,
-						&entry->shader,
-						cairo_gl_operand_get_var_type (source),
-						cairo_gl_operand_get_var_type (mask),
-						use_coverage,
-						fs_source);
-    free (fs_source);
-
-    if (unlikely (status)) {
-	free (entry);
-	return status;
-    }
-
-    status = _cairo_gl_shader_set_samplers (ctx, &entry->shader);
-    if (unlikely (status)) {
-	_cairo_gl_shader_fini (ctx, &entry->shader);
-	free (entry);
-	return status;
-    }
-
-    status = _cairo_cache_insert (&ctx->shaders, &entry->base);
-    if (unlikely (status)) {
-	_cairo_gl_shader_fini (ctx, &entry->shader);
-	free (entry);
-	return status;
-    }
-
-    *shader = &entry->shader;
-
-    return CAIRO_STATUS_SUCCESS;
-}
diff --git a/src/cairo-gl-source.c b/src/cairo-gl-source.c
deleted file mode 100644
index 7e0ee4a82..000000000
--- a/src/cairo-gl-source.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2011 Intel Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Chris Wilson <chris at chris-wilson.co.uk>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-surface-backend-private.h"
-
-static cairo_status_t
-_cairo_gl_source_finish (void *abstract_surface)
-{
-    cairo_gl_source_t *source = abstract_surface;
-
-    _cairo_gl_operand_destroy (&source->operand);
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static const cairo_surface_backend_t cairo_gl_source_backend = {
-    CAIRO_SURFACE_TYPE_GL,
-    _cairo_gl_source_finish,
-    NULL, /* read-only wrapper */
-};
-
-cairo_surface_t *
-_cairo_gl_pattern_to_source (cairo_surface_t *dst,
-			     const cairo_pattern_t *pattern,
-			     cairo_bool_t is_mask,
-			     const cairo_rectangle_int_t *extents,
-			     const cairo_rectangle_int_t *sample,
-			     int *src_x, int *src_y)
-{
-    cairo_gl_source_t *source;
-    cairo_int_status_t status;
-
-    TRACE ((stderr, "%s\n", __FUNCTION__));
-    if (pattern == NULL)
-	return _cairo_gl_white_source ();
-
-    source = _cairo_malloc (sizeof (*source));
-    if (unlikely (source == NULL))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _cairo_surface_init (&source->base,
-			 &cairo_gl_source_backend,
-			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA,
-			 FALSE); /* is_vector */
-
-    *src_x = *src_y = 0;
-    status = _cairo_gl_operand_init (&source->operand, pattern,
-				     (cairo_gl_surface_t *)dst,
-				     sample, extents,
-				     FALSE);
-    if (unlikely (status)) {
-	cairo_surface_destroy (&source->base);
-	return _cairo_surface_create_in_error (status);
-    }
-
-    return &source->base;
-}
-
-cairo_surface_t *
-_cairo_gl_white_source (void)
-{
-    cairo_gl_source_t *source;
-
-    source = _cairo_malloc (sizeof (*source));
-    if (unlikely (source == NULL))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _cairo_surface_init (&source->base,
-			 &cairo_gl_source_backend,
-			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA,
-			 FALSE); /* is_vector */
-
-    _cairo_gl_solid_operand_init (&source->operand, CAIRO_COLOR_WHITE);
-
-    return &source->base;
-}
diff --git a/src/cairo-gl-spans-compositor.c b/src/cairo-gl-spans-compositor.c
deleted file mode 100644
index 0a4538a04..000000000
--- a/src/cairo-gl-spans-compositor.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- * Copyright © 2011 Intel Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-composite-rectangles-private.h"
-#include "cairo-compositor-private.h"
-#include "cairo-default-context-private.h"
-#include "cairo-error-private.h"
-#include "cairo-image-surface-private.h"
-#include "cairo-spans-compositor-private.h"
-#include "cairo-surface-backend-private.h"
-
-typedef struct _cairo_gl_span_renderer {
-    cairo_span_renderer_t base;
-
-    cairo_gl_composite_t setup;
-    double opacity;
-
-    cairo_gl_emit_span_t emit;
-
-    int xmin, xmax;
-    int ymin, ymax;
-
-    cairo_gl_context_t *ctx;
-} cairo_gl_span_renderer_t;
-
-static cairo_status_t
-_cairo_gl_bounded_opaque_spans (void *abstract_renderer,
-				int y, int height,
-				const cairo_half_open_span_t *spans,
-				unsigned num_spans)
-{
-    cairo_gl_span_renderer_t *r = abstract_renderer;
-    cairo_gl_emit_span_t emit = r->emit;
-
-    if (num_spans == 0)
-	return CAIRO_STATUS_SUCCESS;
-
-    do {
-	if (spans[0].coverage) {
-	    emit (r->ctx,
-		  spans[0].x, y,
-		  spans[1].x, y + height,
-		  spans[0].coverage);
-	}
-
-	spans++;
-    } while (--num_spans > 1);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_bounded_spans (void *abstract_renderer,
-			 int y, int height,
-			 const cairo_half_open_span_t *spans,
-			 unsigned num_spans)
-{
-    cairo_gl_span_renderer_t *r = abstract_renderer;
-    cairo_gl_emit_span_t emit = r->emit;
-
-    if (num_spans == 0)
-	return CAIRO_STATUS_SUCCESS;
-
-    do {
-	if (spans[0].coverage) {
-	    emit (r->ctx,
-		  spans[0].x, y,
-		  spans[1].x, y + height,
-		  r->opacity * spans[0].coverage);
-	}
-
-	spans++;
-    } while (--num_spans > 1);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_unbounded_spans (void *abstract_renderer,
-			   int y, int height,
-			   const cairo_half_open_span_t *spans,
-			   unsigned num_spans)
-{
-    cairo_gl_span_renderer_t *r = abstract_renderer;
-    cairo_gl_emit_span_t emit = r->emit;
-
-    if (y > r->ymin) {
-	emit (r->ctx,
-	      r->xmin, r->ymin,
-	      r->xmax, y,
-	      0);
-    }
-
-    if (num_spans == 0) {
-	emit (r->ctx,
-	      r->xmin, y,
-	      r->xmax, y + height,
-	      0);
-    } else {
-	if (spans[0].x != r->xmin) {
-	    emit (r->ctx,
-		  r->xmin, y,
-		  spans[0].x,     y + height,
-		  0);
-	}
-
-	do {
-	    emit (r->ctx,
-		  spans[0].x, y,
-		  spans[1].x, y + height,
-		  r->opacity * spans[0].coverage);
-	    spans++;
-	} while (--num_spans > 1);
-
-	if (spans[0].x != r->xmax) {
-	    emit (r->ctx,
-		  spans[0].x,     y,
-		  r->xmax, y + height,
-		  0);
-	}
-    }
-
-    r->ymin = y + height;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-/* XXX */
-static cairo_status_t
-_cairo_gl_clipped_spans (void *abstract_renderer,
-			   int y, int height,
-			   const cairo_half_open_span_t *spans,
-			   unsigned num_spans)
-{
-    cairo_gl_span_renderer_t *r = abstract_renderer;
-    cairo_gl_emit_span_t emit = r->emit;
-
-    if (y > r->ymin) {
-	emit (r->ctx,
-	      r->xmin, r->ymin,
-	      r->xmax, y,
-	      0);
-    }
-
-    if (num_spans == 0) {
-	emit (r->ctx,
-	      r->xmin, y,
-	      r->xmax, y + height,
-	      0);
-    } else {
-	if (spans[0].x != r->xmin) {
-	    emit (r->ctx,
-		  r->xmin, y,
-		  spans[0].x,     y + height,
-		  0);
-	}
-
-	do {
-	    emit (r->ctx,
-		  spans[0].x, y,
-		  spans[1].x, y + height,
-		  r->opacity * spans[0].coverage);
-	    spans++;
-	} while (--num_spans > 1);
-
-	if (spans[0].x != r->xmax) {
-	    emit (r->ctx,
-		  spans[0].x,     y,
-		  r->xmax, y + height,
-		  0);
-	}
-    }
-
-    r->ymin = y + height;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_finish_unbounded_spans (void *abstract_renderer)
-{
-    cairo_gl_span_renderer_t *r = abstract_renderer;
-    cairo_gl_emit_span_t emit = r->emit;
-
-    if (r->ymax > r->ymin) {
-	emit (r->ctx,
-	      r->xmin, r->ymin,
-	      r->xmax, r->ymax,
-	      0);
-    }
-
-    return _cairo_gl_context_release (r->ctx, CAIRO_STATUS_SUCCESS);
-}
-
-static cairo_status_t
-_cairo_gl_finish_bounded_spans (void *abstract_renderer)
-{
-    cairo_gl_span_renderer_t *r = abstract_renderer;
-
-    return _cairo_gl_context_release (r->ctx, CAIRO_STATUS_SUCCESS);
-}
-
-static void
-emit_aligned_boxes (cairo_gl_context_t *ctx,
-		    const cairo_boxes_t *boxes)
-{
-    const struct _cairo_boxes_chunk *chunk;
-    cairo_gl_emit_rect_t emit = _cairo_gl_context_choose_emit_rect (ctx);
-    int i;
-
-    TRACE ((stderr, "%s: num_boxes=%d\n", __FUNCTION__, boxes->num_boxes));
-    for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
-	for (i = 0; i < chunk->count; i++) {
-	    int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
-	    int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
-	    int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
-	    int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
-	    emit (ctx, x1, y1, x2, y2);
-	}
-    }
-}
-
-static cairo_int_status_t
-fill_boxes (void		*_dst,
-	    cairo_operator_t	 op,
-	    const cairo_color_t	*color,
-	    cairo_boxes_t	*boxes)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-
-    TRACE ((stderr, "%s\n", __FUNCTION__));
-    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-   _cairo_gl_composite_set_solid_source (&setup, color);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    emit_aligned_boxes (ctx, boxes);
-    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-    return status;
-}
-
-static cairo_int_status_t
-draw_image_boxes (void *_dst,
-		  cairo_image_surface_t *image,
-		  cairo_boxes_t *boxes,
-		  int dx, int dy)
-{
-    cairo_gl_surface_t *dst = _dst;
-    struct _cairo_boxes_chunk *chunk;
-    int i;
-
-    for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
-	for (i = 0; i < chunk->count; i++) {
-	    cairo_box_t *b = &chunk->base[i];
-	    int x = _cairo_fixed_integer_part (b->p1.x);
-	    int y = _cairo_fixed_integer_part (b->p1.y);
-	    int w = _cairo_fixed_integer_part (b->p2.x) - x;
-	    int h = _cairo_fixed_integer_part (b->p2.y) - y;
-	    cairo_status_t status;
-
-	    status = _cairo_gl_surface_draw_image (dst, image,
-						   x + dx, y + dy,
-						   w, h,
-						   x, y, TRUE);
-	    if (unlikely (status))
-		return status;
-	}
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t copy_boxes (void *_dst,
-				      cairo_surface_t *_src,
-				      cairo_boxes_t *boxes,
-				      const cairo_rectangle_int_t *extents,
-				      int dx, int dy)
-{
-    cairo_gl_surface_t *dst = _dst;
-    cairo_gl_surface_t *src = (cairo_gl_surface_t *)_src;
-    cairo_gl_composite_t setup;
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-
-    TRACE ((stderr, "%s\n", __FUNCTION__));
-    if (! _cairo_gl_surface_is_texture (src))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (src->base.device != dst->base.device)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE, _dst, FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-    _cairo_gl_composite_set_source_operand (&setup, &src->operand);
-    _cairo_gl_operand_translate (&setup.src, -dx, -dy);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    emit_aligned_boxes (ctx, boxes);
-    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-    return status;
-}
-
-static cairo_int_status_t
-composite_boxes (void			*_dst,
-		 cairo_operator_t	op,
-		 cairo_surface_t	*abstract_src,
-		 cairo_surface_t	*abstract_mask,
-		 int			src_x,
-		 int			src_y,
-		 int			mask_x,
-		 int			mask_y,
-		 int			dst_x,
-		 int			dst_y,
-		 cairo_boxes_t		*boxes,
-		 const cairo_rectangle_int_t  *extents)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-    cairo_gl_operand_t tmp_operand;
-    cairo_gl_operand_t *src_operand;
-
-    TRACE ((stderr, "%s mask=(%d,%d), dst=(%d, %d)\n", __FUNCTION__,
-	    mask_x, mask_y, dst_x, dst_y));
-
-    if (abstract_mask) {
-	if (op == CAIRO_OPERATOR_CLEAR) {
-	    _cairo_gl_solid_operand_init (&tmp_operand, CAIRO_COLOR_WHITE);
-	    src_operand = &tmp_operand;
-	    op = CAIRO_OPERATOR_DEST_OUT;
-	} else if (op == CAIRO_OPERATOR_SOURCE) {
-	    /* requires a LERP in the shader between dest and source */
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	} else
-	    src_operand = source_to_operand (abstract_src);
-    } else
-	src_operand = source_to_operand (abstract_src);
-
-    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-    _cairo_gl_composite_set_source_operand (&setup,
-					    src_operand);
-    _cairo_gl_operand_translate (&setup.src, -src_x, -src_y);
-
-    _cairo_gl_composite_set_mask_operand (&setup,
-					  source_to_operand (abstract_mask));
-    _cairo_gl_operand_translate (&setup.mask, -mask_x, -mask_y);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    emit_aligned_boxes (ctx, boxes);
-    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-    if (src_operand == &tmp_operand)
-	_cairo_gl_operand_destroy (&tmp_operand);
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t	*_r,
-			      const cairo_composite_rectangles_t *composite,
-			      cairo_antialias_t			 antialias,
-			      cairo_bool_t			 needs_clip)
-{
-    cairo_gl_span_renderer_t *r = (cairo_gl_span_renderer_t *)_r;
-    const cairo_pattern_t *source = &composite->source_pattern.base;
-    cairo_operator_t op = composite->op;
-    cairo_int_status_t status;
-
-    if (op == CAIRO_OPERATOR_SOURCE) {
-	if (! _cairo_pattern_is_opaque (&composite->source_pattern.base,
-					&composite->source_sample_area))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	op = CAIRO_OPERATOR_OVER;
-    }
-
-    /* XXX earlier! */
-    if (op == CAIRO_OPERATOR_CLEAR) {
-	source = &_cairo_pattern_white.base;
-	op = CAIRO_OPERATOR_DEST_OUT;
-    } else if (composite->surface->is_clear &&
-	       (op == CAIRO_OPERATOR_SOURCE ||
-		op == CAIRO_OPERATOR_OVER ||
-		op == CAIRO_OPERATOR_ADD)) {
-	op = CAIRO_OPERATOR_SOURCE;
-    } else if (op == CAIRO_OPERATOR_SOURCE) {
-	/* no lerp equivalent without some major PITA */
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    } else if (! _cairo_gl_operator_is_supported (op))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    status = _cairo_gl_composite_init (&r->setup,
-				       op, (cairo_gl_surface_t *)composite->surface,
-				       FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-    status = _cairo_gl_composite_set_source (&r->setup, source,
-					     &composite->source_sample_area,
-					     &composite->unbounded,
-					     TRUE);
-    if (unlikely (status))
-	goto FAIL;
-
-    r->opacity = 1.0;
-    if (composite->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID) {
-	r->opacity = composite->mask_pattern.solid.color.alpha;
-    } else {
-	status = _cairo_gl_composite_set_mask (&r->setup,
-					       &composite->mask_pattern.base,
-					       &composite->mask_sample_area,
-					       &composite->unbounded,
-					       TRUE);
-	if (unlikely (status))
-	    goto FAIL;
-    }
-
-    _cairo_gl_composite_set_spans (&r->setup);
-
-    status = _cairo_gl_composite_begin (&r->setup, &r->ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    r->emit = _cairo_gl_context_choose_emit_span (r->ctx);
-    if (composite->is_bounded) {
-	if (r->opacity == 1.)
-	    r->base.render_rows = _cairo_gl_bounded_opaque_spans;
-	else
-	    r->base.render_rows = _cairo_gl_bounded_spans;
-	r->base.finish = _cairo_gl_finish_bounded_spans;
-    } else {
-	if (needs_clip)
-	    r->base.render_rows = _cairo_gl_clipped_spans;
-	else
-	    r->base.render_rows = _cairo_gl_unbounded_spans;
-	r->base.finish = _cairo_gl_finish_unbounded_spans;
-	r->xmin = composite->unbounded.x;
-	r->xmax = composite->unbounded.x + composite->unbounded.width;
-	r->ymin = composite->unbounded.y;
-	r->ymax = composite->unbounded.y + composite->unbounded.height;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-
-FAIL:
-    return status;
-}
-
-static void
-_cairo_gl_span_renderer_fini (cairo_abstract_span_renderer_t *_r,
-			      cairo_int_status_t status)
-{
-    cairo_gl_span_renderer_t *r = (cairo_gl_span_renderer_t *) _r;
-
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-	return;
-
-    if (status == CAIRO_INT_STATUS_SUCCESS)
-	r->base.finish (r);
-
-    _cairo_gl_composite_fini (&r->setup);
-}
-
-const cairo_compositor_t *
-_cairo_gl_span_compositor_get (void)
-{
-    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
-    static cairo_spans_compositor_t spans;
-    static cairo_compositor_t shape;
-
-    if (_cairo_atomic_init_once_enter(&once)) {
-	/* The fallback to traps here is essentially just for glyphs... */
-	_cairo_shape_mask_compositor_init (&shape,
-					   _cairo_gl_traps_compositor_get());
-	shape.glyphs = NULL;
-
-	_cairo_spans_compositor_init (&spans, &shape);
-	spans.fill_boxes = fill_boxes;
-	spans.draw_image_boxes = draw_image_boxes;
-	spans.copy_boxes = copy_boxes;
-	//spans.check_composite_boxes = check_composite_boxes;
-	spans.pattern_to_surface = _cairo_gl_pattern_to_source;
-	spans.composite_boxes = composite_boxes;
-	//spans.check_span_renderer = check_span_renderer;
-	spans.renderer_init = _cairo_gl_span_renderer_init;
-	spans.renderer_fini = _cairo_gl_span_renderer_fini;
-
-	_cairo_atomic_init_once_leave(&once);
-    }
-
-    return &spans.base;
-}
diff --git a/src/cairo-gl-surface-legacy.c b/src/cairo-gl-surface-legacy.c
deleted file mode 100644
index 87dca2f03..000000000
--- a/src/cairo-gl-surface-legacy.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- */
-
-#include "cairoint.h"
-
-#include "cairo-composite-rectangles-private.h"
-#include "cairo-default-context-private.h"
-#include "cairo-error-private.h"
-#include "cairo-gl-private.h"
-#include "cairo-image-surface-inline.h"
-
-cairo_status_t
-_cairo_gl_surface_acquire_dest_image (void		      *abstract_surface,
-				      cairo_rectangle_int_t   *interest_rect,
-				      cairo_image_surface_t  **image_out,
-				      cairo_rectangle_int_t   *image_rect_out,
-				      void		     **image_extra)
-{
-    cairo_gl_surface_t *surface = abstract_surface;
-    cairo_int_status_t status;
-
-    status = _cairo_gl_surface_deferred_clear (surface);
-    if (unlikely (status))
-	return status;
-
-    *image_extra = NULL;
-    return _cairo_gl_surface_get_image (surface, interest_rect, image_out,
-					image_rect_out);
-}
-
-void
-_cairo_gl_surface_release_dest_image (void		      *abstract_surface,
-				      cairo_rectangle_int_t   *interest_rect,
-				      cairo_image_surface_t   *image,
-				      cairo_rectangle_int_t   *image_rect,
-				      void		      *image_extra)
-{
-    cairo_status_t status;
-
-    status = _cairo_gl_surface_draw_image (abstract_surface, image,
-					   0, 0,
-					   image->width, image->height,
-					   image_rect->x, image_rect->y,
-					   TRUE);
-    /* as we created the image, its format should be directly applicable */
-    assert (status == CAIRO_STATUS_SUCCESS);
-
-    cairo_surface_destroy (&image->base);
-}
-
-cairo_status_t
-_cairo_gl_surface_clone_similar (void		     *abstract_surface,
-				 cairo_surface_t     *src,
-				 int                  src_x,
-				 int                  src_y,
-				 int                  width,
-				 int                  height,
-				 int                 *clone_offset_x,
-				 int                 *clone_offset_y,
-				 cairo_surface_t    **clone_out)
-{
-    cairo_gl_surface_t *surface = abstract_surface;
-    cairo_int_status_t status;
-
-    /* XXX: Use GLCopyTexImage2D to clone non-texture-surfaces */
-    if (src->device == surface->base.device &&
-	_cairo_gl_surface_is_texture ((cairo_gl_surface_t *) src)) {
-	status = _cairo_gl_surface_deferred_clear ((cairo_gl_surface_t *)src);
-	if (unlikely (status))
-	    return status;
-
-	*clone_offset_x = 0;
-	*clone_offset_y = 0;
-	*clone_out = cairo_surface_reference (src);
-
-	return CAIRO_STATUS_SUCCESS;
-    } else if (_cairo_surface_is_image (src)) {
-	cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
-	cairo_gl_surface_t *clone;
-
-	clone = (cairo_gl_surface_t *)
-		_cairo_gl_surface_create_similar (&surface->base,
-						  src->content,
-						  width, height);
-	if (clone == NULL)
-	    return UNSUPPORTED ("create_similar failed");
-	if (clone->base.status)
-	    return clone->base.status;
-
-	status = _cairo_gl_surface_draw_image (clone, image_src,
-					       src_x, src_y,
-					       width, height,
-					       0, 0, TRUE);
-	if (status) {
-	    cairo_surface_destroy (&clone->base);
-	    return status;
-	}
-
-	*clone_out = &clone->base;
-	*clone_offset_x = src_x;
-	*clone_offset_y = src_y;
-
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    return UNSUPPORTED ("unknown src surface type in clone_similar");
-}
-
-/* Creates a cairo-gl pattern surface for the given trapezoids */
-static cairo_status_t
-_cairo_gl_get_traps_pattern (cairo_gl_surface_t *dst,
-			     int dst_x, int dst_y,
-			     int width, int height,
-			     cairo_trapezoid_t *traps,
-			     int num_traps,
-			     cairo_antialias_t antialias,
-			     cairo_surface_pattern_t *pattern)
-{
-    pixman_format_code_t pixman_format;
-    pixman_image_t *image;
-    cairo_surface_t *surface;
-    int i;
-
-    pixman_format = antialias != CAIRO_ANTIALIAS_NONE ? PIXMAN_a8 : PIXMAN_a1,
-    image = pixman_image_create_bits (pixman_format, width, height, NULL, 0);
-    if (unlikely (image == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    for (i = 0; i < num_traps; i++) {
-	pixman_trapezoid_t trap;
-
-	trap.top = _cairo_fixed_to_16_16 (traps[i].top);
-	trap.bottom = _cairo_fixed_to_16_16 (traps[i].bottom);
-
-	trap.left.p1.x = _cairo_fixed_to_16_16 (traps[i].left.p1.x);
-	trap.left.p1.y = _cairo_fixed_to_16_16 (traps[i].left.p1.y);
-	trap.left.p2.x = _cairo_fixed_to_16_16 (traps[i].left.p2.x);
-	trap.left.p2.y = _cairo_fixed_to_16_16 (traps[i].left.p2.y);
-
-	trap.right.p1.x = _cairo_fixed_to_16_16 (traps[i].right.p1.x);
-	trap.right.p1.y = _cairo_fixed_to_16_16 (traps[i].right.p1.y);
-	trap.right.p2.x = _cairo_fixed_to_16_16 (traps[i].right.p2.x);
-	trap.right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
-
-	pixman_rasterize_trapezoid (image, &trap, -dst_x, -dst_y);
-    }
-
-    surface = _cairo_image_surface_create_for_pixman_image (image,
-							    pixman_format);
-    if (unlikely (surface->status)) {
-	pixman_image_unref (image);
-	return surface->status;
-    }
-
-    _cairo_pattern_init_for_surface (pattern, surface);
-    cairo_surface_destroy (surface);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_int_status_t
-_cairo_gl_surface_composite (cairo_operator_t		  op,
-			     const cairo_pattern_t	 *src,
-			     const cairo_pattern_t	 *mask,
-			     void			 *abstract_dst,
-			     int			  src_x,
-			     int			  src_y,
-			     int			  mask_x,
-			     int			  mask_y,
-			     int			  dst_x,
-			     int			  dst_y,
-			     unsigned int		  width,
-			     unsigned int		  height,
-			     cairo_region_t		 *clip_region)
-{
-    cairo_gl_surface_t *dst = abstract_dst;
-    cairo_gl_context_t *ctx;
-    cairo_status_t status;
-    cairo_gl_composite_t setup;
-    cairo_rectangle_int_t rect = { dst_x, dst_y, width, height };
-    int dx, dy;
-
-    status = _cairo_gl_surface_deferred_clear (dst);
-    if (unlikely (status))
-	    return status;
-
-    if (op == CAIRO_OPERATOR_SOURCE &&
-	mask == NULL &&
-	src->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	_cairo_surface_is_image (((cairo_surface_pattern_t *) src)->surface) &&
-	_cairo_matrix_is_integer_translation (&src->matrix, &dx, &dy)) {
-	cairo_image_surface_t *image = (cairo_image_surface_t *)
-	    ((cairo_surface_pattern_t *) src)->surface;
-	dx += src_x;
-	dy += src_y;
-	if (dx >= 0 &&
-	    dy >= 0 &&
-	    dx + width <= (unsigned int) image->width &&
-	    dy + height <= (unsigned int) image->height) {
-	    status = _cairo_gl_surface_draw_image (dst, image,
-						   dx, dy,
-						   width, height,
-						   dst_x, dst_y, TRUE);
-	    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-		return status;
-	}
-    }
-
-    status = _cairo_gl_composite_init (&setup, op, dst,
-				       mask && mask->has_component_alpha,
-				       &rect);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    status = _cairo_gl_composite_set_source (&setup, src,
-					     src_x, src_y,
-					     dst_x, dst_y,
-					     width, height);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    status = _cairo_gl_composite_set_mask (&setup, mask,
-					   mask_x, mask_y,
-					   dst_x, dst_y,
-					   width, height);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    if (clip_region != NULL) {
-	int i, num_rectangles;
-
-	num_rectangles = cairo_region_num_rectangles (clip_region);
-
-	for (i = 0; i < num_rectangles; i++) {
-	    cairo_rectangle_int_t rect;
-
-	    cairo_region_get_rectangle (clip_region, i, &rect);
-	    _cairo_gl_composite_emit_rect (ctx,
-					   rect.x,              rect.y,
-					   rect.x + rect.width, rect.y + rect.height,
-					   0);
-	}
-    } else {
-	_cairo_gl_composite_emit_rect (ctx,
-				       dst_x,         dst_y,
-				       dst_x + width, dst_y + height,
-				       0);
-    }
-
-    status = _cairo_gl_context_release (ctx, status);
-
-  CLEANUP:
-    _cairo_gl_composite_fini (&setup);
-
-    return status;
-}
-
-cairo_int_status_t
-_cairo_gl_surface_composite_trapezoids (cairo_operator_t op,
-					const cairo_pattern_t *pattern,
-					void *abstract_dst,
-					cairo_antialias_t antialias,
-					int src_x, int src_y,
-					int dst_x, int dst_y,
-					unsigned int width,
-					unsigned int height,
-					cairo_trapezoid_t *traps,
-					int num_traps,
-					cairo_region_t *clip_region)
-{
-    cairo_gl_surface_t *dst = abstract_dst;
-    cairo_surface_pattern_t traps_pattern;
-    cairo_int_status_t status;
-
-    if (! _cairo_gl_operator_is_supported (op))
-	return UNSUPPORTED ("unsupported operator");
-
-    status = _cairo_gl_surface_deferred_clear (dst);
-    if (unlikely (status))
-	    return status;
-
-    status = _cairo_gl_get_traps_pattern (dst,
-					  dst_x, dst_y, width, height,
-					  traps, num_traps, antialias,
-					  &traps_pattern);
-    if (unlikely (status))
-	return status;
-
-    status = _cairo_gl_surface_composite (op,
-					  pattern, &traps_pattern.base, dst,
-					  src_x, src_y,
-					  0, 0,
-					  dst_x, dst_y,
-					  width, height,
-					  clip_region);
-
-    _cairo_pattern_fini (&traps_pattern.base);
-
-    assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
-    return status;
-}
-
-cairo_int_status_t
-_cairo_gl_surface_fill_rectangles (void			   *abstract_dst,
-				   cairo_operator_t	    op,
-				   const cairo_color_t     *color,
-				   cairo_rectangle_int_t   *rects,
-				   int			    num_rects)
-{
-    cairo_gl_surface_t *dst = abstract_dst;
-    cairo_solid_pattern_t solid;
-    cairo_gl_context_t *ctx;
-    cairo_status_t status;
-    cairo_gl_composite_t setup;
-    int i;
-
-    status = _cairo_gl_surface_deferred_clear (dst);
-    if (unlikely (status))
-	    return status;
-
-    status = _cairo_gl_composite_init (&setup, op, dst,
-				       FALSE,
-				       /* XXX */ NULL);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    _cairo_pattern_init_solid (&solid, color);
-    status = _cairo_gl_composite_set_source (&setup, &solid.base,
-					     0, 0,
-					     0, 0,
-					     0, 0);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    status = _cairo_gl_composite_set_mask (&setup, NULL,
-					   0, 0,
-					   0, 0,
-					   0, 0);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    for (i = 0; i < num_rects; i++) {
-	_cairo_gl_composite_emit_rect (ctx,
-				       rects[i].x,
-				       rects[i].y,
-				       rects[i].x + rects[i].width,
-				       rects[i].y + rects[i].height,
-				       0);
-    }
-
-    status = _cairo_gl_context_release (ctx, status);
-
-  CLEANUP:
-    _cairo_gl_composite_fini (&setup);
-
-    return status;
-}
-
-typedef struct _cairo_gl_surface_span_renderer {
-    cairo_span_renderer_t base;
-
-    cairo_gl_composite_t setup;
-
-    int xmin, xmax;
-    int ymin, ymax;
-
-    cairo_gl_context_t *ctx;
-} cairo_gl_surface_span_renderer_t;
-
-static cairo_status_t
-_cairo_gl_render_bounded_spans (void *abstract_renderer,
-				int y, int height,
-				const cairo_half_open_span_t *spans,
-				unsigned num_spans)
-{
-    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
-
-    if (num_spans == 0)
-	return CAIRO_STATUS_SUCCESS;
-
-    do {
-	if (spans[0].coverage) {
-	    _cairo_gl_composite_emit_rect (renderer->ctx,
-					   spans[0].x, y,
-					   spans[1].x, y + height,
-					   spans[0].coverage);
-	}
-
-	spans++;
-    } while (--num_spans > 1);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_render_unbounded_spans (void *abstract_renderer,
-				  int y, int height,
-				  const cairo_half_open_span_t *spans,
-				  unsigned num_spans)
-{
-    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
-
-    if (y > renderer->ymin) {
-	_cairo_gl_composite_emit_rect (renderer->ctx,
-				       renderer->xmin, renderer->ymin,
-				       renderer->xmax, y,
-				       0);
-    }
-
-    if (num_spans == 0) {
-	_cairo_gl_composite_emit_rect (renderer->ctx,
-				       renderer->xmin, y,
-				       renderer->xmax, y + height,
-				       0);
-    } else {
-	if (spans[0].x != renderer->xmin) {
-	    _cairo_gl_composite_emit_rect (renderer->ctx,
-					   renderer->xmin, y,
-					   spans[0].x,     y + height,
-					   0);
-	}
-
-	do {
-	    _cairo_gl_composite_emit_rect (renderer->ctx,
-					   spans[0].x, y,
-					   spans[1].x, y + height,
-					   spans[0].coverage);
-	    spans++;
-	} while (--num_spans > 1);
-
-	if (spans[0].x != renderer->xmax) {
-	    _cairo_gl_composite_emit_rect (renderer->ctx,
-					   spans[0].x,     y,
-					   renderer->xmax, y + height,
-					   0);
-	}
-    }
-
-    renderer->ymin = y + height;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_gl_finish_unbounded_spans (void *abstract_renderer)
-{
-    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
-
-    if (renderer->ymax > renderer->ymin) {
-	_cairo_gl_composite_emit_rect (renderer->ctx,
-				       renderer->xmin, renderer->ymin,
-				       renderer->xmax, renderer->ymax,
-				       0);
-    }
-
-    return _cairo_gl_context_release (renderer->ctx, CAIRO_STATUS_SUCCESS);
-}
-
-static cairo_status_t
-_cairo_gl_finish_bounded_spans (void *abstract_renderer)
-{
-    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
-
-    return _cairo_gl_context_release (renderer->ctx, CAIRO_STATUS_SUCCESS);
-}
-
-static void
-_cairo_gl_surface_span_renderer_destroy (void *abstract_renderer)
-{
-    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
-
-    if (!renderer)
-	return;
-
-    _cairo_gl_composite_fini (&renderer->setup);
-
-    free (renderer);
-}
-
-cairo_bool_t
-_cairo_gl_surface_check_span_renderer (cairo_operator_t	       op,
-				       const cairo_pattern_t  *pattern,
-				       void		      *abstract_dst,
-				       cairo_antialias_t       antialias)
-{
-    if (! _cairo_gl_operator_is_supported (op))
-	return FALSE;
-
-    return TRUE;
-
-    (void) pattern;
-    (void) abstract_dst;
-    (void) antialias;
-}
-
-cairo_span_renderer_t *
-_cairo_gl_surface_create_span_renderer (cairo_operator_t	 op,
-					const cairo_pattern_t	*src,
-					void			*abstract_dst,
-					cairo_antialias_t	 antialias,
-					const cairo_composite_rectangles_t *rects)
-{
-    cairo_gl_surface_t *dst = abstract_dst;
-    cairo_gl_surface_span_renderer_t *renderer;
-    cairo_status_t status;
-    const cairo_rectangle_int_t *extents;
-
-    status = _cairo_gl_surface_deferred_clear (dst);
-    if (unlikely (status))
-	return _cairo_span_renderer_create_in_error (status);
-
-    renderer = calloc (1, sizeof (*renderer));
-    if (unlikely (renderer == NULL))
-	return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
-
-    renderer->base.destroy = _cairo_gl_surface_span_renderer_destroy;
-    if (rects->is_bounded) {
-	renderer->base.render_rows = _cairo_gl_render_bounded_spans;
-	renderer->base.finish =      _cairo_gl_finish_bounded_spans;
-	extents = &rects->bounded;
-    } else {
-	renderer->base.render_rows = _cairo_gl_render_unbounded_spans;
-	renderer->base.finish =      _cairo_gl_finish_unbounded_spans;
-	extents = &rects->unbounded;
-    }
-    renderer->xmin = extents->x;
-    renderer->xmax = extents->x + extents->width;
-    renderer->ymin = extents->y;
-    renderer->ymax = extents->y + extents->height;
-
-    status = _cairo_gl_composite_init (&renderer->setup,
-				       op, dst,
-				       FALSE, extents);
-    if (unlikely (status))
-	goto FAIL;
-
-    status = _cairo_gl_composite_set_source (&renderer->setup, src,
-					     extents->x, extents->y,
-					     extents->x, extents->y,
-					     extents->width, extents->height);
-    if (unlikely (status))
-	goto FAIL;
-
-    _cairo_gl_composite_set_spans (&renderer->setup);
-    _cairo_gl_composite_set_clip_region (&renderer->setup,
-					 _cairo_clip_get_region (rects->clip));
-
-    status = _cairo_gl_composite_begin (&renderer->setup, &renderer->ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    return &renderer->base;
-
-FAIL:
-    _cairo_gl_composite_fini (&renderer->setup);
-    free (renderer);
-    return _cairo_span_renderer_create_in_error (status);
-}
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
deleted file mode 100644
index e48244dd4..000000000
--- a/src/cairo-gl-surface.c
+++ /dev/null
@@ -1,1552 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-composite-rectangles-private.h"
-#include "cairo-compositor-private.h"
-#include "cairo-default-context-private.h"
-#include "cairo-error-private.h"
-#include "cairo-image-surface-inline.h"
-#include "cairo-surface-backend-private.h"
-
-static const cairo_surface_backend_t _cairo_gl_surface_backend;
-
-static cairo_status_t
-_cairo_gl_surface_flush (void *abstract_surface, unsigned flags);
-
-static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface)
-{
-    return surface->backend == &_cairo_gl_surface_backend;
-}
-
-static cairo_bool_t
-_cairo_gl_get_image_format_and_type_gles2 (pixman_format_code_t pixman_format,
-					   GLenum *internal_format, GLenum *format,
-					   GLenum *type, cairo_bool_t *has_alpha,
-					   cairo_bool_t *needs_swap)
-{
-    cairo_bool_t is_little_endian = _cairo_is_little_endian ();
-
-    *has_alpha = TRUE;
-
-    switch ((int) pixman_format) {
-    case PIXMAN_a8r8g8b8:
-	*internal_format = GL_BGRA;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_BYTE;
-	*needs_swap = !is_little_endian;
-	return TRUE;
-
-    case PIXMAN_x8r8g8b8:
-	*internal_format = GL_BGRA;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_BYTE;
-	*has_alpha = FALSE;
-	*needs_swap = !is_little_endian;
-	return TRUE;
-
-    case PIXMAN_a8b8g8r8:
-	*internal_format = GL_RGBA;
-	*format = GL_RGBA;
-	*type = GL_UNSIGNED_BYTE;
-	*needs_swap = !is_little_endian;
-	return TRUE;
-
-    case PIXMAN_x8b8g8r8:
-	*internal_format = GL_RGBA;
-	*format = GL_RGBA;
-	*type = GL_UNSIGNED_BYTE;
-	*has_alpha = FALSE;
-	*needs_swap = !is_little_endian;
-	return TRUE;
-
-    case PIXMAN_b8g8r8a8:
-	*internal_format = GL_BGRA;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_BYTE;
-	*needs_swap = is_little_endian;
-	return TRUE;
-
-    case PIXMAN_b8g8r8x8:
-	*internal_format = GL_BGRA;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_BYTE;
-	*has_alpha = FALSE;
-	*needs_swap = is_little_endian;
-	return TRUE;
-
-    case PIXMAN_r8g8b8:
-	*internal_format = GL_RGB;
-	*format = GL_RGB;
-	*type = GL_UNSIGNED_BYTE;
-	*needs_swap = is_little_endian;
-	return TRUE;
-
-    case PIXMAN_b8g8r8:
-	*internal_format = GL_RGB;
-	*format = GL_RGB;
-	*type = GL_UNSIGNED_BYTE;
-	*needs_swap = !is_little_endian;
-	return TRUE;
-
-    case PIXMAN_r5g6b5:
-	*internal_format = GL_RGB;
-	*format = GL_RGB;
-	*type = GL_UNSIGNED_SHORT_5_6_5;
-	*needs_swap = FALSE;
-	return TRUE;
-
-    case PIXMAN_b5g6r5:
-	*internal_format = GL_RGB;
-	*format = GL_RGB;
-	*type = GL_UNSIGNED_SHORT_5_6_5;
-	*needs_swap = TRUE;
-	return TRUE;
-
-    case PIXMAN_a1b5g5r5:
-	*internal_format = GL_RGBA;
-	*format = GL_RGBA;
-	*type = GL_UNSIGNED_SHORT_5_5_5_1;
-	*needs_swap = TRUE;
-	return TRUE;
-
-    case PIXMAN_x1b5g5r5:
-	*internal_format = GL_RGBA;
-	*format = GL_RGBA;
-	*type = GL_UNSIGNED_SHORT_5_5_5_1;
-	*has_alpha = FALSE;
-	*needs_swap = TRUE;
-	return TRUE;
-
-    case PIXMAN_a8:
-	*internal_format = GL_ALPHA;
-	*format = GL_ALPHA;
-	*type = GL_UNSIGNED_BYTE;
-	*needs_swap = FALSE;
-	return TRUE;
-
-    default:
-	return FALSE;
-    }
-}
-
-static cairo_bool_t
-_cairo_gl_get_image_format_and_type_gl (pixman_format_code_t pixman_format,
-					GLenum *internal_format, GLenum *format,
-					GLenum *type, cairo_bool_t *has_alpha,
-					cairo_bool_t *needs_swap)
-{
-    *has_alpha = TRUE;
-    *needs_swap = FALSE;
-
-    switch (pixman_format) {
-    case PIXMAN_a8r8g8b8:
-	*internal_format = GL_RGBA;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	return TRUE;
-    case PIXMAN_x8r8g8b8:
-	*internal_format = GL_RGB;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	*has_alpha = FALSE;
-	return TRUE;
-    case PIXMAN_a8b8g8r8:
-	*internal_format = GL_RGBA;
-	*format = GL_RGBA;
-	*type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	return TRUE;
-    case PIXMAN_x8b8g8r8:
-	*internal_format = GL_RGB;
-	*format = GL_RGBA;
-	*type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	*has_alpha = FALSE;
-	return TRUE;
-    case PIXMAN_b8g8r8a8:
-	*internal_format = GL_RGBA;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_INT_8_8_8_8;
-	return TRUE;
-    case PIXMAN_b8g8r8x8:
-	*internal_format = GL_RGB;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_INT_8_8_8_8;
-	*has_alpha = FALSE;
-	return TRUE;
-    case PIXMAN_r8g8b8:
-	*internal_format = GL_RGB;
-	*format = GL_RGB;
-	*type = GL_UNSIGNED_BYTE;
-	return TRUE;
-    case PIXMAN_b8g8r8:
-	*internal_format = GL_RGB;
-	*format = GL_BGR;
-	*type = GL_UNSIGNED_BYTE;
-	return TRUE;
-    case PIXMAN_r5g6b5:
-	*internal_format = GL_RGB;
-	*format = GL_RGB;
-	*type = GL_UNSIGNED_SHORT_5_6_5;
-	return TRUE;
-    case PIXMAN_b5g6r5:
-	*internal_format = GL_RGB;
-	*format = GL_RGB;
-	*type = GL_UNSIGNED_SHORT_5_6_5_REV;
-	return TRUE;
-    case PIXMAN_a1r5g5b5:
-	*internal_format = GL_RGBA;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-	return TRUE;
-    case PIXMAN_x1r5g5b5:
-	*internal_format = GL_RGB;
-	*format = GL_BGRA;
-	*type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-	*has_alpha = FALSE;
-	return TRUE;
-    case PIXMAN_a1b5g5r5:
-	*internal_format = GL_RGBA;
-	*format = GL_RGBA;
-	*type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-	return TRUE;
-    case PIXMAN_x1b5g5r5:
-	*internal_format = GL_RGB;
-	*format = GL_RGBA;
-	*type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-	*has_alpha = FALSE;
-	return TRUE;
-    case PIXMAN_a8:
-	*internal_format = GL_ALPHA;
-	*format = GL_ALPHA;
-	*type = GL_UNSIGNED_BYTE;
-	return TRUE;
-
-#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2)
-    case PIXMAN_a8r8g8b8_sRGB:
-#endif
-    case PIXMAN_a2b10g10r10:
-    case PIXMAN_x2b10g10r10:
-    case PIXMAN_a4r4g4b4:
-    case PIXMAN_x4r4g4b4:
-    case PIXMAN_a4b4g4r4:
-    case PIXMAN_x4b4g4r4:
-    case PIXMAN_r3g3b2:
-    case PIXMAN_b2g3r3:
-    case PIXMAN_a2r2g2b2:
-    case PIXMAN_a2b2g2r2:
-    case PIXMAN_c8:
-    case PIXMAN_x4a4:
-    /* case PIXMAN_x4c4: */
-    case PIXMAN_x4g4:
-    case PIXMAN_a4:
-    case PIXMAN_r1g2b1:
-    case PIXMAN_b1g2r1:
-    case PIXMAN_a1r1g1b1:
-    case PIXMAN_a1b1g1r1:
-    case PIXMAN_c4:
-    case PIXMAN_g4:
-    case PIXMAN_a1:
-    case PIXMAN_g1:
-    case PIXMAN_yuy2:
-    case PIXMAN_yv12:
-    case PIXMAN_x2r10g10b10:
-    case PIXMAN_a2r10g10b10:
-    case PIXMAN_r8g8b8x8:
-    case PIXMAN_r8g8b8a8:
-    case PIXMAN_x14r6g6b6:
-    case PIXMAN_rgb_float:
-    case PIXMAN_rgba_float:
-    default:
-	return FALSE;
-    }
-}
-
-/*
- * Extracts pixel data from an image surface.
- */
-static cairo_status_t
-_cairo_gl_surface_extract_image_data (cairo_image_surface_t *image,
-				      int x, int y,
-				      int width, int height,
-				      void **output)
-{
-    int cpp = PIXMAN_FORMAT_BPP (image->pixman_format) / 8;
-    char *data = _cairo_malloc_ab (width * height, cpp);
-    char *dst = data;
-    unsigned char *src = image->data + y * image->stride + x * cpp;
-    int i;
-
-    if (unlikely (data == NULL))
-	return CAIRO_STATUS_NO_MEMORY;
-
-    for (i = 0; i < height; i++) {
-	memcpy (dst, src, width * cpp);
-	src += image->stride;
-	dst += width * cpp;
-    }
-
-    *output = data;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_bool_t
-_cairo_gl_get_image_format_and_type (cairo_gl_flavor_t flavor,
-				     pixman_format_code_t pixman_format,
-				     GLenum *internal_format, GLenum *format,
-				     GLenum *type, cairo_bool_t *has_alpha,
-				     cairo_bool_t *needs_swap)
-{
-    if (flavor == CAIRO_GL_FLAVOR_DESKTOP)
-	return _cairo_gl_get_image_format_and_type_gl (pixman_format,
-						       internal_format, format,
-						       type, has_alpha,
-						       needs_swap);
-    else
-	return _cairo_gl_get_image_format_and_type_gles2 (pixman_format,
-							  internal_format, format,
-							  type, has_alpha,
-							  needs_swap);
-
-}
-
-cairo_bool_t
-_cairo_gl_operator_is_supported (cairo_operator_t op)
-{
-    return op < CAIRO_OPERATOR_SATURATE;
-}
-
-static void
-_cairo_gl_surface_embedded_operand_init (cairo_gl_surface_t *surface)
-{
-    cairo_gl_operand_t *operand = &surface->operand;
-    cairo_surface_attributes_t *attributes = &operand->texture.attributes;
-
-    memset (operand, 0, sizeof (cairo_gl_operand_t));
-
-    operand->type = CAIRO_GL_OPERAND_TEXTURE;
-    operand->texture.surface = surface;
-    operand->texture.tex = surface->tex;
-
-    if (_cairo_gl_device_requires_power_of_two_textures (surface->base.device)) {
-	cairo_matrix_init_identity (&attributes->matrix);
-    } else {
-	cairo_matrix_init_scale (&attributes->matrix,
-				 1.0 / surface->width,
-				 1.0 / surface->height);
-    }
-
-    attributes->extend = CAIRO_EXTEND_NONE;
-    attributes->filter = CAIRO_FILTER_NEAREST;
-}
-
-void
-_cairo_gl_surface_init (cairo_device_t *device,
-			cairo_gl_surface_t *surface,
-			cairo_content_t content,
-			int width, int height)
-{
-    assert (width > 0 && height > 0);
-
-    _cairo_surface_init (&surface->base,
-			 &_cairo_gl_surface_backend,
-			 device,
-			 content,
-			 FALSE); /* is_vector */
-
-    surface->width = width;
-    surface->height = height;
-    surface->needs_update = FALSE;
-    surface->content_in_texture = FALSE;
-
-    _cairo_gl_surface_embedded_operand_init (surface);
-}
-
-static cairo_bool_t
-_cairo_gl_surface_size_valid_for_context (cairo_gl_context_t *ctx,
-					  int width, int height)
-{
-    return width > 0 && height > 0 &&
-	width <= ctx->max_framebuffer_size &&
-	height <= ctx->max_framebuffer_size;
-}
-
-static cairo_bool_t
-_cairo_gl_surface_size_valid (cairo_gl_surface_t *surface,
-			      int width, int height)
-{
-    cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
-    return _cairo_gl_surface_size_valid_for_context (ctx, width, height);
-}
-
-static cairo_surface_t *
-_cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t   *ctx,
-					      cairo_content_t	    content,
-					      GLuint		    tex,
-					      int		    width,
-					      int		    height)
-{
-    cairo_gl_surface_t *surface;
-
-    surface = calloc (1, sizeof (cairo_gl_surface_t));
-    if (unlikely (surface == NULL))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    surface->tex = tex;
-    _cairo_gl_surface_init (&ctx->base, surface, content, width, height);
-
-    surface->supports_msaa = ctx->supports_msaa;
-    surface->num_samples = ctx->num_samples;
-    surface->supports_stencil = TRUE;
-
-    /* Create the texture used to store the surface's data. */
-    _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
-    glBindTexture (ctx->tex_target, surface->tex);
-    glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-    return &surface->base;
-}
-
-static cairo_surface_t *
-_create_scratch_internal (cairo_gl_context_t *ctx,
-			  cairo_content_t content,
-			  int width,
-			  int height,
-			  cairo_bool_t for_caching)
-{
-    cairo_gl_surface_t *surface;
-    GLenum format;
-    GLuint tex;
-
-    glGenTextures (1, &tex);
-    surface = (cairo_gl_surface_t *)
-	_cairo_gl_surface_create_scratch_for_texture (ctx, content,
-						      tex, width, height);
-    if (unlikely (surface->base.status))
-	return &surface->base;
-
-    surface->owns_tex = TRUE;
-
-    /* adjust the texture size after setting our real extents */
-    if (width < 1)
-	width = 1;
-    if (height < 1)
-	height = 1;
-
-    switch (content) {
-    default:
-	ASSERT_NOT_REACHED;
-    case CAIRO_CONTENT_COLOR_ALPHA:
-	format = GL_RGBA;
-	break;
-    case CAIRO_CONTENT_ALPHA:
-	/* When using GL_ALPHA, compositing doesn't work properly, but for
-	 * caching surfaces, we are just uploading pixel data, so it isn't
-	 * an issue. */
-	if (for_caching)
-	    format = GL_ALPHA;
-	else
-	    format = GL_RGBA;
-	break;
-    case CAIRO_CONTENT_COLOR:
-	/* GL_RGB is almost what we want here -- sampling 1 alpha when
-	 * texturing, using 1 as destination alpha factor in blending,
-	 * etc.  However, when filtering with GL_CLAMP_TO_BORDER, the
-	 * alpha channel of the border color will also be clamped to
-	 * 1, when we actually want the border color we explicitly
-	 * specified.  So, we have to store RGBA, and fill the alpha
-	 * channel with 1 when blending.
-	 */
-	format = GL_RGBA;
-	break;
-    }
-
-    glTexImage2D (ctx->tex_target, 0, format, width, height, 0,
-		  format, GL_UNSIGNED_BYTE, NULL);
-
-    return &surface->base;
-}
-
-cairo_surface_t *
-_cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
-				  cairo_content_t	content,
-				  int			width,
-				  int			height)
-{
-    return _create_scratch_internal (ctx, content, width, height, FALSE);
-}
-
-cairo_surface_t *
-_cairo_gl_surface_create_scratch_for_caching (cairo_gl_context_t *ctx,
-					      cairo_content_t content,
-					      int width,
-					      int height)
-{
-    return _create_scratch_internal (ctx, content, width, height, TRUE);
-}
-
-static cairo_status_t
-_cairo_gl_surface_clear (cairo_gl_surface_t  *surface,
-			 const cairo_color_t *color)
-{
-    cairo_gl_context_t *ctx;
-    cairo_status_t status;
-    double r, g, b, a;
-
-    status = _cairo_gl_context_acquire (surface->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    _cairo_gl_context_set_destination (ctx, surface, surface->msaa_active);
-    if (surface->base.content & CAIRO_CONTENT_COLOR) {
-	r = color->red   * color->alpha;
-	g = color->green * color->alpha;
-	b = color->blue  * color->alpha;
-    } else {
-	r = g = b = 0;
-    }
-    if (surface->base.content & CAIRO_CONTENT_ALPHA) {
-	a = color->alpha;
-    } else {
-	a = 1.0;
-    }
-
-    glDisable (GL_SCISSOR_TEST);
-    glClearColor (r, g, b, a);
-    glClear (GL_COLOR_BUFFER_BIT);
-
-    if (a == 0)
-	surface->base.is_clear = TRUE;
-
-    return _cairo_gl_context_release (ctx, status);
-}
-
-static cairo_surface_t *
-_cairo_gl_surface_create_and_clear_scratch (cairo_gl_context_t *ctx,
-					    cairo_content_t content,
-					    int width,
-					    int height)
-{
-    cairo_gl_surface_t *surface;
-    cairo_int_status_t status;
-
-    surface = (cairo_gl_surface_t *)
-	_cairo_gl_surface_create_scratch (ctx, content, width, height);
-    if (unlikely (surface->base.status))
-	return &surface->base;
-
-    /* Cairo surfaces start out initialized to transparent (black) */
-    status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
-    if (unlikely (status)) {
-	cairo_surface_destroy (&surface->base);
-	return _cairo_surface_create_in_error (status);
-    }
-
-    return &surface->base;
-}
-
-cairo_surface_t *
-cairo_gl_surface_create (cairo_device_t		*abstract_device,
-			 cairo_content_t	 content,
-			 int			 width,
-			 int			 height)
-{
-    cairo_gl_context_t *ctx;
-    cairo_gl_surface_t *surface;
-    cairo_status_t status;
-
-    if (! CAIRO_CONTENT_VALID (content))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
-
-    if (abstract_device == NULL)
-	return _cairo_image_surface_create_with_content (content, width, height);
-
-    if (abstract_device->status)
-	return _cairo_surface_create_in_error (abstract_device->status);
-
-    if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL)
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
-
-    status = _cairo_gl_context_acquire (abstract_device, &ctx);
-    if (unlikely (status))
-	return _cairo_surface_create_in_error (status);
-
-    if (! _cairo_gl_surface_size_valid_for_context (ctx, width, height)) {
-	status = _cairo_gl_context_release (ctx, status);
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
-    }
-
-    surface = (cairo_gl_surface_t *)
-	_cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
-    if (unlikely (surface->base.status)) {
-	status = _cairo_gl_context_release (ctx, surface->base.status);
-	cairo_surface_destroy (&surface->base);
-	return _cairo_surface_create_in_error (status);
-    }
-
-    status = _cairo_gl_context_release (ctx, status);
-    if (unlikely (status)) {
-	cairo_surface_destroy (&surface->base);
-	return _cairo_surface_create_in_error (status);
-    }
-
-    return &surface->base;
-}
-slim_hidden_def (cairo_gl_surface_create);
-
-/**
- * cairo_gl_surface_create_for_texture:
- * @content: type of content in the surface
- * @tex: name of texture to use for storage of surface pixels
- * @width: width of the surface, in pixels
- * @height: height of the surface, in pixels
- *
- * Creates a GL surface for the specified texture with the specified
- * content and dimensions.  The texture must be kept around until the
- * #cairo_surface_t is destroyed or cairo_surface_finish() is called
- * on the surface.  The initial contents of @tex will be used as the
- * initial image contents; you must explicitly clear the buffer,
- * using, for example, cairo_rectangle() and cairo_fill() if you want
- * it cleared.  The format of @tex should be compatible with @content,
- * in the sense that it must have the color components required by
- * @content.
- *
- * Return value: a pointer to the newly created surface. The caller
- * owns the surface and should call cairo_surface_destroy() when done
- * with it.
- *
- * This function always returns a valid pointer, but it will return a
- * pointer to a "nil" surface if an error such as out of memory
- * occurs. You can use cairo_surface_status() to check for this.
- *
- * Since: TBD
- **/
-cairo_surface_t *
-cairo_gl_surface_create_for_texture (cairo_device_t	*abstract_device,
-				     cairo_content_t	 content,
-				     unsigned int	 tex,
-				     int		 width,
-				     int		 height)
-{
-    cairo_gl_context_t *ctx;
-    cairo_gl_surface_t *surface;
-    cairo_status_t status;
-
-    if (! CAIRO_CONTENT_VALID (content))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
-
-    if (abstract_device == NULL)
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
-
-    if (abstract_device->status)
-	return _cairo_surface_create_in_error (abstract_device->status);
-
-    if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL)
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH));
-
-    status = _cairo_gl_context_acquire (abstract_device, &ctx);
-    if (unlikely (status))
-	return _cairo_surface_create_in_error (status);
-
-    if (! _cairo_gl_surface_size_valid_for_context (ctx, width, height)) {
-	status = _cairo_gl_context_release (ctx, status);
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
-    }
-
-    surface = (cairo_gl_surface_t *)
-	_cairo_gl_surface_create_scratch_for_texture (ctx, content,
-						      tex, width, height);
-    status = _cairo_gl_context_release (ctx, status);
-
-    return &surface->base;
-}
-slim_hidden_def (cairo_gl_surface_create_for_texture);
-
-
-void
-cairo_gl_surface_set_size (cairo_surface_t *abstract_surface,
-			   int              width,
-			   int              height)
-{
-    cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
-
-    if (unlikely (abstract_surface->status))
-	return;
-    if (unlikely (abstract_surface->finished)) {
-	_cairo_surface_set_error (abstract_surface,
-				  _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
-	return;
-    }
-
-    if (! _cairo_surface_is_gl (abstract_surface) ||
-	_cairo_gl_surface_is_texture (surface)) {
-	_cairo_surface_set_error (abstract_surface,
-				  _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
-	return;
-    }
-
-    if (surface->width != width || surface->height != height) {
-	surface->needs_update = TRUE;
-	surface->width = width;
-	surface->height = height;
-    }
-}
-
-int
-cairo_gl_surface_get_width (cairo_surface_t *abstract_surface)
-{
-    cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
-
-    if (! _cairo_surface_is_gl (abstract_surface))
-	return 0;
-
-    return surface->width;
-}
-
-int
-cairo_gl_surface_get_height (cairo_surface_t *abstract_surface)
-{
-    cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
-
-    if (! _cairo_surface_is_gl (abstract_surface))
-	return 0;
-
-    return surface->height;
-}
-
-void
-cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
-{
-    cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
-
-    if (unlikely (abstract_surface->status))
-	return;
-    if (unlikely (abstract_surface->finished)) {
-	_cairo_surface_set_error (abstract_surface,
-				  _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
-	return;
-    }
-
-    if (! _cairo_surface_is_gl (abstract_surface)) {
-	_cairo_surface_set_error (abstract_surface,
-				  CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
-	return;
-    }
-
-    if (! _cairo_gl_surface_is_texture (surface)) {
-	cairo_gl_context_t *ctx;
-	cairo_status_t status;
-
-	status = _cairo_gl_context_acquire (surface->base.device, &ctx);
-	if (unlikely (status))
-	    return;
-
-	/* For swapping on EGL, at least, we need a valid context/target. */
-	_cairo_gl_context_set_destination (ctx, surface, FALSE);
-	/* And in any case we should flush any pending operations. */
-	_cairo_gl_composite_flush (ctx);
-
-	ctx->swap_buffers (ctx, surface);
-
-	status = _cairo_gl_context_release (ctx, status);
-	if (status)
-	    status = _cairo_surface_set_error (abstract_surface, status);
-    }
-}
-
-static cairo_surface_t *
-_cairo_gl_surface_create_similar (void		 *abstract_surface,
-				  cairo_content_t  content,
-				  int		  width,
-				  int		  height)
-{
-    cairo_surface_t *surface = abstract_surface;
-    cairo_gl_context_t *ctx;
-    cairo_status_t status;
-
-    if (! _cairo_gl_surface_size_valid (abstract_surface, width, height))
-	return _cairo_image_surface_create_with_content (content, width, height);
-
-    status = _cairo_gl_context_acquire (surface->device, &ctx);
-    if (unlikely (status))
-	return _cairo_surface_create_in_error (status);
-
-    surface = _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
-
-    status = _cairo_gl_context_release (ctx, status);
-    if (unlikely (status)) {
-	cairo_surface_destroy (surface);
-	return _cairo_surface_create_in_error (status);
-    }
-
-    return surface;
-}
-
-static cairo_int_status_t
-_cairo_gl_surface_fill_alpha_channel (cairo_gl_surface_t *dst,
-				      cairo_gl_context_t *ctx,
-				      int x, int y,
-				      int width, int height)
-{
-    cairo_gl_composite_t setup;
-    cairo_status_t status;
-
-    _cairo_gl_composite_flush (ctx);
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
-
-    status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE,
-				       dst, FALSE);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_BLACK);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    _cairo_gl_context_emit_rect (ctx, x, y, x + width, y + height);
-
-    status = _cairo_gl_context_release (ctx, status);
-
-  CLEANUP:
-    _cairo_gl_composite_fini (&setup);
-
-    _cairo_gl_composite_flush (ctx);
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
-    return status;
-}
-
-cairo_status_t
-_cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
-			      cairo_image_surface_t *src,
-			      int src_x, int src_y,
-			      int width, int height,
-			      int dst_x, int dst_y,
-			      cairo_bool_t force_flush)
-{
-    GLenum internal_format, format, type;
-    cairo_bool_t has_alpha, needs_swap;
-    cairo_image_surface_t *clone = NULL;
-    cairo_gl_context_t *ctx;
-    int cpp;
-    cairo_image_surface_t *rgba_clone = NULL;
-    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
-    status = _cairo_gl_context_acquire (dst->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES3 ||
-	_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2) {
-	pixman_format_code_t pixman_format;
-	cairo_surface_pattern_t pattern;
-	cairo_bool_t require_conversion = FALSE;
-	pixman_format = _cairo_is_little_endian () ? PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8;
-
-	if (src->base.content != CAIRO_CONTENT_ALPHA) {
-	    if (src->pixman_format != pixman_format)
-		require_conversion = TRUE;
-	}
-	else if (dst->base.content != CAIRO_CONTENT_ALPHA) {
-	    require_conversion = TRUE;
-	}
-	else if (src->pixman_format != PIXMAN_a8) {
-	    pixman_format = PIXMAN_a8;
-	    require_conversion = TRUE;
-	}
-
-	if (require_conversion) {
-	    rgba_clone = (cairo_image_surface_t *)
-		_cairo_image_surface_create_with_pixman_format (NULL,
-								pixman_format,
-								src->width,
-								src->height,
-								0);
-	    if (unlikely (rgba_clone->base.status))
-		goto FAIL;
-
-	    _cairo_pattern_init_for_surface (&pattern, &src->base);
-	    status = _cairo_surface_paint (&rgba_clone->base,
-					   CAIRO_OPERATOR_SOURCE,
-					   &pattern.base, NULL);
-	    _cairo_pattern_fini (&pattern.base);
-	    if (unlikely (status))
-		goto FAIL;
-
-	    src = rgba_clone;
-	}
-    }
-
-    if (! _cairo_gl_get_image_format_and_type (ctx->gl_flavor,
-					       src->pixman_format,
-					       &internal_format,
-					       &format,
-					       &type,
-					       &has_alpha,
-					       &needs_swap))
-    {
-	cairo_bool_t is_supported;
-
-	clone = _cairo_image_surface_coerce (src);
-	if (unlikely (status = clone->base.status))
-	    goto FAIL;
-
-	is_supported =
-	    _cairo_gl_get_image_format_and_type (ctx->gl_flavor,
-						 clone->pixman_format,
-						 &internal_format,
-						 &format,
-						 &type,
-						 &has_alpha,
-						 &needs_swap);
-	assert (is_supported);
-	assert (!needs_swap);
-	src = clone;
-    }
-
-    cpp = PIXMAN_FORMAT_BPP (src->pixman_format) / 8;
-
-    if (force_flush) {
-	status = _cairo_gl_surface_flush (&dst->base, 0);
-	if (unlikely (status))
-	    goto FAIL;
-    }
-
-    if (_cairo_gl_surface_is_texture (dst)) {
-	void *data_start = src->data + src_y * src->stride + src_x * cpp;
-	void *data_start_gles2 = NULL;
-
-	/*
-	 * Due to GL_UNPACK_ROW_LENGTH missing in GLES2 we have to extract the
-	 * image data ourselves in some cases. In particular, we must extract
-	 * the pixels if:
-	 * a. we don't want full-length lines or
-	 * b. the row stride cannot be handled by GL itself using a 4 byte
-	 *     alignment constraint
-	 */
-	if (src->stride < 0 ||
-	    (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
-	     (src->width * cpp < src->stride - 3 ||
-	      width != src->width)))
-	{
-	    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
-	    status = _cairo_gl_surface_extract_image_data (src, src_x, src_y,
-							   width, height,
-							   &data_start_gles2);
-	    if (unlikely (status))
-		goto FAIL;
-
-	    data_start = data_start_gles2;
-	}
-	else
-	{
-	    glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
-	    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
-		ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-		glPixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp);
-	}
-
-	/* we must resolve the renderbuffer to texture before we
-	   upload image */
-	status = _cairo_gl_surface_resolve_multisampling (dst);
-	if (unlikely (status)) {
-	    free (data_start_gles2);
-	    goto FAIL;
-	}
-
-	_cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
-	glBindTexture (ctx->tex_target, dst->tex);
-	glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexSubImage2D (ctx->tex_target, 0,
-			 dst_x, dst_y, width, height,
-			 format, type, data_start);
-
-	free (data_start_gles2);
-
-	/* If we just treated some rgb-only data as rgba, then we have to
-	 * go back and fix up the alpha channel where we filled in this
-	 * texture data.
-	 */
-	if (!has_alpha) {
-	    _cairo_gl_surface_fill_alpha_channel (dst, ctx,
-						  dst_x, dst_y,
-						  width, height);
-	}
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	    dst->content_in_texture = TRUE;
-    } else {
-	cairo_surface_t *tmp;
-
-	tmp = _cairo_gl_surface_create_scratch (ctx,
-						dst->base.content,
-						width, height);
-	if (unlikely (tmp->status))
-	    goto FAIL;
-
-	status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *) tmp,
-					       src,
-					       src_x, src_y,
-					       width, height,
-					       0, 0, force_flush);
-	if (status == CAIRO_INT_STATUS_SUCCESS) {
-	    cairo_surface_pattern_t tmp_pattern;
-	    cairo_rectangle_int_t r;
-	    cairo_clip_t *clip;
-
-	    _cairo_pattern_init_for_surface (&tmp_pattern, tmp);
-	    cairo_matrix_init_translate (&tmp_pattern.base.matrix,
-					 -dst_x, -dst_y);
-	    tmp_pattern.base.filter = CAIRO_FILTER_NEAREST;
-	    tmp_pattern.base.extend = CAIRO_EXTEND_NONE;
-
-	    r.x = dst_x;
-	    r.y = dst_y;
-	    r.width = width;
-	    r.height = height;
-	    clip = _cairo_clip_intersect_rectangle (NULL, &r);
-	    status = _cairo_surface_paint (&dst->base,
-					   CAIRO_OPERATOR_SOURCE,
-					   &tmp_pattern.base,
-					   clip);
-	    _cairo_clip_destroy (clip);
-	    _cairo_pattern_fini (&tmp_pattern.base);
-	}
-
-	cairo_surface_destroy (tmp);
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	    dst->content_in_texture = TRUE;
-    }
-
-FAIL:
-    status = _cairo_gl_context_release (ctx, status);
-
-    if (clone)
-	cairo_surface_destroy (&clone->base);
-
-    if (rgba_clone)
-	cairo_surface_destroy (&rgba_clone->base);
-
-    return status;
-}
-
-static int _cairo_gl_surface_flavor (cairo_gl_surface_t *surface)
-{
-    cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
-    return ctx->gl_flavor;
-}
-
-static cairo_status_t
-_cairo_gl_surface_finish (void *abstract_surface)
-{
-    cairo_gl_surface_t *surface = abstract_surface;
-    cairo_status_t status;
-    cairo_gl_context_t *ctx;
-
-    status = _cairo_gl_context_acquire (surface->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    if (ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE &&
-	ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface)
-	_cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE);
-    if (ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE &&
-	ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface)
-	_cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK);
-    if (ctx->current_target == surface)
-	ctx->current_target = NULL;
-
-    if (surface->fb)
-	ctx->dispatch.DeleteFramebuffers (1, &surface->fb);
-    if (surface->depth_stencil)
-	ctx->dispatch.DeleteRenderbuffers (1, &surface->depth_stencil);
-    if (surface->owns_tex)
-	glDeleteTextures (1, &surface->tex);
-
-    if (surface->msaa_depth_stencil)
-	ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_depth_stencil);
-
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-    if (surface->msaa_fb)
-	ctx->dispatch.DeleteFramebuffers (1, &surface->msaa_fb);
-    if (surface->msaa_rb)
-	ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_rb);
-#endif
-
-    _cairo_clip_destroy (surface->clip_on_stencil_buffer);
-
-    return _cairo_gl_context_release (ctx, status);
-}
-
-static cairo_image_surface_t *
-_cairo_gl_surface_map_to_image (void      *abstract_surface,
-				const cairo_rectangle_int_t   *extents)
-{
-    cairo_gl_surface_t *surface = abstract_surface;
-    cairo_image_surface_t *image;
-    cairo_gl_context_t *ctx;
-    GLenum format, type;
-    pixman_format_code_t pixman_format;
-    unsigned int cpp;
-    cairo_bool_t flipped, mesa_invert;
-    cairo_status_t status;
-    int y;
-
-    status = _cairo_gl_context_acquire (surface->base.device, &ctx);
-    if (unlikely (status)) {
-	return _cairo_image_surface_create_in_error (status);
-    }
-
-    /* Want to use a switch statement here but the compiler gets whiny. */
-    if (surface->base.content == CAIRO_CONTENT_COLOR_ALPHA) {
-	format = GL_BGRA;
-	pixman_format = PIXMAN_a8r8g8b8;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	cpp = 4;
-    } else if (surface->base.content == CAIRO_CONTENT_COLOR) {
-	format = GL_BGRA;
-	pixman_format = PIXMAN_x8r8g8b8;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	cpp = 4;
-    } else if (surface->base.content == CAIRO_CONTENT_ALPHA) {
-	format = GL_ALPHA;
-	pixman_format = PIXMAN_a8;
-	type = GL_UNSIGNED_BYTE;
-	cpp = 1;
-    } else {
-	ASSERT_NOT_REACHED;
-	return NULL;
-    }
-
-    if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES3 ||
-	_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES2) {
-	/* If only RGBA is supported, we must download data in a compatible
-	 * format. This means that pixman will convert the data on the CPU when
-	 * interacting with other image surfaces. For ALPHA, GLES2 does not
-	 * support GL_PACK_ROW_LENGTH anyway, and this makes sure that the
-	 * pixman image that is created has row_stride = row_width * bpp. */
-	if (surface->base.content == CAIRO_CONTENT_ALPHA || !ctx->can_read_bgra) {
-	    cairo_bool_t little_endian = _cairo_is_little_endian ();
-	    format = GL_RGBA;
-
-	    if (surface->base.content == CAIRO_CONTENT_COLOR) {
-		pixman_format = little_endian ?
-		    PIXMAN_x8b8g8r8 : PIXMAN_r8g8b8x8;
-	    } else {
-		pixman_format = little_endian ?
-		    PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8;
-	    }
-	}
-
-	/* GLES2 only supports GL_UNSIGNED_BYTE. */
-	type = GL_UNSIGNED_BYTE;
-	cpp = 4;
-    }
-
-    image = (cairo_image_surface_t*)
-	_cairo_image_surface_create_with_pixman_format (NULL,
-							pixman_format,
-							extents->width,
-							extents->height,
-							-1);
-    if (unlikely (image->base.status)) {
-	status = _cairo_gl_context_release (ctx, status);
-	return image;
-    }
-
-    cairo_surface_set_device_offset (&image->base, -extents->x, -extents->y);
-
-    /* If the original surface has not been modified or
-     * is clear, we can avoid downloading data. */
-    if (surface->base.is_clear || surface->base.serial == 0) {
-	status = _cairo_gl_context_release (ctx, status);
-	return image;
-    }
-
-    /* This is inefficient, as we'd rather just read the thing without making
-     * it the destination.  But then, this is the fallback path, so let's not
-     * fall back instead.
-     */
-    _cairo_gl_composite_flush (ctx);
-
-    if (ctx->gl_flavor != CAIRO_GL_FLAVOR_ES3) {
-	_cairo_gl_context_set_destination (ctx, surface, FALSE);
-    } else {
-	if (surface->content_in_texture) {
-	    _cairo_gl_ensure_framebuffer (ctx, surface);
-	    ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
-	} else {
-	    status = _cairo_gl_surface_resolve_multisampling (surface);
-	    if (unlikely (status)) {
-		status = _cairo_gl_context_release (ctx, status);
-		cairo_surface_destroy (&image->base);
-		return _cairo_image_surface_create_in_error (status);
-	    }
-	}
-    }
-
-    flipped = ! _cairo_gl_surface_is_texture (surface);
-    mesa_invert = flipped && ctx->has_mesa_pack_invert;
-
-    glPixelStorei (GL_PACK_ALIGNMENT, 4);
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	glPixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp);
-    if (mesa_invert)
-	glPixelStorei (GL_PACK_INVERT_MESA, 1);
-
-    y = extents->y;
-    if (flipped)
-	y = surface->height - extents->y - extents->height;
-
-    glReadPixels (extents->x, y,
-		  extents->width, extents->height,
-		  format, type, image->data);
-    if (mesa_invert)
-	glPixelStorei (GL_PACK_INVERT_MESA, 0);
-
-    status = _cairo_gl_context_release (ctx, status);
-    if (unlikely (status)) {
-	cairo_surface_destroy (&image->base);
-	return _cairo_image_surface_create_in_error (status);
-    }
-
-    /* We must invert the image manually if we lack GL_MESA_pack_invert */
-    if (flipped && ! mesa_invert) {
-	uint8_t stack[1024], *row = stack;
-	uint8_t *top = image->data;
-	uint8_t *bot = image->data + (image->height-1)*image->stride;
-
-	if (image->stride > (int)sizeof(stack)) {
-	    row = _cairo_malloc (image->stride);
-	    if (unlikely (row == NULL)) {
-		cairo_surface_destroy (&image->base);
-		return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-	    }
-	}
-
-	while (top < bot) {
-	    memcpy (row, top, image->stride);
-	    memcpy (top, bot, image->stride);
-	    memcpy (bot, row, image->stride);
-	    top += image->stride;
-	    bot -= image->stride;
-	}
-
-	if (row != stack)
-	    free(row);
-    }
-
-    image->base.is_clear = FALSE;
-    return image;
-}
-
-static cairo_surface_t *
-_cairo_gl_surface_source (void		       *abstract_surface,
-			  cairo_rectangle_int_t *extents)
-{
-    cairo_gl_surface_t *surface = abstract_surface;
-
-    if (extents) {
-	extents->x = extents->y = 0;
-	extents->width  = surface->width;
-	extents->height = surface->height;
-    }
-
-    return &surface->base;
-}
-
-static cairo_status_t
-_cairo_gl_surface_acquire_source_image (void		       *abstract_surface,
-					cairo_image_surface_t **image_out,
-					void		      **image_extra)
-{
-    cairo_gl_surface_t *surface = abstract_surface;
-    cairo_rectangle_int_t extents;
-
-    *image_extra = NULL;
-
-    extents.x = extents.y = 0;
-    extents.width = surface->width;
-    extents.height = surface->height;
-
-    *image_out = (cairo_image_surface_t *)
-	_cairo_gl_surface_map_to_image (surface, &extents);
-    return (*image_out)->base.status;
-}
-
-static void
-_cairo_gl_surface_release_source_image (void		      *abstract_surface,
-					cairo_image_surface_t *image,
-					void		      *image_extra)
-{
-    cairo_surface_destroy (&image->base);
-}
-
-static cairo_int_status_t
-_cairo_gl_surface_unmap_image (void		      *abstract_surface,
-			       cairo_image_surface_t *image)
-{
-    cairo_int_status_t status;
-
-    status = _cairo_gl_surface_draw_image (abstract_surface, image,
-					   0, 0,
-					   image->width, image->height,
-					   image->base.device_transform_inverse.x0,
-					   image->base.device_transform_inverse.y0,
-					   TRUE);
-
-    cairo_surface_finish (&image->base);
-    cairo_surface_destroy (&image->base);
-
-    return status;
-}
-
-static cairo_bool_t
-_cairo_gl_surface_get_extents (void		     *abstract_surface,
-			       cairo_rectangle_int_t *rectangle)
-{
-    cairo_gl_surface_t *surface = abstract_surface;
-
-    rectangle->x = 0;
-    rectangle->y = 0;
-    rectangle->width  = surface->width;
-    rectangle->height = surface->height;
-
-    return TRUE;
-}
-
-static cairo_status_t
-_cairo_gl_surface_flush (void *abstract_surface, unsigned flags)
-{
-    cairo_gl_surface_t *surface = abstract_surface;
-    cairo_status_t status;
-    cairo_gl_context_t *ctx;
-
-    if (flags)
-	return CAIRO_STATUS_SUCCESS;
-
-    status = _cairo_gl_context_acquire (surface->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-    if ((ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE &&
-	 ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface) ||
-	(ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE &&
-	 ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface) ||
-	(ctx->current_target == surface))
-      _cairo_gl_composite_flush (ctx);
-
-    status = _cairo_gl_surface_resolve_multisampling (surface);
-
-    return _cairo_gl_context_release (ctx, status);
-}
-
-cairo_int_status_t
-_cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface)
-{
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-
-    if (! surface->msaa_active)
-	return CAIRO_INT_STATUS_SUCCESS;
-
-    if (surface->base.device == NULL)
-	return CAIRO_INT_STATUS_SUCCESS;
-
-    /* GLES surfaces do not need explicit resolution. */
-    if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES2)
-	return CAIRO_INT_STATUS_SUCCESS;
-    else if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES3 &&
-	     surface->content_in_texture)
-	return CAIRO_INT_STATUS_SUCCESS;
-
-    if (! _cairo_gl_surface_is_texture (surface))
-	return CAIRO_INT_STATUS_SUCCESS;
-
-    status = _cairo_gl_context_acquire (surface->base.device, &ctx);
-    if (unlikely (status))
-	return status;
-
-#if CAIRO_HAS_GLESV3_SURFACE
-    _cairo_gl_composite_flush (ctx);
-    ctx->current_target = NULL;
-    _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
-	surface->content_in_texture = TRUE;
-
-#elif CAIRO_HAS_GL_SURFACE
-    ctx->current_target = surface;
-    _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
-
-#else
-    ctx->current_target = surface;
-
-#endif
-
-    status = _cairo_gl_context_release (ctx, status);
-    return status;
-}
-
-static const cairo_compositor_t *
-get_compositor (cairo_gl_surface_t *surface)
-{
-    cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
-    return ctx->compositor;
-}
-
-static cairo_int_status_t
-_cairo_gl_surface_paint (void			*surface,
-			 cairo_operator_t	 op,
-			 const cairo_pattern_t	*source,
-			 const cairo_clip_t	*clip)
-{
-    /* simplify the common case of clearing the surface */
-    if (clip == NULL) {
-	if (op == CAIRO_OPERATOR_CLEAR)
-	    return _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
-       else if (source->type == CAIRO_PATTERN_TYPE_SOLID &&
-		(op == CAIRO_OPERATOR_SOURCE ||
-		 (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) {
-	    return _cairo_gl_surface_clear (surface,
-					    &((cairo_solid_pattern_t *) source)->color);
-	}
-    }
-
-    return _cairo_compositor_paint (get_compositor (surface), surface,
-				    op, source, clip);
-}
-
-static cairo_int_status_t
-_cairo_gl_surface_mask (void			 *surface,
-			cairo_operator_t	  op,
-			const cairo_pattern_t	*source,
-			const cairo_pattern_t	*mask,
-			const cairo_clip_t	*clip)
-{
-    return _cairo_compositor_mask (get_compositor (surface), surface,
-				   op, source, mask, clip);
-}
-
-static cairo_int_status_t
-_cairo_gl_surface_stroke (void				*surface,
-			  cairo_operator_t		 op,
-			  const cairo_pattern_t		*source,
-			  const cairo_path_fixed_t	*path,
-			  const cairo_stroke_style_t	*style,
-			  const cairo_matrix_t		*ctm,
-			  const cairo_matrix_t		*ctm_inverse,
-			  double			 tolerance,
-			  cairo_antialias_t		 antialias,
-			  const cairo_clip_t		*clip)
-{
-    return _cairo_compositor_stroke (get_compositor (surface), surface,
-				     op, source, path, style,
-				     ctm, ctm_inverse, tolerance, antialias,
-				     clip);
-}
-
-static cairo_int_status_t
-_cairo_gl_surface_fill (void			*surface,
-			cairo_operator_t	 op,
-			const cairo_pattern_t	*source,
-			const cairo_path_fixed_t*path,
-			cairo_fill_rule_t	 fill_rule,
-			double			 tolerance,
-			cairo_antialias_t	 antialias,
-			const cairo_clip_t	*clip)
-{
-    return _cairo_compositor_fill (get_compositor (surface), surface,
-				   op, source, path,
-				   fill_rule, tolerance, antialias,
-				   clip);
-}
-
-static cairo_int_status_t
-_cairo_gl_surface_glyphs (void			*surface,
-			  cairo_operator_t	 op,
-			  const cairo_pattern_t	*source,
-			  cairo_glyph_t		*glyphs,
-			  int			 num_glyphs,
-			  cairo_scaled_font_t	*font,
-			  const cairo_clip_t	*clip)
-{
-    return _cairo_compositor_glyphs (get_compositor (surface), surface,
-				     op, source, glyphs, num_glyphs, font,
-				     clip);
-}
-
-static const cairo_surface_backend_t _cairo_gl_surface_backend = {
-    CAIRO_SURFACE_TYPE_GL,
-    _cairo_gl_surface_finish,
-    _cairo_default_context_create,
-
-    _cairo_gl_surface_create_similar,
-    NULL, /* similar image */
-    _cairo_gl_surface_map_to_image,
-    _cairo_gl_surface_unmap_image,
-
-    _cairo_gl_surface_source,
-    _cairo_gl_surface_acquire_source_image,
-    _cairo_gl_surface_release_source_image,
-    NULL, /* snapshot */
-
-    NULL, /* copy_page */
-    NULL, /* show_page */
-
-    _cairo_gl_surface_get_extents,
-    _cairo_image_surface_get_font_options,
-
-    _cairo_gl_surface_flush,
-    NULL, /* mark_dirty_rectangle */
-
-    _cairo_gl_surface_paint,
-    _cairo_gl_surface_mask,
-    _cairo_gl_surface_stroke,
-    _cairo_gl_surface_fill,
-    NULL, /* fill/stroke */
-    _cairo_gl_surface_glyphs,
-};
diff --git a/src/cairo-gl-traps-compositor.c b/src/cairo-gl-traps-compositor.c
deleted file mode 100644
index 7938c5b20..000000000
--- a/src/cairo-gl-traps-compositor.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005,2010 Red Hat, Inc
- * Copyright © 2011 Intel Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Benjamin Otte <otte at gnome.org>
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Eric Anholt <eric at anholt.net>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-composite-rectangles-private.h"
-#include "cairo-compositor-private.h"
-#include "cairo-default-context-private.h"
-#include "cairo-error-private.h"
-#include "cairo-image-surface-private.h"
-#include "cairo-spans-compositor-private.h"
-#include "cairo-surface-backend-private.h"
-#include "cairo-surface-offset-private.h"
-
-static cairo_int_status_t
-acquire (void *abstract_dst)
-{
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-release (void *abstract_dst)
-{
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-set_clip_region (void *_surface,
-		 cairo_region_t *region)
-{
-    cairo_gl_surface_t *surface = _surface;
-
-    surface->clip_region = region;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-draw_image_boxes (void *_dst,
-		  cairo_image_surface_t *image,
-		  cairo_boxes_t *boxes,
-		  int dx, int dy)
-{
-    cairo_gl_surface_t *dst = _dst;
-    struct _cairo_boxes_chunk *chunk;
-    int i;
-
-    for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
-	for (i = 0; i < chunk->count; i++) {
-	    cairo_box_t *b = &chunk->base[i];
-	    int x = _cairo_fixed_integer_part (b->p1.x);
-	    int y = _cairo_fixed_integer_part (b->p1.y);
-	    int w = _cairo_fixed_integer_part (b->p2.x) - x;
-	    int h = _cairo_fixed_integer_part (b->p2.y) - y;
-	    cairo_status_t status;
-
-	    status = _cairo_gl_surface_draw_image (dst, image,
-						   x + dx, y + dy,
-						   w, h,
-						   x, y,
-						   TRUE);
-	    if (unlikely (status))
-		return status;
-	}
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-emit_aligned_boxes (cairo_gl_context_t *ctx,
-		    const cairo_boxes_t *boxes)
-{
-    const struct _cairo_boxes_chunk *chunk;
-    cairo_gl_emit_rect_t emit = _cairo_gl_context_choose_emit_rect (ctx);
-    int i;
-
-    for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
-	for (i = 0; i < chunk->count; i++) {
-	    int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
-	    int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
-	    int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
-	    int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
-	    emit (ctx, x1, y1, x2, y2);
-	}
-    }
-}
-
-static cairo_int_status_t
-fill_boxes (void		*_dst,
-	    cairo_operator_t	 op,
-	    const cairo_color_t	*color,
-	    cairo_boxes_t	*boxes)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-
-    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-   _cairo_gl_composite_set_solid_source (&setup, color);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    emit_aligned_boxes (ctx, boxes);
-    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-    return status;
-}
-
-static cairo_int_status_t
-composite_boxes (void			*_dst,
-		 cairo_operator_t	op,
-		 cairo_surface_t	*abstract_src,
-		 cairo_surface_t	*abstract_mask,
-		 int			src_x,
-		 int			src_y,
-		 int			mask_x,
-		 int			mask_y,
-		 int			dst_x,
-		 int			dst_y,
-		 cairo_boxes_t		*boxes,
-		 const cairo_rectangle_int_t  *extents)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-
-    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-    _cairo_gl_composite_set_source_operand (&setup,
-					    source_to_operand (abstract_src));
-    _cairo_gl_operand_translate (&setup.src, dst_x-src_x, dst_y-src_y);
-
-    _cairo_gl_composite_set_mask_operand (&setup,
-					  source_to_operand (abstract_mask));
-    _cairo_gl_operand_translate (&setup.mask, dst_x-mask_x, dst_y-mask_y);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    emit_aligned_boxes (ctx, boxes);
-    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-    return status;
-}
-
-static cairo_int_status_t
-composite (void			*_dst,
-	   cairo_operator_t	op,
-	   cairo_surface_t	*abstract_src,
-	   cairo_surface_t	*abstract_mask,
-	   int			src_x,
-	   int			src_y,
-	   int			mask_x,
-	   int			mask_y,
-	   int			dst_x,
-	   int			dst_y,
-	   unsigned int		width,
-	   unsigned int		height)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-
-    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-    _cairo_gl_composite_set_source_operand (&setup,
-					    source_to_operand (abstract_src));
-    _cairo_gl_operand_translate (&setup.src, dst_x-src_x, dst_y-src_y);
-
-    _cairo_gl_composite_set_mask_operand (&setup,
-					  source_to_operand (abstract_mask));
-    _cairo_gl_operand_translate (&setup.mask, dst_x-mask_x, dst_y-mask_y);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    /* XXX clip */
-    _cairo_gl_context_emit_rect (ctx, dst_x, dst_y, dst_x+width, dst_y+height);
-    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-    return status;
-}
-
-static cairo_int_status_t
-lerp (void			*dst,
-      cairo_surface_t		*src,
-      cairo_surface_t		*mask,
-      int			src_x,
-      int			src_y,
-      int			mask_x,
-      int			mask_y,
-      int			dst_x,
-      int			dst_y,
-      unsigned int		width,
-      unsigned int		height)
-{
-    cairo_int_status_t status;
-
-    /* we could avoid some repetition... */
-    status = composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL,
-			mask_x, mask_y,
-			0, 0,
-			dst_x, dst_y,
-			width, height);
-    if (unlikely (status))
-	return status;
-
-    status = composite (dst, CAIRO_OPERATOR_ADD, src, mask,
-			src_x, src_y,
-			mask_x, mask_y,
-			dst_x, dst_y,
-			width, height);
-    if (unlikely (status))
-	return status;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-traps_to_operand (void *_dst,
-		  const cairo_rectangle_int_t *extents,
-		  cairo_antialias_t	antialias,
-		  cairo_traps_t		*traps,
-		  cairo_gl_operand_t	*operand,
-		  int dst_x, int dst_y)
-{
-    pixman_format_code_t pixman_format;
-    pixman_image_t *pixman_image;
-    cairo_surface_t *image, *mask;
-    cairo_surface_pattern_t pattern;
-    cairo_status_t status;
-
-    pixman_format = antialias != CAIRO_ANTIALIAS_NONE ? PIXMAN_a8 : PIXMAN_a1;
-    pixman_image = pixman_image_create_bits (pixman_format,
-					     extents->width,
-					     extents->height,
-					     NULL, 0);
-    if (unlikely (pixman_image == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    _pixman_image_add_traps (pixman_image, extents->x, extents->y, traps);
-    image = _cairo_image_surface_create_for_pixman_image (pixman_image,
-							  pixman_format);
-    if (unlikely (image->status)) {
-	pixman_image_unref (pixman_image);
-	return image->status;
-    }
-
-    mask = _cairo_surface_create_scratch (_dst,
-					  CAIRO_CONTENT_COLOR_ALPHA,
-					  extents->width,
-					  extents->height,
-					  NULL);
-    if (unlikely (mask->status)) {
-	cairo_surface_destroy (image);
-	return mask->status;
-    }
-
-    status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *)mask,
-					   (cairo_image_surface_t *)image,
-					   0, 0,
-					   extents->width, extents->height,
-					   0, 0,
-					   TRUE);
-    cairo_surface_destroy (image);
-
-    if (unlikely (status))
-	goto error;
-
-    _cairo_pattern_init_for_surface (&pattern, mask);
-    cairo_matrix_init_translate (&pattern.base.matrix,
-				 -extents->x+dst_x, -extents->y+dst_y);
-    pattern.base.filter = CAIRO_FILTER_NEAREST;
-    pattern.base.extend = CAIRO_EXTEND_NONE;
-    status = _cairo_gl_operand_init (operand, &pattern.base, _dst,
-				     &_cairo_unbounded_rectangle,
-				     &_cairo_unbounded_rectangle,
-				     FALSE);
-    _cairo_pattern_fini (&pattern.base);
-
-    if (unlikely (status))
-	goto error;
-
-    operand->texture.owns_surface = (cairo_gl_surface_t *)mask;
-    return CAIRO_STATUS_SUCCESS;
-
-error:
-    cairo_surface_destroy (mask);
-    return status;
-}
-
-static cairo_int_status_t
-composite_traps (void			*_dst,
-		 cairo_operator_t	op,
-		 cairo_surface_t	*abstract_src,
-		 int			src_x,
-		 int			src_y,
-		 int			dst_x,
-		 int			dst_y,
-		 const cairo_rectangle_int_t *extents,
-		 cairo_antialias_t	antialias,
-		 cairo_traps_t		*traps)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_context_t *ctx;
-    cairo_int_status_t status;
-
-    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-    _cairo_gl_composite_set_source_operand (&setup,
-					    source_to_operand (abstract_src));
-    _cairo_gl_operand_translate (&setup.src, -src_x-dst_x, -src_y-dst_y);
-    status = traps_to_operand (_dst, extents, antialias, traps, &setup.mask, dst_x, dst_y);
-    if (unlikely (status))
-	goto FAIL;
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    /* XXX clip */
-    _cairo_gl_context_emit_rect (ctx,
-				 extents->x-dst_x, extents->y-dst_y,
-				 extents->x-dst_x+extents->width,
-				 extents->y-dst_y+extents->height);
-    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-    return status;
-}
-
-static cairo_gl_surface_t *
-tristrip_to_surface (void *_dst,
-		  const cairo_rectangle_int_t *extents,
-		  cairo_antialias_t	antialias,
-		  cairo_tristrip_t	*strip)
-{
-    pixman_format_code_t pixman_format;
-    pixman_image_t *pixman_image;
-    cairo_surface_t *image, *mask;
-    cairo_status_t status;
-
-    pixman_format = antialias != CAIRO_ANTIALIAS_NONE ? PIXMAN_a8 : PIXMAN_a1,
-    pixman_image = pixman_image_create_bits (pixman_format,
-					     extents->width,
-					     extents->height,
-					     NULL, 0);
-    if (unlikely (pixman_image == NULL))
-	return (cairo_gl_surface_t *)_cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _pixman_image_add_tristrip (pixman_image, extents->x, extents->y, strip);
-    image = _cairo_image_surface_create_for_pixman_image (pixman_image,
-							  pixman_format);
-    if (unlikely (image->status)) {
-	pixman_image_unref (pixman_image);
-	return (cairo_gl_surface_t *)image;
-    }
-
-    mask = _cairo_surface_create_scratch (_dst,
-					  CAIRO_CONTENT_COLOR_ALPHA,
-					  extents->width,
-					  extents->height,
-					  NULL);
-    if (unlikely (mask->status)) {
-	cairo_surface_destroy (image);
-	return (cairo_gl_surface_t *)mask;
-    }
-
-    status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *)mask,
-					   (cairo_image_surface_t *)image,
-					   0, 0,
-					   extents->width, extents->height,
-					   0, 0,
-					   TRUE);
-    cairo_surface_destroy (image);
-    if (unlikely (status)) {
-	cairo_surface_destroy (mask);
-	return (cairo_gl_surface_t*)_cairo_surface_create_in_error (status);
-    }
-
-    return (cairo_gl_surface_t*)mask;
-}
-
-static cairo_int_status_t
-composite_tristrip (void		*_dst,
-		    cairo_operator_t	op,
-		    cairo_surface_t	*abstract_src,
-		    int			src_x,
-		    int			src_y,
-		    int			dst_x,
-		    int			dst_y,
-		    const cairo_rectangle_int_t *extents,
-		    cairo_antialias_t	antialias,
-		    cairo_tristrip_t	*strip)
-{
-    cairo_gl_composite_t setup;
-    cairo_gl_context_t *ctx;
-    cairo_gl_surface_t *mask;
-    cairo_int_status_t status;
-
-    mask = tristrip_to_surface (_dst, extents, antialias, strip);
-    if (unlikely (mask->base.status))
-	return mask->base.status;
-
-    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
-    if (unlikely (status))
-	goto FAIL;
-
-    _cairo_gl_composite_set_source_operand (&setup,
-					    source_to_operand (abstract_src));
-
-    //_cairo_gl_composite_set_mask_surface (&setup, mask, 0, 0);
-
-    status = _cairo_gl_composite_begin (&setup, &ctx);
-    if (unlikely (status))
-	goto FAIL;
-
-    /* XXX clip */
-    _cairo_gl_context_emit_rect (ctx,
-				 dst_x, dst_y,
-				 dst_x+extents->width,
-				 dst_y+extents->height);
-    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
-
-FAIL:
-    _cairo_gl_composite_fini (&setup);
-    cairo_surface_destroy (&mask->base);
-    return status;
-}
-
-static cairo_int_status_t
-check_composite (const cairo_composite_rectangles_t *extents)
-{
-    if (! _cairo_gl_operator_is_supported (extents->op))
-	return UNSUPPORTED ("unsupported operator");
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-const cairo_compositor_t *
-_cairo_gl_traps_compositor_get (void)
-{
-    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
-    static cairo_traps_compositor_t compositor;
-
-    if (_cairo_atomic_init_once_enter(&once)) {
-	_cairo_traps_compositor_init (&compositor, &_cairo_fallback_compositor);
-	compositor.acquire = acquire;
-	compositor.release = release;
-	compositor.set_clip_region = set_clip_region;
-	compositor.pattern_to_surface = _cairo_gl_pattern_to_source;
-	compositor.draw_image_boxes = draw_image_boxes;
-	//compositor.copy_boxes = copy_boxes;
-	compositor.fill_boxes = fill_boxes;
-	compositor.check_composite = check_composite;
-	compositor.composite = composite;
-	compositor.lerp = lerp;
-	//compositor.check_composite_boxes = check_composite_boxes;
-	compositor.composite_boxes = composite_boxes;
-	//compositor.check_composite_traps = check_composite_traps;
-	compositor.composite_traps = composite_traps;
-	//compositor.check_composite_tristrip = check_composite_traps;
-	compositor.composite_tristrip = composite_tristrip;
-	compositor.check_composite_glyphs = _cairo_gl_check_composite_glyphs;
-	compositor.composite_glyphs = _cairo_gl_composite_glyphs;
-
-	_cairo_atomic_init_once_leave(&once);
-    }
-
-    return &compositor.base;
-}
diff --git a/src/cairo-gl.h b/src/cairo-gl.h
deleted file mode 100644
index 7cd869c76..000000000
--- a/src/cairo-gl.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* Cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Eric Anholt.
- */
-
-/*
- * cairo-gl.h:
- *
- * The cairo-gl backend provides an implementation of possibly
- * hardware-accelerated cairo rendering by targeting the OpenGL API.
- * The goal of the cairo-gl backend is to provide better performance
- * with equal functionality to cairo-image where possible.  It does
- * not directly provide for applying additional OpenGL effects to
- * cairo surfaces.
- *
- * Cairo-gl allows interoperability with other GL rendering through GL
- * context sharing.  Cairo-gl surfaces are created in reference to a
- * #cairo_device_t, which represents a GL context created by the user.
- * When that GL context is created with its sharePtr set to another
- * context (or vice versa), its objects (textures backing cairo-gl
- * surfaces) can be accessed in the other OpenGL context.  This allows
- * cairo-gl to maintain its drawing state in one context while the
- * user's 3D rendering occurs in the user's other context.
- *
- * However, as only one context can be current to a thread at a time,
- * cairo-gl may make its context current to the thread on any cairo
- * call which interacts with a cairo-gl surface or the cairo-gl
- * device.  As a result, the user must make their own context current
- * between any cairo calls and their own OpenGL rendering.
- **/
-
-#ifndef CAIRO_GL_H
-#define CAIRO_GL_H
-
-#include "cairo.h"
-
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_GLESV3_SURFACE
-
-CAIRO_BEGIN_DECLS
-
-cairo_public cairo_surface_t *
-cairo_gl_surface_create (cairo_device_t *device,
-			 cairo_content_t content,
-			 int width, int height);
-
-cairo_public cairo_surface_t *
-cairo_gl_surface_create_for_texture (cairo_device_t *abstract_device,
-				     cairo_content_t content,
-				     unsigned int tex,
-                                     int width, int height);
-cairo_public void
-cairo_gl_surface_set_size (cairo_surface_t *surface, int width, int height);
-
-cairo_public int
-cairo_gl_surface_get_width (cairo_surface_t *abstract_surface);
-
-cairo_public int
-cairo_gl_surface_get_height (cairo_surface_t *abstract_surface);
-
-cairo_public void
-cairo_gl_surface_swapbuffers (cairo_surface_t *surface);
-
-cairo_public void
-cairo_gl_device_set_thread_aware (cairo_device_t	*device,
-				  cairo_bool_t		 thread_aware);
-
-#if CAIRO_HAS_GLX_FUNCTIONS
-#include <GL/glx.h>
-
-cairo_public cairo_device_t *
-cairo_glx_device_create (Display *dpy, GLXContext gl_ctx);
-
-cairo_public Display *
-cairo_glx_device_get_display (cairo_device_t *device);
-
-cairo_public GLXContext
-cairo_glx_device_get_context (cairo_device_t *device);
-
-cairo_public cairo_surface_t *
-cairo_gl_surface_create_for_window (cairo_device_t *device,
-				    Window win,
-				    int width, int height);
-#endif
-
-#if CAIRO_HAS_WGL_FUNCTIONS
-#include <windows.h>
-
-cairo_public cairo_device_t *
-cairo_wgl_device_create (HGLRC rc);
-
-cairo_public HGLRC
-cairo_wgl_device_get_context (cairo_device_t *device);
-
-cairo_public cairo_surface_t *
-cairo_gl_surface_create_for_dc (cairo_device_t		*device,
-				HDC			 dc,
-				int			 width,
-				int			 height);
-#endif
-
-#if CAIRO_HAS_EGL_FUNCTIONS
-#include <EGL/egl.h>
-
-cairo_public cairo_device_t *
-cairo_egl_device_create (EGLDisplay dpy, EGLContext egl);
-
-cairo_public cairo_surface_t *
-cairo_gl_surface_create_for_egl (cairo_device_t	*device,
-				 EGLSurface	 egl,
-				 int		 width,
-				 int		 height);
-
-cairo_public EGLDisplay
-cairo_egl_device_get_display (cairo_device_t *device);
-
-cairo_public EGLSurface
-cairo_egl_device_get_context (cairo_device_t *device);
-
-#endif
-
-CAIRO_END_DECLS
-
-#else  /* CAIRO_HAS_GL_SURFACE */
-# error Cairo was not compiled with support for the GL backend
-#endif /* CAIRO_HAS_GL_SURFACE */
-
-#endif /* CAIRO_GL_H */
diff --git a/src/cairo-glx-context.c b/src/cairo-glx-context.c
deleted file mode 100644
index 66f5a0d1b..000000000
--- a/src/cairo-glx-context.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-error-private.h"
-
-#include <X11/Xutil.h>
-
-/* XXX needs hooking into XCloseDisplay() */
-
-typedef struct _cairo_glx_context {
-    cairo_gl_context_t base;
-
-    Display *display;
-    Window dummy_window;
-    GLXContext context;
-
-    GLXDrawable previous_drawable;
-    GLXContext previous_context;
-
-    cairo_bool_t has_multithread_makecurrent;
-} cairo_glx_context_t;
-
-typedef struct _cairo_glx_surface {
-    cairo_gl_surface_t base;
-
-    Window win;
-} cairo_glx_surface_t;
-
-static cairo_bool_t
-_context_acquisition_changed_glx_state (cairo_glx_context_t *ctx,
-					GLXDrawable current_drawable)
-{
-    return ctx->previous_drawable != current_drawable ||
-	   ctx->previous_context != ctx->context;
-}
-
-static GLXDrawable
-_glx_get_current_drawable (cairo_glx_context_t *ctx)
-{
-    if (ctx->base.current_target == NULL ||
-	_cairo_gl_surface_is_texture (ctx->base.current_target)) {
-	return ctx->dummy_window;
-    }
-
-    return ((cairo_glx_surface_t *) ctx->base.current_target)->win;
-}
-
-static void
-_glx_query_current_state (cairo_glx_context_t * ctx)
-{
-    ctx->previous_drawable = glXGetCurrentDrawable ();
-    ctx->previous_context = glXGetCurrentContext ();
-
-    /* If any of the values were none, assume they are all none. Not all
-       drivers seem well behaved when it comes to using these values across
-       multiple threads. */
-    if (ctx->previous_drawable == None ||
-	ctx->previous_context == None) {
-	ctx->previous_drawable = None;
-	ctx->previous_context = None;
-    }
-}
-
-static void
-_glx_acquire (void *abstract_ctx)
-{
-    cairo_glx_context_t *ctx = abstract_ctx;
-    GLXDrawable current_drawable = _glx_get_current_drawable (ctx);
-
-    _glx_query_current_state (ctx);
-    if (!_context_acquisition_changed_glx_state (ctx, current_drawable))
-	return;
-
-    glXMakeCurrent (ctx->display, current_drawable, ctx->context);
-}
-
-static void
-_glx_make_current (void *abstract_ctx, cairo_gl_surface_t *abstract_surface)
-{
-    cairo_glx_context_t *ctx = abstract_ctx;
-    cairo_glx_surface_t *surface = (cairo_glx_surface_t *) abstract_surface;
-
-    /* Set the window as the target of our context. */
-    glXMakeCurrent (ctx->display, surface->win, ctx->context);
-}
-
-static void
-_glx_release (void *abstract_ctx)
-{
-    cairo_glx_context_t *ctx = abstract_ctx;
-
-    if (ctx->has_multithread_makecurrent || !ctx->base.thread_aware ||
-	!_context_acquisition_changed_glx_state (ctx,
-						_glx_get_current_drawable (ctx))) {
-	return;
-    }
-
-    glXMakeCurrent (ctx->display, None, None);
-}
-
-static void
-_glx_swap_buffers (void *abstract_ctx,
-		   cairo_gl_surface_t *abstract_surface)
-{
-    cairo_glx_context_t *ctx = abstract_ctx;
-    cairo_glx_surface_t *surface = (cairo_glx_surface_t *) abstract_surface;
-
-    glXSwapBuffers (ctx->display, surface->win);
-}
-
-static void
-_glx_destroy (void *abstract_ctx)
-{
-    cairo_glx_context_t *ctx = abstract_ctx;
-
-    if (ctx->dummy_window != None)
-	XDestroyWindow (ctx->display, ctx->dummy_window);
-
-    glXMakeCurrent (ctx->display, None, None);
-}
-
-static cairo_status_t
-_glx_dummy_window (Display *dpy, GLXContext gl_ctx, Window *dummy)
-{
-    int attr[3] = { GLX_FBCONFIG_ID, 0, None };
-    GLXFBConfig *config;
-    XVisualInfo *vi;
-    Colormap cmap;
-    XSetWindowAttributes swa;
-    Window win = None;
-    int cnt;
-
-    /* Create a dummy window created for the target GLX context that we can
-     * use to query the available GL/GLX extensions.
-     */
-    glXQueryContext (dpy, gl_ctx, GLX_FBCONFIG_ID, &attr[1]);
-
-    cnt = 0;
-    config = glXChooseFBConfig (dpy, DefaultScreen (dpy), attr, &cnt);
-    if (unlikely (cnt == 0))
-	return _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
-
-    vi = glXGetVisualFromFBConfig (dpy, config[0]);
-    XFree (config);
-
-    if (unlikely (vi == NULL))
-	return _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
-
-    cmap = XCreateColormap (dpy,
-			    RootWindow (dpy, vi->screen),
-			    vi->visual,
-			    AllocNone);
-    swa.colormap = cmap;
-    swa.border_pixel = 0;
-    win = XCreateWindow (dpy, RootWindow (dpy, vi->screen),
-			 -1, -1, 1, 1, 0,
-			 vi->depth,
-			 InputOutput,
-			 vi->visual,
-			 CWBorderPixel | CWColormap, &swa);
-    XFreeColormap (dpy, cmap);
-    XFree (vi);
-
-    XFlush (dpy);
-    if (unlikely (! glXMakeCurrent (dpy, win, gl_ctx))) {
-	XDestroyWindow (dpy, win);
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    *dummy = win;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_device_t *
-cairo_glx_device_create (Display *dpy, GLXContext gl_ctx)
-{
-    cairo_glx_context_t *ctx;
-    cairo_status_t status;
-    Window dummy = None;
-    const char *glx_extensions;
-
-    ctx = calloc (1, sizeof (cairo_glx_context_t));
-    if (unlikely (ctx == NULL))
-	return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
-
-    /* glx_dummy_window will call glXMakeCurrent, so we need to
-     *  query the current state of the context now. */
-    _glx_query_current_state (ctx);
-
-    status = _glx_dummy_window (dpy, gl_ctx, &dummy);
-    if (unlikely (status)) {
-	free (ctx);
-	return _cairo_gl_context_create_in_error (status);
-    }
-
-    ctx->display = dpy;
-    ctx->dummy_window = dummy;
-    ctx->context = gl_ctx;
-
-    ctx->base.acquire = _glx_acquire;
-    ctx->base.release = _glx_release;
-    ctx->base.make_current = _glx_make_current;
-    ctx->base.swap_buffers = _glx_swap_buffers;
-    ctx->base.destroy = _glx_destroy;
-
-    status = _cairo_gl_dispatch_init (&ctx->base.dispatch,
-				      (cairo_gl_get_proc_addr_func_t) glXGetProcAddress);
-    if (unlikely (status)) {
-	free (ctx);
-	return _cairo_gl_context_create_in_error (status);
-    }
-
-    status = _cairo_gl_context_init (&ctx->base);
-    if (unlikely (status)) {
-	free (ctx);
-	return _cairo_gl_context_create_in_error (status);
-    }
-
-    glx_extensions = glXQueryExtensionsString (dpy, DefaultScreen (dpy));
-    if (strstr(glx_extensions, "GLX_MESA_multithread_makecurrent")) {
-	ctx->has_multithread_makecurrent = TRUE;
-    }
-
-    ctx->base.release (ctx);
-
-    return &ctx->base.base;
-}
-
-Display *
-cairo_glx_device_get_display (cairo_device_t *device)
-{
-    cairo_glx_context_t *ctx;
-
-    if (device->backend->type != CAIRO_DEVICE_TYPE_GL) {
-	_cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
-	return NULL;
-    }
-
-    ctx = (cairo_glx_context_t *) device;
-
-    return ctx->display;
-}
-
-GLXContext
-cairo_glx_device_get_context (cairo_device_t *device)
-{
-    cairo_glx_context_t *ctx;
-
-    if (device->backend->type != CAIRO_DEVICE_TYPE_GL) {
-	_cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
-	return NULL;
-    }
-
-    ctx = (cairo_glx_context_t *) device;
-
-    return ctx->context;
-}
-
-cairo_surface_t *
-cairo_gl_surface_create_for_window (cairo_device_t	*device,
-				    Window		 win,
-				    int			 width,
-				    int			 height)
-{
-    cairo_glx_surface_t *surface;
-
-    if (unlikely (device->status))
-	return _cairo_surface_create_in_error (device->status);
-
-    if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
-
-    if (width <= 0 || height <= 0)
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
-
-    surface = calloc (1, sizeof (cairo_glx_surface_t));
-    if (unlikely (surface == NULL))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _cairo_gl_surface_init (device, &surface->base,
-			    CAIRO_CONTENT_COLOR_ALPHA, width, height);
-    surface->win = win;
-
-    return &surface->base.base;
-}
diff --git a/src/cairo-mutex-list-private.h b/src/cairo-mutex-list-private.h
index 70d566ebb..af5cc0517 100644
--- a/src/cairo-mutex-list-private.h
+++ b/src/cairo-mutex-list-private.h
@@ -64,10 +64,6 @@ CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex)
 CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex)
 #endif
 
-#if CAIRO_HAS_GL_SURFACE
-CAIRO_MUTEX_DECLARE (_cairo_gl_context_mutex)
-#endif
-
 #if !defined (HAS_ATOMIC_OPS) || defined (ATOMIC_OP_NEEDS_MEMORY_BARRIER)
 CAIRO_MUTEX_DECLARE (_cairo_atomic_mutex)
 #endif
diff --git a/src/cairo-wgl-context.c b/src/cairo-wgl-context.c
deleted file mode 100644
index b6cd803a0..000000000
--- a/src/cairo-wgl-context.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005 Red Hat, Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Contributor(s):
- *	Carl Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- *	Zoxc <zoxc32 at gmail.com>
- */
-
-#include "cairoint.h"
-
-#include "cairo-gl-private.h"
-
-#include "cairo-error-private.h"
-
-#include <windows.h>
-
-typedef struct _cairo_wgl_context {
-    cairo_gl_context_t base;
-
-    HDC dummy_dc;
-    HWND dummy_wnd;
-    HGLRC rc;
-
-    HDC prev_dc;
-    HGLRC prev_rc;
-} cairo_wgl_context_t;
-
-typedef struct _cairo_wgl_surface {
-    cairo_gl_surface_t base;
-
-    HDC dc;
-} cairo_wgl_surface_t;
-
-static void
-_wgl_acquire (void *abstract_ctx)
-{
-    cairo_wgl_context_t *ctx = abstract_ctx;
-
-    HDC current_dc;
-
-    ctx->prev_dc = wglGetCurrentDC ();
-    ctx->prev_rc = wglGetCurrentContext ();
-
-    if (ctx->base.current_target == NULL ||
-        _cairo_gl_surface_is_texture (ctx->base.current_target))
-    {
-        current_dc = ctx->dummy_dc;
-    }
-    else
-    {
-        cairo_wgl_surface_t *surface = (cairo_wgl_surface_t *) ctx->base.current_target;
-        current_dc = surface->dc;
-    }
-
-    if (ctx->prev_dc != current_dc ||
-	(ctx->prev_rc != ctx->rc &&
-	 current_dc != ctx->dummy_dc))
-    {
-        wglMakeCurrent (current_dc, ctx->rc);
-    }
-}
-
-static void
-_wgl_make_current (void *abstract_ctx, cairo_gl_surface_t *abstract_surface)
-{
-    cairo_wgl_context_t *ctx = abstract_ctx;
-    cairo_wgl_surface_t *surface = (cairo_wgl_surface_t *) abstract_surface;
-
-    /* Set the window as the target of our context. */
-    wglMakeCurrent (surface->dc, ctx->rc);
-}
-
-static void
-_wgl_release (void *abstract_ctx)
-{
-    cairo_wgl_context_t *ctx = abstract_ctx;
-
-    if (ctx->prev_dc != wglGetCurrentDC () ||
-        ctx->prev_rc != wglGetCurrentContext ())
-    {
-        wglMakeCurrent (ctx->prev_dc,
-                        ctx->prev_rc);
-    }
-}
-
-static void
-_wgl_swap_buffers (void *abstract_ctx,
-		   cairo_gl_surface_t *abstract_surface)
-{
-    cairo_wgl_surface_t *surface = (cairo_wgl_surface_t *) abstract_surface;
-
-    SwapBuffers (surface->dc);
-}
-
-static void
-_wgl_destroy (void *abstract_ctx)
-{
-    cairo_wgl_context_t *ctx = abstract_ctx;
-
-    if (ctx->dummy_dc != 0) {	
-        wglMakeCurrent (ctx->dummy_dc, 0);
-        ReleaseDC (ctx->dummy_wnd, ctx->dummy_dc);
-        DestroyWindow (ctx->dummy_wnd);
-    }
-}
-
-static cairo_status_t
-_wgl_dummy_ctx (cairo_wgl_context_t *ctx)
-{
-    WNDCLASSEXA wincl;
-    PIXELFORMATDESCRIPTOR pfd;
-    int format;
-    HDC dc;
-
-    ZeroMemory (&wincl, sizeof (WNDCLASSEXA));
-    wincl.cbSize = sizeof (WNDCLASSEXA);
-    wincl.hInstance = GetModuleHandle (0);
-    wincl.lpszClassName = "cairo_wgl_context_dummy";
-    wincl.lpfnWndProc = DefWindowProcA;
-    wincl.style = CS_OWNDC;
-
-    RegisterClassExA (&wincl);
-
-    ctx->dummy_wnd = CreateWindowA ("cairo_wgl_context_dummy", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-    ctx->dummy_dc = GetDC (ctx->dummy_wnd);
-
-    ZeroMemory (&pfd, sizeof (PIXELFORMATDESCRIPTOR));
-    pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
-    pfd.nVersion = 1;
-    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
-    pfd.iPixelType = PFD_TYPE_RGBA;
-    pfd.cColorBits = 24;
-    pfd.cDepthBits = 16;
-    pfd.iLayerType = PFD_MAIN_PLANE;
-
-    format = ChoosePixelFormat (ctx->dummy_dc, &pfd);
-    SetPixelFormat (ctx->dummy_dc, format, &pfd);
-
-    wglMakeCurrent(ctx->dummy_dc, ctx->rc);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_device_t *
-cairo_wgl_device_create (HGLRC rc)
-{
-    cairo_wgl_context_t *ctx;
-    cairo_status_t status;
-
-    ctx = calloc (1, sizeof (cairo_wgl_context_t));
-    if (unlikely (ctx == NULL))
-        return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
-
-    ctx->rc = rc;
-    ctx->prev_dc = 0;
-    ctx->prev_rc = 0;
-
-    status = _wgl_dummy_ctx (ctx);
-    if (unlikely (status)) {
-        free (ctx);
-        return _cairo_gl_context_create_in_error (status);
-    }
-
-    ctx->base.acquire = _wgl_acquire;
-    ctx->base.release = _wgl_release;
-    ctx->base.make_current = _wgl_make_current;
-    ctx->base.swap_buffers = _wgl_swap_buffers;
-    ctx->base.destroy = _wgl_destroy;
-
-    status = _cairo_gl_dispatch_init (&ctx->base.dispatch,
-				      (cairo_gl_get_proc_addr_func_t) wglGetProcAddress);
-    if (unlikely (status)) {
-	free (ctx);
-	return _cairo_gl_context_create_in_error (status);
-    }
-
-    status = _cairo_gl_context_init (&ctx->base);
-    if (unlikely (status)) {
-        free (ctx);
-        return _cairo_gl_context_create_in_error (status);
-    }
-
-    ctx->base.release (ctx);
-
-    return &ctx->base.base;
-}
-
-HGLRC
-cairo_wgl_device_get_context (cairo_device_t *device)
-{
-    cairo_wgl_context_t *ctx;
-
-    if (device->backend->type != CAIRO_DEVICE_TYPE_GL) {
-        _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
-        return NULL;
-    }
-
-    ctx = (cairo_wgl_context_t *) device;
-
-    return ctx->rc;
-}
-
-cairo_surface_t *
-cairo_gl_surface_create_for_dc (cairo_device_t	*device,
-				HDC			 dc,
-				int			 width,
-				int			 height)
-{
-    cairo_wgl_surface_t *surface;
-
-    if (unlikely (device->status))
-        return _cairo_surface_create_in_error (device->status);
-
-    if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
-        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
-
-    if (width <= 0 || height <= 0)
-        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
-
-    surface = calloc (1, sizeof (cairo_wgl_surface_t));
-    if (unlikely (surface == NULL))
-        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _cairo_gl_surface_init (device, &surface->base,
-			    CAIRO_CONTENT_COLOR_ALPHA, width, height);
-    surface->dc = dc;
-
-    return &surface->base.base;
-}
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index c58821a48..a4441dc46 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -1242,12 +1242,6 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
 	    }
 	}
     }
-#endif
-#if CAIRO_HAS_GL_FUNCTIONS
-    else if (source->type == CAIRO_SURFACE_TYPE_GL)
-    {
-	/* pixmap from texture */
-    }
 #endif
     else if (source->type == CAIRO_SURFACE_TYPE_RECORDING)
     {
diff --git a/src/cairo.h b/src/cairo.h
index a9b423b28..ca7d67836 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -157,9 +157,7 @@ typedef struct _cairo_surface cairo_surface_t;
  *
  * A #cairo_device_t represents the driver interface for drawing
  * operations to a #cairo_surface_t.  There are different subtypes of
- * #cairo_device_t for different drawing backends; for example,
- * cairo_egl_device_create() creates a device that wraps an EGL display and
- * context.
+ * #cairo_device_t for different drawing backends.
  *
  * The type of a device can be queried with cairo_device_get_type().
  *
diff --git a/src/meson.build b/src/meson.build
index 768dba143..db9bf41e4 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -182,21 +182,6 @@ cairo_feature_sources = {
   'cairo-win32-dwrite-font': [
     'win32/cairo-dwrite-font.cpp',
   ],
-  'cairo-gl': [
-    'cairo-gl-composite.c',
-    'cairo-gl-device.c',
-    'cairo-gl-dispatch.c',
-    'cairo-gl-glyphs.c',
-    'cairo-gl-gradient.c',
-    'cairo-gl-info.c',
-    'cairo-gl-msaa-compositor.c',
-    'cairo-gl-operand.c',
-    'cairo-gl-shaders.c',
-    'cairo-gl-source.c',
-    'cairo-gl-spans-compositor.c',
-    'cairo-gl-surface.c',
-    'cairo-gl-traps-compositor.c',
-  ],
   'cairo-script': [
     'cairo-script-surface.c',
   ],
@@ -210,15 +195,6 @@ cairo_feature_sources = {
   'cairo-svg': [
     'cairo-svg-surface.c',
   ],
-  'cairo-egl': [
-    'cairo-egl-context.c',
-  ],
-  'cairo-glx': [
-    'cairo-glx-context.c',
-  ],
-  'cairo-wgl': [
-    'cairo-wgl-context.c',
-  ],
   'cairo-xml': [
     'cairo-xml-surface.c',
   ],
diff --git a/test/api-special-cases.c b/test/api-special-cases.c
index ce54200b7..d926aa652 100644
--- a/test/api-special-cases.c
+++ b/test/api-special-cases.c
@@ -63,9 +63,6 @@
 
 #include "cairo-test.h"
 
-#if CAIRO_HAS_GL_SURFACE
-#include <cairo-gl.h>
-#endif
 #if CAIRO_HAS_PDF_SURFACE
 #include <cairo-pdf.h>
 #endif
@@ -1312,38 +1309,6 @@ test_cairo_tee_surface_index (cairo_surface_t *surface)
 
 #endif /* CAIRO_HAS_TEE_SURFACE */
 
-#if CAIRO_HAS_GL_SURFACE
-
-static cairo_test_status_t
-test_cairo_gl_surface_set_size (cairo_surface_t *surface)
-{
-    cairo_gl_surface_set_size (surface, 5, 5);
-    return CAIRO_TEST_SUCCESS;
-}
-
-static cairo_test_status_t
-test_cairo_gl_surface_get_width (cairo_surface_t *surface)
-{
-    unsigned int width = cairo_gl_surface_get_width (surface);
-    return width == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_GL) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
-}
-
-static cairo_test_status_t
-test_cairo_gl_surface_get_height (cairo_surface_t *surface)
-{
-    unsigned int height = cairo_gl_surface_get_height (surface);
-    return height == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_GL) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
-}
-
-static cairo_test_status_t
-test_cairo_gl_surface_swapbuffers (cairo_surface_t *surface)
-{
-    cairo_gl_surface_swapbuffers (surface);
-    return CAIRO_TEST_SUCCESS;
-}
-
-#endif /* CAIRO_HAS_GL_SURFACE */
-
 #if CAIRO_HAS_PDF_SURFACE
 
 static cairo_test_status_t
@@ -1675,12 +1640,6 @@ struct {
     TEST (cairo_tee_surface_remove, CAIRO_SURFACE_TYPE_TEE, TRUE),
     TEST (cairo_tee_surface_index, CAIRO_SURFACE_TYPE_TEE, FALSE),
 #endif
-#if CAIRO_HAS_GL_SURFACE
-    TEST (cairo_gl_surface_set_size, CAIRO_SURFACE_TYPE_GL, TRUE),
-    TEST (cairo_gl_surface_get_width, CAIRO_SURFACE_TYPE_GL, FALSE),
-    TEST (cairo_gl_surface_get_height, CAIRO_SURFACE_TYPE_GL, FALSE),
-    TEST (cairo_gl_surface_swapbuffers, CAIRO_SURFACE_TYPE_GL, TRUE),
-#endif
 #if CAIRO_HAS_PDF_SURFACE
     TEST (cairo_pdf_surface_restrict_to_version, CAIRO_SURFACE_TYPE_PDF, TRUE),
     TEST (cairo_pdf_surface_set_size, CAIRO_SURFACE_TYPE_PDF, TRUE),
diff --git a/test/egl-oversized-surface.c b/test/egl-oversized-surface.c
deleted file mode 100644
index cb85a628d..000000000
--- a/test/egl-oversized-surface.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright © 2014 Samsung Electronics
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Author: Ravi Nanjundappa <nravi.n at samsung.com>
- */
-
-/*
- * This test exercises error scenario for over sized egl surface
- *
- */
-
-#include "cairo-test.h"
-#include <cairo-gl.h>
-#include <assert.h>
-#include <limits.h>
-
-static cairo_test_status_t
-preamble (cairo_test_context_t *test_ctx)
-{
-    EGLint rgba_attribs[] = {
-	EGL_RED_SIZE, 8,
-	EGL_GREEN_SIZE, 8,
-	EGL_BLUE_SIZE, 8,
-	EGL_ALPHA_SIZE, 8,
-	EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-#if CAIRO_HAS_GL_SURFACE
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
-#elif CAIRO_HAS_GLESV2_SURFACE
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#endif
-	EGL_NONE
-    };
-    const EGLint ctx_attribs[] = {
-#if CAIRO_HAS_GLESV2_SURFACE
-	EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-	EGL_NONE
-    };
-
-    EGLDisplay dpy;
-    EGLContext ctx;
-    EGLConfig config;
-    EGLint numConfigs;
-    int major, minor;
-    cairo_device_t *device;
-    cairo_surface_t *oversized_surface;
-    cairo_test_status_t test_status = CAIRO_TEST_SUCCESS;
-
-    dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
-    if (! eglInitialize (dpy, &major, &minor)) {
-	test_status = CAIRO_TEST_UNTESTED;
-	goto CLEANUP_1;
-    }
-
-    eglChooseConfig (dpy, rgba_attribs, &config, 1, &numConfigs);
-    if (numConfigs == 0) {
-	test_status = CAIRO_TEST_UNTESTED;
-	goto CLEANUP_1;
-    }
-
-#if CAIRO_HAS_GL_SURFACE
-    eglBindAPI (EGL_OPENGL_API);
-#elif CAIRO_HAS_GLESV2_SURFACE
-    eglBindAPI (EGL_OPENGL_ES_API);
-#endif
-
-   ctx = eglCreateContext (dpy, config, EGL_NO_CONTEXT,
-				  ctx_attribs);
-    if (ctx == EGL_NO_CONTEXT) {
-	test_status = CAIRO_TEST_UNTESTED;
-	goto CLEANUP_2;
-    }
-
-    device = cairo_egl_device_create (dpy, ctx);
-
-    oversized_surface = cairo_gl_surface_create (device, CAIRO_CONTENT_COLOR_ALPHA, INT_MAX, INT_MAX);
-    if (cairo_surface_status (oversized_surface) != CAIRO_STATUS_INVALID_SIZE)
-        test_status = CAIRO_TEST_FAILURE;
-
-    cairo_device_destroy (device);
-    eglDestroyContext (dpy, ctx);
-    eglMakeCurrent (dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    ctx = EGL_NO_CONTEXT;
-
-CLEANUP_2:
-    eglTerminate (dpy);
-
-CLEANUP_1:
-    return test_status;
-}
-
-CAIRO_TEST (egl_oversized_surface,
-	    "Test that creating a surface beyond texture limits results in an error surface",
-	    "egl", /* keywords */
-	    NULL, /* requirements */
-	    0, 0,
-	    preamble, NULL)
diff --git a/test/egl-surface-source.c b/test/egl-surface-source.c
deleted file mode 100644
index 4a84d7042..000000000
--- a/test/egl-surface-source.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright © 2014 Samsung Electronics
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Author: Ravi Nanjundappa <nravi.n at samsung.com>
- */
-
-/*
- * This case tests using a EGL surface as the source
- *
- */
-
-#include "cairo-test.h"
-#include <cairo-gl.h>
-
-#include "surface-source.c"
-
-struct closure {
-    EGLDisplay dpy;
-    EGLContext ctx;
-};
-
-static void
-cleanup (void *data)
-{
-    struct closure *arg = data;
-
-    eglDestroyContext (arg->dpy, arg->ctx);
-    eglMakeCurrent (arg->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    eglTerminate (arg->dpy);
-
-    free (arg);
-}
-
-static cairo_surface_t *
-create_source_surface (int size)
-{
-    EGLint config_attribs[] = {
-	EGL_RED_SIZE, 8,
-	EGL_GREEN_SIZE, 8,
-	EGL_BLUE_SIZE, 8,
-	EGL_ALPHA_SIZE, 8,
-	EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-#if CAIRO_HAS_GL_SURFACE
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
-#elif CAIRO_HAS_GLESV2_SURFACE
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#endif
-	EGL_NONE
-    };
-    const EGLint ctx_attribs[] = {
-#if CAIRO_HAS_GLESV2_SURFACE
-	EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-	EGL_NONE
-    };
-
-    struct closure *arg;
-    cairo_device_t *device;
-    cairo_surface_t *surface;
-    EGLConfig config;
-    EGLint numConfigs;
-    EGLDisplay dpy;
-    EGLContext ctx;
-    int major, minor;
-
-    dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
-    if (! eglInitialize (dpy, &major, &minor)) {
-	return NULL;
-    }
-
-    eglChooseConfig (dpy, config_attribs, &config, 1, &numConfigs);
-    if (numConfigs == 0) {
-	return NULL;
-    }
-
-#if CAIRO_HAS_GL_SURFACE
-    eglBindAPI (EGL_OPENGL_API);
-#elif CAIRO_HAS_GLESV2_SURFACE
-    eglBindAPI (EGL_OPENGL_ES_API);
-#endif
-
-   ctx = eglCreateContext (dpy, config, EGL_NO_CONTEXT,
-				  ctx_attribs);
-    if (ctx == EGL_NO_CONTEXT) {
-	eglTerminate (dpy);
-	return NULL;
-    }
-
-    arg = xmalloc (sizeof (struct closure));
-    arg->dpy = dpy;
-    arg->ctx = ctx;
-    device = cairo_egl_device_create (dpy, ctx);
-    if (cairo_device_set_user_data (device,
-				    (cairo_user_data_key_t *) cleanup,
-				    arg,
-				    cleanup))
-    {
-	cleanup (arg);
-	return NULL;
-    }
-
-    surface = cairo_gl_surface_create (device,
-				       CAIRO_CONTENT_COLOR_ALPHA,
-				       size, size);
-    cairo_device_destroy (device);
-
-    return surface;
-}
-
-CAIRO_TEST (egl_surface_source,
-	    "Test using a EGL surface as the source",
-	    "source", /* keywords */
-	    NULL, /* requirements */
-	    SIZE, SIZE,
-	    preamble, draw)
diff --git a/test/error-setters.c b/test/error-setters.c
index c69a6d89b..ecbb78fde 100644
--- a/test/error-setters.c
+++ b/test/error-setters.c
@@ -29,9 +29,6 @@
 
 #include "cairo-test.h"
 
-#if CAIRO_HAS_GL_SURFACE
-#include <cairo-gl.h>
-#endif
 #if CAIRO_HAS_PDF_SURFACE
 #include <cairo-pdf.h>
 #endif
@@ -53,11 +50,6 @@ preamble (cairo_test_context_t *ctx)
     /* get the error surface */
     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, INT_MAX, INT_MAX);
 
-#if CAIRO_HAS_GL_SURFACE
-    cairo_gl_surface_set_size (surface, 0, 0);
-    cairo_gl_surface_swapbuffers (surface);
-#endif
-
 #if CAIRO_HAS_PDF_SURFACE
     cairo_pdf_surface_restrict_to_version (surface, CAIRO_PDF_VERSION_1_4);
     cairo_pdf_surface_set_size (surface, 0, 0);
diff --git a/test/gl-device-release.c b/test/gl-device-release.c
deleted file mode 100644
index 7f554be30..000000000
--- a/test/gl-device-release.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright © 2012 Igalia S.L.
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005 Red Hat, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of
- * Chris Wilson not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Chris Wilson makes no representations about the
- * suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * IGALIA S.L. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Martin Robinson <mrobinson at igalia.com>
- */
-
-#include "cairo-test.h"
-#include <cairo-gl.h>
-#include <assert.h>
-
-static Window
-create_test_window (Display *display,
-		    GLXContext glx_context,
-		    XVisualInfo *visual_info)
-{
-    Colormap colormap;
-    XSetWindowAttributes window_attributes;
-    Window window = None;
-
-    colormap = XCreateColormap (display,
-			    RootWindow (display, visual_info->screen),
-			    visual_info->visual,
-			    AllocNone);
-    window_attributes.colormap = colormap;
-    window_attributes.border_pixel = 0;
-    window = XCreateWindow (display, RootWindow (display, visual_info->screen),
-			    -1, -1, 1, 1, 0,
-			    visual_info->depth,
-			    InputOutput,
-			    visual_info->visual,
-			    CWBorderPixel | CWColormap, &window_attributes);
-    XFreeColormap (display, colormap);
-
-    XFlush (display);
-    return window;
-}
-
-static cairo_bool_t
-multithread_makecurrent_available (Display *display)
-{
-    const char *extensions = glXQueryExtensionsString (display,
-						       DefaultScreen (display));
-    return !! strstr(extensions, "GLX_MESA_multithread_makecurrent");
-}
-
-static void
-draw_to_surface (cairo_surface_t *surface)
-{
-    cairo_t *cr = cairo_create (surface);
-    cairo_paint (cr);
-    cairo_destroy (cr);
-}
-
-static cairo_test_status_t
-preamble (cairo_test_context_t *test_ctx)
-{
-    int rgba_attribs[] = {
-	GLX_RGBA,
-	GLX_RED_SIZE, 1,
-	GLX_GREEN_SIZE, 1,
-	GLX_BLUE_SIZE, 1,
-	GLX_ALPHA_SIZE, 1,
-	GLX_DOUBLEBUFFER,
-	None
-    };
-
-    XVisualInfo *visual_info;
-    GLXContext glx_context;
-    cairo_device_t *device;
-    Display *display;
-    Window test_window;
-    cairo_surface_t *window_surface;
-    cairo_bool_t has_multithread_makecurrent;
-
-    display = XOpenDisplay (NULL);
-    if (display == NULL)
-	return CAIRO_TEST_UNTESTED;
-
-    visual_info = glXChooseVisual (display, DefaultScreen (display), rgba_attribs);
-    if (visual_info == NULL) {
-	XCloseDisplay (display);
-	return CAIRO_TEST_UNTESTED;
-    }
-
-    glx_context = glXCreateContext (display, visual_info, NULL, True);
-    if (glx_context == NULL) {
-	XCloseDisplay (display);
-	return CAIRO_TEST_UNTESTED;
-    }
-
-    test_window = create_test_window (display, glx_context, visual_info);
-    XFree (visual_info);
-    if (test_window == None) {
-	XCloseDisplay (display);
-	return CAIRO_TEST_UNTESTED;
-    }
-
-    has_multithread_makecurrent = multithread_makecurrent_available (display);
-
-    glXMakeCurrent (display, None, None);
-
-    /* Creating the device should actually change the GL context, because of
-     * the creation/activation of a dummy window used for texture surfaces. */
-    device = cairo_glx_device_create (display, glx_context);
-
-    /* It's important that when multithread_makecurrent isn't available the
-     * Cairo backend clears the current context, so that the dummy texture
-     * window is not active while the device is unlocked. */
-    if (has_multithread_makecurrent) {
-	assert (None != glXGetCurrentDrawable ());
-	assert (display == glXGetCurrentDisplay ());
-	assert (glx_context == glXGetCurrentContext ());
-    } else {
-	assert (None == glXGetCurrentDrawable ());
-	assert (None == glXGetCurrentDisplay ());
-	assert (None == glXGetCurrentContext ());
-    }
-
-    window_surface = cairo_gl_surface_create_for_window (device, test_window,
-							 1, 1);
-    assert (cairo_surface_status (window_surface) == CAIRO_STATUS_SUCCESS);
-
-    draw_to_surface (window_surface);
-    if (has_multithread_makecurrent) {
-	assert (test_window == glXGetCurrentDrawable ());
-	assert (display == glXGetCurrentDisplay ());
-	assert (glx_context == glXGetCurrentContext ());
-    } else {
-	assert (None == glXGetCurrentDrawable ());
-	assert (None == glXGetCurrentDisplay ());
-	assert (None == glXGetCurrentContext ());
-    }
-
-    /* In this case, drawing to the window surface will not change the current
-     * GL context, so Cairo setting the current surface and context to none. */
-    glXMakeCurrent (display, test_window, glx_context);
-    draw_to_surface (window_surface);
-    assert (test_window == glXGetCurrentDrawable ());
-    assert (display == glXGetCurrentDisplay ());
-    assert (glx_context == glXGetCurrentContext ());
-
-    /* There should be no context change when destroying the device. */
-    cairo_device_destroy (device);
-    assert (test_window == glXGetCurrentDrawable ());
-    assert (display == glXGetCurrentDisplay ());
-    assert (glx_context == glXGetCurrentContext ());
-
-    glXDestroyContext(display, glx_context);
-    XDestroyWindow (display, test_window);
-    XCloseDisplay (display);
-
-    return CAIRO_TEST_SUCCESS;
-}
-
-CAIRO_TEST (gl_device_creation_changes_context,
-	    "Test that using the Cairo GL backend leaves the current GL context in the appropriate state",
-	    "gl", /* keywords */
-	    NULL, /* requirements */
-	    0, 0,
-	    preamble, NULL)
diff --git a/test/gl-oversized-surface.c b/test/gl-oversized-surface.c
deleted file mode 100644
index 4c46efd80..000000000
--- a/test/gl-oversized-surface.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright © 2012 Igalia S.L.
- * Copyright © 2009 Eric Anholt
- * Copyright © 2009 Chris Wilson
- * Copyright © 2005 Red Hat, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of
- * Chris Wilson not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Chris Wilson makes no representations about the
- * suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * IGALIA S.L. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Martin Robinson <mrobinson at igalia.com>
- */
-
-#include "cairo-test.h"
-#include <cairo-gl.h>
-#include <assert.h>
-#include <limits.h>
-
-static cairo_test_status_t
-preamble (cairo_test_context_t *test_ctx)
-{
-    int rgba_attribs[] = {
-	GLX_RGBA,
-	GLX_RED_SIZE, 1,
-	GLX_GREEN_SIZE, 1,
-	GLX_BLUE_SIZE, 1,
-	GLX_ALPHA_SIZE, 1,
-	GLX_DOUBLEBUFFER,
-	None
-    };
-
-    Display *display;
-    XVisualInfo *visual_info;
-    GLXContext glx_context;
-    cairo_device_t *device;
-    cairo_surface_t *oversized_surface;
-    cairo_test_status_t test_status = CAIRO_TEST_SUCCESS;
-
-    display = XOpenDisplay (NULL);
-    if (display == NULL)
-	return CAIRO_TEST_UNTESTED;
-
-    visual_info = glXChooseVisual (display, DefaultScreen (display), rgba_attribs);
-    if (visual_info == NULL) {
-	XCloseDisplay (display);
-	return CAIRO_TEST_UNTESTED;
-    }
-
-    glx_context = glXCreateContext (display, visual_info, NULL, True);
-    if (glx_context == NULL) {
-	XCloseDisplay (display);
-	return CAIRO_TEST_UNTESTED;
-    }
-
-    device = cairo_glx_device_create (display, glx_context);
-
-    oversized_surface = cairo_gl_surface_create (device, CAIRO_CONTENT_COLOR_ALPHA, INT_MAX, INT_MAX);
-    if (cairo_surface_status (oversized_surface) != CAIRO_STATUS_INVALID_SIZE)
-        test_status = CAIRO_TEST_FAILURE;
-
-    cairo_device_destroy (device);
-    glXDestroyContext(display, glx_context);
-    XCloseDisplay (display);
-
-    return test_status;
-}
-
-CAIRO_TEST (gl_oversized_surface,
-	    "Test that creating a surface beyond texture limits results in an error surface",
-	    "gl", /* keywords */
-	    NULL, /* requirements */
-	    0, 0,
-	    preamble, NULL)
diff --git a/test/gl-surface-source.c b/test/gl-surface-source.c
deleted file mode 100644
index 09d4d9c47..000000000
--- a/test/gl-surface-source.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright © 2008 Chris Wilson
- * Copyright © 2010 Intel Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of
- * Chris Wilson not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Chris Wilson makes no representations about the
- * suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Chris Wilson <chris at chris-wilson.co.uk>
- */
-
-#include "cairo-test.h"
-#include <cairo-gl.h>
-
-#include "surface-source.c"
-
-struct closure {
-    Display *dpy;
-    GLXContext ctx;
-};
-
-static void
-cleanup (void *data)
-{
-    struct closure *arg = data;
-
-    glXDestroyContext (arg->dpy, arg->ctx);
-    XCloseDisplay (arg->dpy);
-
-    free (arg);
-}
-
-static cairo_surface_t *
-create_source_surface (int size)
-{
-    int rgba_attribs[] = {
-	GLX_RGBA,
-	GLX_RED_SIZE, 1,
-	GLX_GREEN_SIZE, 1,
-	GLX_BLUE_SIZE, 1,
-	GLX_ALPHA_SIZE, 1,
-	GLX_DOUBLEBUFFER,
-	None
-    };
-    XVisualInfo *visinfo;
-    GLXContext ctx;
-    struct closure *arg;
-    cairo_device_t *device;
-    cairo_surface_t *surface;
-    Display *dpy;
-
-    dpy = XOpenDisplay (NULL);
-    if (dpy == NULL)
-	return NULL;
-
-    visinfo = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
-    if (visinfo == NULL) {
-	XCloseDisplay (dpy);
-	return NULL;
-    }
-
-    ctx = glXCreateContext (dpy, visinfo, NULL, True);
-    XFree (visinfo);
-
-    if (ctx == NULL) {
-	XCloseDisplay (dpy);
-	return NULL;
-    }
-
-    arg = xmalloc (sizeof (struct closure));
-    arg->dpy = dpy;
-    arg->ctx = ctx;
-    device = cairo_glx_device_create (dpy, ctx);
-    if (cairo_device_set_user_data (device,
-				    (cairo_user_data_key_t *) cleanup,
-				    arg,
-				    cleanup))
-    {
-	cleanup (arg);
-	return NULL;
-    }
-
-    surface = cairo_gl_surface_create (device,
-				       CAIRO_CONTENT_COLOR_ALPHA,
-				       size, size);
-    cairo_device_destroy (device);
-
-    return surface;
-}
-
-CAIRO_TEST (gl_surface_source,
-	    "Test using a GL surface as the source",
-	    "source", /* keywords */
-	    NULL, /* requirements */
-	    SIZE, SIZE,
-	    preamble, draw)
diff --git a/test/meson.build b/test/meson.build
index 275dd07d7..d950e2254 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -439,17 +439,6 @@ test_ft_svg_ttx_font_sources = [
   'ft-svg-render-palette.c'
 ]
 
-test_gl_sources = [
-  'gl-device-release.c',
-  'gl-oversized-surface.c',
-  'gl-surface-source.c',
-]
-
-test_egl_sources = [
-  'egl-oversized-surface.c',
-  'egl-surface-source.c',
-]
-
 test_quartz_sources = [
   'quartz-surface-source.c',
   'quartz-color-font.c',
@@ -596,10 +585,6 @@ if feature_conf.get('CAIRO_HAS_XLIB_XRENDER_SURFACE', 0) == 1
   test_sources += test_xlib_xrender_sources
 endif
 
-if feature_conf.get('CAIRO_HAS_EGL_FUNCTIONS', 0) == 1
-  test_sources += test_egl_sources
-endif
-
 if has_multipage_surfaces
   test_sources += test_multi_page_sources
 endif
diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c
index 9d9be72c2..4460d6414 100644
--- a/util/cairo-script/csi-replay.c
+++ b/util/cairo-script/csi-replay.c
@@ -206,64 +206,6 @@ _xrender_surface_create (void *closure,
 #endif
 #endif
 
-#if CAIRO_HAS_GL_GLX_SURFACE
-#include <cairo-gl.h>
-static cairo_gl_context_t *
-_glx_get_context (cairo_content_t content)
-{
-    static cairo_gl_context_t *context;
-
-    if (context == NULL) {
-	int rgba_attribs[] = {
-	    GLX_RGBA,
-	    GLX_RED_SIZE, 1,
-	    GLX_GREEN_SIZE, 1,
-	    GLX_BLUE_SIZE, 1,
-	    GLX_ALPHA_SIZE, 1,
-	    GLX_DOUBLEBUFFER,
-	    None
-	};
-	XVisualInfo *visinfo;
-	GLXContext gl_ctx;
-	Display *dpy;
-
-	dpy = XOpenDisplay (NULL);
-	if (dpy == NULL) {
-	    fprintf (stderr, "Failed to open display.\n");
-	    exit (1);
-	}
-
-	visinfo = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
-	if (visinfo == NULL) {
-	    fprintf (stderr, "Failed to create RGBA, double-buffered visual\n");
-	    exit (1);
-	}
-
-	gl_ctx = glXCreateContext (dpy, visinfo, NULL, True);
-	XFree (visinfo);
-
-	context = cairo_glx_context_create (dpy, gl_ctx);
-    }
-
-    return context;
-}
-
-static cairo_surface_t *
-_glx_surface_create (void *closure,
-		     cairo_content_t content,
-		     double width, double height,
-		     long uid)
-{
-    if (width == 0)
-	width = 1;
-    if (height == 0)
-	height = 1;
-
-    return cairo_gl_surface_create (_glx_get_context (content),
-				    content, width, height);
-}
-#endif
-
 #if CAIRO_HAS_PDF_SURFACE
 #include <cairo-pdf.h>
 static cairo_surface_t *
@@ -341,9 +283,6 @@ main (int argc, char **argv)
 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
 	{ "--xrender", _xrender_surface_create },
 #endif
-#if CAIRO_HAS_GL_GLX_SURFACE
-	{ "--glx", _glx_surface_create },
-#endif
 #if CAIRO_HAS_XLIB_SURFACE
 	{ "--xlib", _xlib_surface_create },
 #endif
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index a9181ce24..7ccdc41dc 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -5323,191 +5323,3 @@ cairo_recording_surface_create (cairo_content_t content,
     _exit_trace ();
     return ret;
 }
-
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV2_SURFACE
-#include <cairo-gl.h>
-cairo_surface_t *
-cairo_gl_surface_create (cairo_device_t		*abstract_device,
-			 cairo_content_t	 content,
-			 int			 width,
-			 int			 height)
-{
-    cairo_surface_t *ret;
-
-    _enter_trace ();
-
-    ret = DLCALL (cairo_gl_surface_create, abstract_device, content, width, height);
-
-    _emit_line_info ();
-    if (_write_lock ()) {
-	Object *obj = _create_surface (ret);
-
-	_trace_printf ("dict\n"
-		       "  /type /gl set\n"
-		       "  /content //%s set\n"
-		       "  /width %d set\n"
-		       "  /height %d set\n"
-		       "  surface dup /s%ld exch def\n",
-		       _content_to_string (content),
-		       width, height,
-		       obj->token);
-	obj->width = width;
-	obj->height = height;
-	obj->defined = TRUE;
-	_push_object (obj);
-	dump_stack(__func__);
-	_write_unlock ();
-    }
-
-    _exit_trace ();
-    return ret;
-}
-
-cairo_surface_t *
-cairo_gl_surface_create_for_texture (cairo_device_t	*abstract_device,
-				     cairo_content_t	 content,
-				     unsigned int	 tex,
-				     int		 width,
-				     int		 height)
-{
-    cairo_surface_t *ret;
-
-    _enter_trace ();
-
-    ret = DLCALL (cairo_gl_surface_create_for_texture, abstract_device, content, tex, width, height);
-
-    _emit_line_info ();
-    if (_write_lock ()) {
-	Object *obj = _create_surface (ret);
-
-	_trace_printf ("dict\n"
-		       "  /type /gl set\n"
-		       "  /content //%s set\n"
-		       "  /width %d set\n"
-		       "  /height %d set\n"
-		       "  surface dup /s%ld exch def\n",
-		       _content_to_string (content),
-		       width, height,
-		       obj->token);
-	obj->width = width;
-	obj->height = height;
-	obj->defined = TRUE;
-	_push_object (obj);
-	dump_stack(__func__);
-	_write_unlock ();
-    }
-
-    _exit_trace ();
-    return ret;
-}
-
-#if CAIRO_HAS_GLX_FUNCTIONS
-cairo_surface_t *
-cairo_gl_surface_create_for_window (cairo_device_t *device,
-				    Window win,
-				    int width, int height)
-{
-    cairo_surface_t *ret;
-
-    _enter_trace ();
-
-    ret = DLCALL (cairo_gl_surface_create_for_window, device, win, width, height);
-
-    _emit_line_info ();
-    if (_write_lock ()) {
-	Object *obj = _create_surface (ret);
-
-	_trace_printf ("dict\n"
-		       "  /type /gl set\n"
-		       "  /width %d set\n"
-		       "  /height %d set\n"
-		       "  surface dup /s%ld exch def\n",
-		       width, height,
-		       obj->token);
-	obj->width = width;
-	obj->height = height;
-	obj->defined = TRUE;
-	_push_object (obj);
-	dump_stack(__func__);
-	_write_unlock ();
-    }
-
-    _exit_trace ();
-    return ret;
-}
-#endif
-
-#if CAIRO_HAS_WGL_FUNCTIONS
-cairo_surface_t *
-cairo_gl_surface_create_for_dc (cairo_device_t		*device,
-				HDC			 dc,
-				int			 width,
-				int			 height)
-{
-    cairo_surface_t *ret;
-
-    _enter_trace ();
-
-    ret = DLCALL (cairo_gl_surface_create_for_dc, device, dc, width, height);
-
-    _emit_line_info ();
-    if (_write_lock ()) {
-	Object *obj = _create_surface (ret);
-
-	_trace_printf ("dict\n"
-		       "  /type /gl set\n"
-		       "  /width %d set\n"
-		       "  /height %d set\n"
-		       "  surface dup /s%ld exch def\n",
-		       width, height,
-		       obj->token);
-	obj->width = width;
-	obj->height = height;
-	obj->defined = TRUE;
-	_push_object (obj);
-	dump_stack(__func__);
-	_write_unlock ();
-    }
-
-    _exit_trace ();
-    return ret;
-}
-#endif
-
-#if CAIRO_HAS_EGL_FUNCTIONS
-cairo_surface_t *
-cairo_gl_surface_create_for_egl (cairo_device_t	*device,
-				 EGLSurface	 egl,
-				 int		 width,
-				 int		 height)
-{
-    cairo_surface_t *ret;
-
-    _enter_trace ();
-
-    ret = DLCALL (cairo_gl_surface_create_for_egl, device, egl, width, height);
-
-    _emit_line_info ();
-    if (_write_lock ()) {
-	Object *obj = _create_surface (ret);
-
-	_trace_printf ("dict\n"
-		       "  /type /gl set\n"
-		       "  /width %d set\n"
-		       "  /height %d set\n"
-		       "  surface dup /s%ld exch def\n",
-		       width, height,
-		       obj->token);
-	obj->width = width;
-	obj->height = height;
-	obj->defined = TRUE;
-	_push_object (obj);
-	dump_stack(__func__);
-	_write_unlock ();
-    }
-
-    _exit_trace ();
-    return ret;
-}
-#endif
-#endif


More information about the cairo-commit mailing list