summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml10
-rw-r--r--boilerplate/cairo-boilerplate-egl.c192
-rw-r--r--boilerplate/cairo-boilerplate-glx.c457
-rw-r--r--boilerplate/cairo-boilerplate-wgl.c239
-rw-r--r--boilerplate/meson.build4
-rw-r--r--meson.build135
-rw-r--r--meson_options.txt10
-rw-r--r--src/cairo-egl-context.c317
-rw-r--r--src/cairo-gl-composite.c1364
-rw-r--r--src/cairo-gl-device.c851
-rw-r--r--src/cairo-gl-dispatch-private.h129
-rw-r--r--src/cairo-gl-dispatch.c273
-rw-r--r--src/cairo-gl-ext-def-private.h143
-rw-r--r--src/cairo-gl-glyphs.c507
-rw-r--r--src/cairo-gl-gradient-private.h96
-rw-r--r--src/cairo-gl-gradient.c339
-rw-r--r--src/cairo-gl-info.c147
-rw-r--r--src/cairo-gl-msaa-compositor.c956
-rw-r--r--src/cairo-gl-operand.c793
-rw-r--r--src/cairo-gl-private.h865
-rw-r--r--src/cairo-gl-shaders.c1111
-rw-r--r--src/cairo-gl-source.c113
-rw-r--r--src/cairo-gl-spans-compositor.c556
-rw-r--r--src/cairo-gl-surface-legacy.c602
-rw-r--r--src/cairo-gl-surface.c1552
-rw-r--r--src/cairo-gl-traps-compositor.c531
-rw-r--r--src/cairo-gl.h155
-rw-r--r--src/cairo-glx-context.c324
-rw-r--r--src/cairo-mutex-list-private.h4
-rw-r--r--src/cairo-wgl-context.c260
-rw-r--r--src/cairo-xcb-surface-render.c6
-rw-r--r--src/cairo.h4
-rw-r--r--src/meson.build24
-rw-r--r--test/api-special-cases.c41
-rw-r--r--test/egl-oversized-surface.c117
-rw-r--r--test/egl-surface-source.c135
-rw-r--r--test/error-setters.c8
-rw-r--r--test/gl-device-release.c182
-rw-r--r--test/gl-oversized-surface.c88
-rw-r--r--test/gl-surface-source.c111
-rw-r--r--test/meson.build15
-rw-r--r--util/cairo-script/csi-replay.c61
-rw-r--r--util/cairo-trace/trace.c188
43 files changed, 1 insertions, 14014 deletions
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@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@cworth.org>
- * Chris Wilson <chris@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@anholt.net>
- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
- * Henry Song <hsong@sisa.samsung.com>
- * Martin Robinson <mrobinson@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@anholt.net>
- * Alexandros Frantzis <alexandros.frantzis@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@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@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@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@gnome.org>
- * Chris Wilson <chris@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@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@linaro.org>
- * Heiko Lewin <heiko.lewin@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@sisa.samsung.com>
- * Martin Robinson <mrobinson@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@anholt.net>
- * T. Zachary Laine <whatwasthataddress@gmail.com>
- * Alexandros Frantzis <alexandros.frantzis@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@gnome.org>
- * Eric Anholt <eric@anholt.net>
- * T. Zachary Laine <whatwasthataddress@gmail.com>
- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
- * H. Lewin <heiko.lewin@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@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@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@gnome.org>
- * Carl Worth <cworth@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Eric Anholt <eric@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@cworth.org>
- * Chris Wilson <chris@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@cworth.org>
- * Chris Wilson <chris@chris-wilson.co.uk>
- * Zoxc <zoxc32@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
@@ -1243,12 +1243,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)
{
/* We have to skip the call to attach_snapshot() because we possibly
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@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@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@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@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@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 e5b4f89d5..b18a23f48 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -439,17 +439,6 @@ test_ft_svg_ttx_font_sources = [
'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',
@@ -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