summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2021-04-18 00:11:16 +0100
committerEmmanuele Bassi <ebassi@gnome.org>2023-01-27 19:21:46 +0000
commitb5793081d095a13517e157d793b367e4527fd39d (patch)
treecb22d4992c0462e2520d6e22a946072809c2e5ad /src
parent407bb0a478890c2640c326fab0642d8595407ba1 (diff)
downloadcairo-b5793081d095a13517e157d793b367e4527fd39d.tar.gz
Drop cairo-gl
The GL support in Cairo has always been a prototype, and nothing happened in the past 10+ years to make it work as it was meant to. GL support is not enabled by any downstream packagers of Cairo, so nobody should notice its absence.
Diffstat (limited to 'src')
-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
26 files changed, 1 insertions, 12021 deletions
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',
],