[cairo-commit] 12 commits - boilerplate/cairo-boilerplate-gl.c src/cairo-array.c src/cairo-gl-device.c src/cairo-gl-glyphs.c src/cairo-gl.h src/cairo-gl-private.h src/cairo-gl-surface.c src/Makefile.sources
Benjamin Otte
company at kemper.freedesktop.org
Wed May 5 04:20:44 PDT 2010
boilerplate/cairo-boilerplate-gl.c | 17 --
src/Makefile.sources | 6
src/cairo-array.c | 2
src/cairo-gl-device.c | 205 ++++++++++++++++++++++++
src/cairo-gl-glyphs.c | 21 +-
src/cairo-gl-private.h | 12 +
src/cairo-gl-surface.c | 312 +++++++++----------------------------
src/cairo-gl.h | 3
8 files changed, 316 insertions(+), 262 deletions(-)
New commits:
commit 9c594d8b405eba09b07c0a438f5311f5c5e40313
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 12:28:59 2010 +0200
gl: Get rid of ctx variable
The code used renderer->ctx and ctx interchangably, that was confusing.
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index c6aacdf..2690bd6 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -2786,7 +2786,6 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
cairo_region_t *clip_region)
{
cairo_gl_surface_t *dst = abstract_dst;
- cairo_gl_context_t *ctx = (cairo_gl_context_t *) dst->base.device;
cairo_gl_surface_span_renderer_t *renderer;
cairo_status_t status;
cairo_surface_attributes_t *src_attributes;
@@ -2819,17 +2818,18 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
return _cairo_span_renderer_create_in_error (status);
}
- status = _cairo_gl_operand_init (ctx, &renderer->setup.src, src, dst,
+ status = _cairo_gl_operand_init (renderer->ctx,
+ &renderer->setup.src, src, dst,
rects->source.x, rects->source.y,
extents->x, extents->y,
extents->width, extents->height);
if (unlikely (status)) {
- _cairo_gl_context_release (ctx);
+ _cairo_gl_context_release (renderer->ctx);
free (renderer);
return _cairo_span_renderer_create_in_error (status);
}
- _cairo_gl_set_destination (ctx, dst);
+ _cairo_gl_set_destination (renderer->ctx, dst);
status = _cairo_gl_get_program (renderer->ctx,
renderer->setup.src.source,
@@ -2853,8 +2853,8 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
/* Set up the mask to source from the incoming vertex color. */
glActiveTexture (GL_TEXTURE1);
/* Have to have a dummy texture bound in order to use the combiner unit. */
- glBindTexture (ctx->tex_target, renderer->ctx->dummy_tex);
- glEnable (ctx->tex_target);
+ glBindTexture (renderer->ctx->tex_target, renderer->ctx->dummy_tex);
+ glEnable (renderer->ctx->tex_target);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
commit a354f1f92a17378f42d0b703482ae2b8168c7f68
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 12:28:24 2010 +0200
gl: Another case of proper device acquiring
This patch isn't strictly necessary, but it cleans up the code.
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 5576a99..c6aacdf 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -536,20 +536,23 @@ _cairo_gl_surface_create_similar (void *abstract_surface,
int height)
{
cairo_surface_t *surface = abstract_surface;
- cairo_gl_context_t *ctx = (cairo_gl_context_t *) surface->device;
+ cairo_gl_context_t *ctx;
cairo_status_t status;
+ status = _cairo_gl_context_acquire (surface->device, &ctx);
+ if (unlikely (status))
+ return _cairo_surface_create_in_error (status);
+
if (width > ctx->max_framebuffer_size ||
height > ctx->max_framebuffer_size)
{
- return NULL;
+ surface = NULL;
+ goto RELEASE;
}
- status = _cairo_gl_context_acquire (surface->device, &ctx);
- if (unlikely (status))
- return _cairo_surface_create_in_error (status);
-
surface = _cairo_gl_surface_create_scratch (ctx, content, width, height);
+
+RELEASE:
_cairo_gl_context_release (ctx);
return surface;
commit 36210ee51444979271f7ba1cc0ac452cd30df0af
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 12:24:43 2010 +0200
gl: Get rid of another cast to cairo_gl_context_t
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 5dedcbd..5576a99 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -419,19 +419,19 @@ cairo_gl_surface_create (cairo_device_t *abstract_device,
int width,
int height)
{
- cairo_gl_context_t *ctx = (cairo_gl_context_t *) abstract_device;
+ 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 (ctx == NULL) {
+ if (abstract_device == NULL) {
return cairo_image_surface_create (_cairo_format_from_content (content),
width, height);
}
- if (ctx->base.backend->type != CAIRO_DEVICE_TYPE_GL)
+ 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);
commit 58b03691d379979b50d74740748b8b8523e0cd0d
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 12:21:23 2010 +0200
gl: Introduce _cairo_gl_device_has_glsl() function
The function takes a cairo_device_t argument as it can be called on an
unacquired device.
This is the first patch in a process to try to rid cairo-gl-surface.c of
casts from cairo_device_t to cairo_gl_context_t. As its members should
usually only be accessed when the device is locked, the only way the
cairo_gl_context_t should be acquired is using
_cairo_gl_context_acquire().
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index cf0cbd6..604d060 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -316,7 +316,7 @@ _cairo_gl_glyphs_set_shader (cairo_gl_context_t *ctx,
if (setup->in == in)
return;
- if (ctx->using_glsl) {
+ if (_cairo_gl_device_has_glsl (&ctx->base)) {
cairo_status_t status;
status = _cairo_gl_get_program (ctx,
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 75a9348..c0d9c62 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -224,6 +224,12 @@ _cairo_gl_operand_init (cairo_gl_context_t *ctx,
int dst_x, int dst_y,
int width, int height);
+static cairo_always_inline cairo_bool_t
+_cairo_gl_device_has_glsl (cairo_device_t *device)
+{
+ return ((cairo_gl_context_t *) device)->using_glsl;
+}
+
static cairo_always_inline cairo_status_t cairo_warn
_cairo_gl_context_acquire (cairo_device_t *device,
cairo_gl_context_t **ctx)
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index d9eb3fd..5dedcbd 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -637,7 +637,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
GLuint tex;
GLfloat vertices[8], texcoords[8];
- if (ctx->using_glsl) {
+ if (_cairo_gl_device_has_glsl (&ctx->base)) {
cairo_gl_shader_program_t *program;
status = _cairo_gl_get_program (ctx,
@@ -710,7 +710,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
glDisableClientState (GL_VERTEX_ARRAY);
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
- if (ctx->using_glsl)
+ if (_cairo_gl_device_has_glsl (&ctx->base))
_cairo_gl_use_program (NULL);
glDeleteTextures (1, &tex);
glDisable (ctx->tex_target);
@@ -1268,7 +1268,7 @@ _cairo_gl_gradient_operand_init(cairo_gl_context_t *ctx,
}
}
- if (!ctx->using_glsl)
+ if (! _cairo_gl_device_has_glsl (&ctx->base))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
@@ -2487,9 +2487,8 @@ _cairo_gl_surface_fill_rectangles (void *abstract_surface,
int num_rects)
{
cairo_gl_surface_t *surface = abstract_surface;
- cairo_gl_context_t *ctx = (cairo_gl_context_t *) surface->base.device;
- if (ctx->using_glsl) {
+ if (_cairo_gl_device_has_glsl (surface->base.device)) {
return _cairo_gl_surface_fill_rectangles_glsl(abstract_surface,
op,
color,
commit 5223b654230d3074d0bc31eb74c415e50eced365
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 12:07:49 2010 +0200
gl: Get rid of cairo_gl_surface_glfinish() from public API
This is now done explicitly in the boilerplate code. It was not a useful
public API to begin with.
diff --git a/boilerplate/cairo-boilerplate-gl.c b/boilerplate/cairo-boilerplate-gl.c
index 37030af..5957da4 100644
--- a/boilerplate/cairo-boilerplate-gl.c
+++ b/boilerplate/cairo-boilerplate-gl.c
@@ -234,7 +234,12 @@ _cairo_boilerplate_gl_synchronize (void *closure)
{
gl_target_closure_t *gltc = closure;
- cairo_gl_surface_glfinish (gltc->surface);
+ if (cairo_device_acquire (gltc->device))
+ return;
+
+ glFinish ();
+
+ cairo_device_release (gltc->device);
}
#if CAIRO_HAS_EGL_FUNCTIONS
@@ -312,14 +317,6 @@ _cairo_boilerplate_egl_create_surface (const char *name,
return surface;
}
-
-static void
-_cairo_boilerplate_egl_synchronize (void *closure)
-{
- egl_target_closure_t *gltc = closure;
-
- cairo_gl_surface_glfinish (gltc->surface);
-}
#endif
static const cairo_boilerplate_target_t targets[] = {
@@ -370,7 +367,7 @@ static const cairo_boilerplate_target_t targets[] = {
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
_cairo_boilerplate_egl_cleanup,
- _cairo_boilerplate_egl_synchronize,
+ _cairo_boilerplate_gl_synchronize,
TRUE, FALSE, FALSE
},
#endif
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 1a0cbd4..d9eb3fd 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -2944,12 +2944,3 @@ const cairo_surface_backend_t _cairo_gl_surface_backend = {
_cairo_gl_surface_show_glyphs, /* show_glyphs */
NULL /* snapshot */
};
-
-/** Call glFinish(), used for accurate performance testing. */
-cairo_status_t
-cairo_gl_surface_glfinish (cairo_surface_t *surface)
-{
- glFinish ();
-
- return CAIRO_STATUS_SUCCESS;
-}
diff --git a/src/cairo-gl.h b/src/cairo-gl.h
index c1416d1..7dc1fbd 100644
--- a/src/cairo-gl.h
+++ b/src/cairo-gl.h
@@ -57,9 +57,6 @@ cairo_gl_surface_get_height (cairo_surface_t *abstract_surface);
cairo_public void
cairo_gl_surface_swapbuffers (cairo_surface_t *surface);
-cairo_public cairo_status_t
-cairo_gl_surface_glfinish (cairo_surface_t *surface);
-
#if CAIRO_HAS_GLX_FUNCTIONS
#include <GL/glx.h>
commit e071fa2c4f62b5ead39c6c6401f39360ea4dee1f
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 12:03:13 2010 +0200
gl: Remove unused member variable
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 00e95d8..75a9348 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -125,7 +125,6 @@ typedef struct _cairo_gl_context {
GLenum tex_target;
cairo_bool_t using_glsl;
- cairo_bool_t using_shaders;
cairo_gl_shader_program_t fill_rectangles_shader;
cairo_gl_shader_program_t shaders[CAIRO_GL_SHADER_SOURCE_COUNT]
[CAIRO_GL_SHADER_MASK_COUNT]
commit 90c64f60d853f1a6ea5febd362ef3528cc9d914b
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 12:01:59 2010 +0200
gl: Move device-specific code into cairo-gl-device.c
diff --git a/src/Makefile.sources b/src/Makefile.sources
index e92ec8b..a40404b 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -313,7 +313,11 @@ cairo_beos_headers = cairo-beos.h
cairo_gl_headers = cairo-gl.h
cairo_gl_private = cairo-gl-private.h
-cairo_gl_sources = cairo-gl-surface.c cairo-gl-glyphs.c cairo-gl-shaders.c
+cairo_gl_sources = cairo-gl-device.c \
+ cairo-gl-glyphs.c \
+ cairo-gl-shaders.c \
+ cairo-gl-surface.c
+
cairo_glx_sources += cairo-glx-context.c
cairo_egl_sources += cairo-egl-context.c
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
new file mode 100644
index 0000000..3d121e9
--- /dev/null
+++ b/src/cairo-gl-device.c
@@ -0,0 +1,205 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Eric Anholt
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2005 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ * Carl Worth <cworth at cworth.org>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-error-private.h"
+#include "cairo-gl-private.h"
+
+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);
+ ctx->current_target = NULL;
+}
+
+static void
+_gl_destroy (void *device)
+{
+ cairo_gl_context_t *ctx = device;
+ cairo_scaled_font_t *scaled_font, *next_scaled_font;
+ int n;
+
+ ctx->acquire (ctx);
+
+ cairo_list_foreach_entry_safe (scaled_font,
+ next_scaled_font,
+ cairo_scaled_font_t,
+ &ctx->fonts,
+ link)
+ {
+ _cairo_scaled_font_revoke_ownership (scaled_font);
+ }
+
+ for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++)
+ _cairo_gl_glyph_cache_fini (ctx, &ctx->glyph_cache[n]);
+
+ ctx->destroy (ctx);
+
+ free (ctx);
+}
+
+static const cairo_device_backend_t _cairo_gl_device_backend = {
+ CAIRO_DEVICE_TYPE_GL,
+
+ _gl_lock,
+ _gl_unlock,
+
+ NULL, /* flush */
+ NULL, /* finish */
+ _gl_destroy,
+};
+
+cairo_status_t
+_cairo_gl_context_init (cairo_gl_context_t *ctx)
+{
+ int n;
+
+ _cairo_device_init (&ctx->base, &_cairo_gl_device_backend);
+
+ memset (ctx->glyph_cache, 0, sizeof (ctx->glyph_cache));
+ cairo_list_init (&ctx->fonts);
+
+ if (glewInit () != GLEW_OK)
+ return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); /* XXX */
+
+ if (! GLEW_EXT_framebuffer_object ||
+ ! GLEW_ARB_texture_env_combine ||
+ ! GLEW_EXT_bgra)
+ {
+ fprintf (stderr,
+ "Required GL extensions not available:\n");
+ if (! GLEW_EXT_framebuffer_object)
+ fprintf (stderr, " GL_EXT_framebuffer_object\n");
+ if (! GLEW_ARB_texture_env_combine)
+ fprintf (stderr, " GL_ARB_texture_env_combine\n");
+ /* EXT_bgra is used in two places:
+ * - draw_image to upload common pixman formats without hand-swizzling.
+ * - get_image to download common pixman formats without hand-swizzling.
+ */
+ if (! GLEW_EXT_bgra)
+ fprintf (stderr, " GL_EXT_bgra\n");
+
+ return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); /* XXX */
+ }
+
+ if (! GLEW_ARB_texture_non_power_of_two &&
+ ! GLEW_ARB_texture_rectangle ) {
+ fprintf (stderr,
+ "Required GL extensions not available:\n");
+ fprintf (stderr, " GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle\n");
+ }
+
+ if (!GLEW_ARB_texture_non_power_of_two)
+ ctx->tex_target = GL_TEXTURE_RECTANGLE_EXT;
+ else
+ ctx->tex_target = GL_TEXTURE_2D;
+
+
+ if (GLEW_VERSION_2_0 ||
+ (GLEW_ARB_fragment_shader &&
+ GLEW_ARB_vertex_shader &&
+ GLEW_ARB_shader_objects))
+ {
+ ctx->using_glsl = TRUE;
+ }
+
+ init_shader_program (&ctx->fill_rectangles_shader);
+
+ /* Set up the dummy texture for tex_env_combine with constant color. */
+ glGenTextures (1, &ctx->dummy_tex);
+ glBindTexture (ctx->tex_target, ctx->dummy_tex);
+ glTexImage2D (ctx->tex_target, 0, GL_RGBA, 1, 1, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ /* PBO for any sort of texture upload */
+ glGenBuffersARB (1, &ctx->texture_load_pbo);
+ glGenBuffersARB (1, &ctx->vbo);
+
+ 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);
+
+ 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_set_destination (cairo_gl_context_t *ctx,
+ cairo_gl_surface_t *surface)
+{
+ if (ctx->current_target != surface) {
+ ctx->current_target = surface;
+
+ if (surface->fb) {
+ glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
+ glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
+ glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
+ } else {
+ ctx->make_current (ctx, surface);
+ glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
+ glDrawBuffer (GL_BACK_LEFT);
+ glReadBuffer (GL_BACK_LEFT);
+ }
+ }
+
+ glViewport (0, 0, surface->width, surface->height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ if (surface->fb)
+ glOrtho (0, surface->width, 0, surface->height, -1.0, 1.0);
+ else
+ glOrtho (0, surface->width, surface->height, 0, -1.0, 1.0);
+
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+}
+
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 0fde030..1a0cbd4 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -67,137 +67,6 @@ static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface)
return surface->backend == &_cairo_gl_surface_backend;
}
-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);
- ctx->current_target = NULL;
-}
-
-static void
-_gl_destroy (void *device)
-{
- cairo_gl_context_t *ctx = device;
- cairo_scaled_font_t *scaled_font, *next_scaled_font;
- int n;
-
- ctx->acquire (ctx);
-
- cairo_list_foreach_entry_safe (scaled_font,
- next_scaled_font,
- cairo_scaled_font_t,
- &ctx->fonts,
- link)
- {
- _cairo_scaled_font_revoke_ownership (scaled_font);
- }
-
- for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++)
- _cairo_gl_glyph_cache_fini (ctx, &ctx->glyph_cache[n]);
-
- ctx->destroy (ctx);
-
- free (ctx);
-}
-
-static const cairo_device_backend_t _cairo_gl_device_backend = {
- CAIRO_DEVICE_TYPE_GL,
-
- _gl_lock,
- _gl_unlock,
-
- NULL, /* flush */
- NULL, /* finish */
- _gl_destroy,
-};
-
-cairo_status_t
-_cairo_gl_context_init (cairo_gl_context_t *ctx)
-{
- int n;
-
- _cairo_device_init (&ctx->base, &_cairo_gl_device_backend);
-
- memset (ctx->glyph_cache, 0, sizeof (ctx->glyph_cache));
- cairo_list_init (&ctx->fonts);
-
- if (glewInit () != GLEW_OK)
- return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); /* XXX */
-
- if (! GLEW_EXT_framebuffer_object ||
- ! GLEW_ARB_texture_env_combine ||
- ! GLEW_EXT_bgra)
- {
- fprintf (stderr,
- "Required GL extensions not available:\n");
- if (! GLEW_EXT_framebuffer_object)
- fprintf (stderr, " GL_EXT_framebuffer_object\n");
- if (! GLEW_ARB_texture_env_combine)
- fprintf (stderr, " GL_ARB_texture_env_combine\n");
- /* EXT_bgra is used in two places:
- * - draw_image to upload common pixman formats without hand-swizzling.
- * - get_image to download common pixman formats without hand-swizzling.
- */
- if (! GLEW_EXT_bgra)
- fprintf (stderr, " GL_EXT_bgra\n");
-
- return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); /* XXX */
- }
-
- if (! GLEW_ARB_texture_non_power_of_two &&
- ! GLEW_ARB_texture_rectangle ) {
- fprintf (stderr,
- "Required GL extensions not available:\n");
- fprintf (stderr, " GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle\n");
- }
-
- if (!GLEW_ARB_texture_non_power_of_two)
- ctx->tex_target = GL_TEXTURE_RECTANGLE_EXT;
- else
- ctx->tex_target = GL_TEXTURE_2D;
-
-
- if (GLEW_VERSION_2_0 ||
- (GLEW_ARB_fragment_shader &&
- GLEW_ARB_vertex_shader &&
- GLEW_ARB_shader_objects))
- {
- ctx->using_glsl = TRUE;
- }
-
- init_shader_program (&ctx->fill_rectangles_shader);
-
- /* Set up the dummy texture for tex_env_combine with constant color. */
- glGenTextures (1, &ctx->dummy_tex);
- glBindTexture (ctx->tex_target, ctx->dummy_tex);
- glTexImage2D (ctx->tex_target, 0, GL_RGBA, 1, 1, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- /* PBO for any sort of texture upload */
- glGenBuffersARB (1, &ctx->texture_load_pbo);
- glGenBuffersARB (1, &ctx->vbo);
-
- 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);
-
- for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++)
- _cairo_gl_glyph_cache_init (&ctx->glyph_cache[n]);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
cairo_bool_t
_cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format,
GLenum *internal_format, GLenum *format,
@@ -319,37 +188,6 @@ _cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format,
}
}
-void
-_cairo_gl_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface)
-{
- if (ctx->current_target != surface) {
- ctx->current_target = surface;
-
- if (surface->fb) {
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
- glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
- glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
- } else {
- ctx->make_current (ctx, surface);
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
- glDrawBuffer (GL_BACK_LEFT);
- glReadBuffer (GL_BACK_LEFT);
- }
- }
-
- glViewport (0, 0, surface->width, surface->height);
-
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
- if (surface->fb)
- glOrtho (0, surface->width, 0, surface->height, -1.0, 1.0);
- else
- glOrtho (0, surface->width, surface->height, 0, -1.0, 1.0);
-
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity ();
-}
-
cairo_bool_t
_cairo_gl_operator_is_supported (cairo_operator_t op)
{
commit 0ff5a18fd5623b57c7493e6b67a6b1c75af82fb3
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 11:52:40 2010 +0200
gl: Make _gl_set_destination() take the context as an argument
Keeping with the API introduced for Xlib, functions that require an
acquired context take this context as the first argument.
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 0b6fb28..cf0cbd6 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -494,7 +494,7 @@ _render_glyphs (cairo_gl_surface_t *dst,
return status;
}
- _cairo_gl_set_destination (dst);
+ _cairo_gl_set_destination (ctx, dst);
_cairo_scaled_font_freeze_cache (scaled_font);
if (! _cairo_gl_surface_owns_font (dst, scaled_font)) {
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 11abb4b..00e95d8 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -246,7 +246,7 @@ _cairo_gl_context_release (cairo_gl_context_t *ctx)
}
cairo_private void
-_cairo_gl_set_destination (cairo_gl_surface_t *surface);
+_cairo_gl_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface);
cairo_private cairo_bool_t
_cairo_gl_operator_is_supported (cairo_operator_t op);
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index f640e6b..0fde030 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -320,10 +320,8 @@ _cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format,
}
void
-_cairo_gl_set_destination (cairo_gl_surface_t *surface)
+_cairo_gl_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface)
{
- cairo_gl_context_t *ctx = (cairo_gl_context_t *) surface->base.device;
-
if (ctx->current_target != surface) {
ctx->current_target = surface;
@@ -564,7 +562,7 @@ _cairo_gl_surface_clear (cairo_gl_surface_t *surface)
if (unlikely (status))
return status;
- _cairo_gl_set_destination (surface);
+ _cairo_gl_set_destination (ctx, surface);
if (surface->base.content == CAIRO_CONTENT_COLOR)
glClearColor (0.0, 0.0, 0.0, 1.0);
else
@@ -819,7 +817,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
- _cairo_gl_set_destination (dst);
+ _cairo_gl_set_destination (ctx, dst);
glGenTextures (1, &tex);
glActiveTexture (GL_TEXTURE0);
@@ -939,7 +937,7 @@ _cairo_gl_surface_get_image (cairo_gl_surface_t *surface,
status = _cairo_gl_context_acquire (surface->base.device, &ctx);
if (unlikely (status))
return status;
- _cairo_gl_set_destination (surface);
+ _cairo_gl_set_destination (ctx, surface);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glPixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp);
@@ -2028,7 +2026,7 @@ _cairo_gl_surface_composite_component_alpha (cairo_operator_t op,
status = CAIRO_STATUS_SUCCESS;
}
- _cairo_gl_set_destination (dst);
+ _cairo_gl_set_destination (ctx, dst);
if (clip_region != NULL) {
int num_rectangles;
@@ -2249,7 +2247,7 @@ _cairo_gl_surface_composite (cairo_operator_t op,
status = CAIRO_STATUS_SUCCESS;
}
- _cairo_gl_set_destination (dst);
+ _cairo_gl_set_destination (ctx, dst);
_cairo_gl_set_operator (dst, op, FALSE);
_cairo_gl_use_program (setup.shader);
@@ -2486,7 +2484,7 @@ _cairo_gl_surface_fill_rectangles_fixed (void *abstract_surface,
if (unlikely (status))
return status;
- _cairo_gl_set_destination (surface);
+ _cairo_gl_set_destination (ctx, surface);
_cairo_gl_set_operator (surface, op, FALSE);
if (num_rects > N_STACK_RECTS) {
@@ -2603,7 +2601,7 @@ _cairo_gl_surface_fill_rectangles_glsl (void *abstract_surface,
_cairo_gl_use_program (&ctx->fill_rectangles_shader);
- _cairo_gl_set_destination (surface);
+ _cairo_gl_set_destination (ctx, surface);
_cairo_gl_set_operator (surface, op, FALSE);
status = bind_vec4_to_shader (ctx->fill_rectangles_shader.program,
@@ -2991,7 +2989,7 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
return _cairo_span_renderer_create_in_error (status);
}
- _cairo_gl_set_destination (dst);
+ _cairo_gl_set_destination (ctx, dst);
status = _cairo_gl_get_program (renderer->ctx,
renderer->setup.src.source,
commit e8c5b6b1c2099fc6a49d0a082f5e884d3fbd89df
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 5 10:05:30 2010 +0200
Fix typo in docs
diff --git a/src/cairo-array.c b/src/cairo-array.c
index f2d2fb8..942c9b9 100644
--- a/src/cairo-array.c
+++ b/src/cairo-array.c
@@ -261,7 +261,7 @@ _cairo_array_append (cairo_array_t *array,
}
/**
- * _cairo_array_append:
+ * _cairo_array_append_multiple:
* @array: a #cairo_array_t
*
* Append one or more items onto the array by growing the array by
commit 53508e6e3047b4dac6d69d5d3ff2208178998fd4
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 4 19:28:45 2010 +0200
gl: Acquire the context before destroying it.
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 0214aec..f640e6b 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -91,7 +91,7 @@ _gl_destroy (void *device)
cairo_scaled_font_t *scaled_font, *next_scaled_font;
int n;
- ctx->destroy (ctx);
+ ctx->acquire (ctx);
cairo_list_foreach_entry_safe (scaled_font,
next_scaled_font,
@@ -105,6 +105,8 @@ _gl_destroy (void *device)
for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++)
_cairo_gl_glyph_cache_fini (ctx, &ctx->glyph_cache[n]);
+ ctx->destroy (ctx);
+
free (ctx);
}
commit c46aec489722bf09cd10c52d70bb4975eb1546d9
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 4 19:28:22 2010 +0200
gl: acquire/release context during surface_finish()
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index f961f10..0214aec 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -964,7 +964,12 @@ static cairo_status_t
_cairo_gl_surface_finish (void *abstract_surface)
{
cairo_gl_surface_t *surface = abstract_surface;
- cairo_gl_context_t *ctx = (cairo_gl_context_t *) surface->base.device;
+ cairo_status_t status;
+ cairo_gl_context_t *ctx;
+
+ status = _cairo_gl_context_acquire (surface->base.device, &ctx);
+ if (unlikely (status))
+ return status;
glDeleteFramebuffersEXT (1, &surface->fb);
glDeleteTextures (1, &surface->tex);
@@ -972,6 +977,8 @@ _cairo_gl_surface_finish (void *abstract_surface)
if (ctx->current_target == surface)
ctx->current_target = NULL;
+ _cairo_gl_context_release (ctx);
+
return CAIRO_STATUS_SUCCESS;
}
commit 88801aabb34328746a53d3d59d036dada7ced756
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 4 19:23:08 2010 +0200
gl: Acquire context when initing/destroying gl operands
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index b5baec6..0b6fb28 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -480,17 +480,19 @@ _render_glyphs (cairo_gl_surface_t *dst,
memset (&composite_setup, 0, sizeof(composite_setup));
- status = _cairo_gl_operand_init (&composite_setup.src, source, dst,
+ status = _cairo_gl_context_acquire (dst->base.device, &ctx);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_gl_operand_init (ctx, &composite_setup.src, source, dst,
glyph_extents->x, glyph_extents->y,
dst_x, dst_y,
glyph_extents->width,
glyph_extents->height);
- if (unlikely (status))
- return status;
-
- status = _cairo_gl_context_acquire (dst->base.device, &ctx);
- if (unlikely (status))
+ if (unlikely (status)) {
+ _cairo_gl_context_release (ctx);
return status;
+ }
_cairo_gl_set_destination (dst);
@@ -639,10 +641,11 @@ _render_glyphs (cairo_gl_surface_t *dst,
_cairo_gl_use_program (NULL);
glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
- _cairo_gl_context_release (ctx);
_cairo_gl_operand_destroy (&composite_setup.src);
+ _cairo_gl_context_release (ctx);
+
*remaining_glyphs = num_glyphs - i;
return status;
}
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 9490072..11abb4b 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -217,7 +217,8 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
int dst_x, int dst_y);
cairo_private cairo_int_status_t
-_cairo_gl_operand_init (cairo_gl_composite_operand_t *operand,
+_cairo_gl_operand_init (cairo_gl_context_t *ctx,
+ cairo_gl_composite_operand_t *operand,
const cairo_pattern_t *pattern,
cairo_gl_surface_t *dst,
int src_x, int src_y,
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index db837aa..f961f10 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -1294,7 +1294,8 @@ _cairo_gl_create_gradient_texture (const cairo_gl_context_t *ctx,
* from dest to src coords.
*/
static cairo_status_t
-_cairo_gl_pattern_texture_setup (cairo_gl_composite_operand_t *operand,
+_cairo_gl_pattern_texture_setup (cairo_gl_context_t *ctx,
+ cairo_gl_composite_operand_t *operand,
const cairo_pattern_t *src,
cairo_gl_surface_t *dst,
int src_x, int src_y,
@@ -1305,7 +1306,6 @@ _cairo_gl_pattern_texture_setup (cairo_gl_composite_operand_t *operand,
cairo_matrix_t m;
cairo_gl_surface_t *surface;
cairo_surface_attributes_t *attributes;
- cairo_gl_context_t *ctx = (cairo_gl_context_t *) dst->base.device;
attributes = &operand->operand.texture.attributes;
status = _cairo_pattern_acquire_surface (src, &dst->base,
@@ -1386,10 +1386,10 @@ _cairo_gl_solid_operand_init (cairo_gl_composite_operand_t *operand,
}
static cairo_status_t
-_cairo_gl_gradient_operand_init(cairo_gl_composite_operand_t *operand,
+_cairo_gl_gradient_operand_init(cairo_gl_context_t *ctx,
+ cairo_gl_composite_operand_t *operand,
cairo_gl_surface_t *dst)
{
- const cairo_gl_context_t *ctx = (cairo_gl_context_t *) dst->base.device;
cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *)operand->pattern;
/* Fast path for gradients with less than 2 color stops.
@@ -1505,7 +1505,8 @@ _cairo_gl_gradient_operand_init(cairo_gl_composite_operand_t *operand,
}
cairo_int_status_t
-_cairo_gl_operand_init (cairo_gl_composite_operand_t *operand,
+_cairo_gl_operand_init (cairo_gl_context_t *ctx,
+ cairo_gl_composite_operand_t *operand,
const cairo_pattern_t *pattern,
cairo_gl_surface_t *dst,
int src_x, int src_y,
@@ -1522,7 +1523,7 @@ _cairo_gl_operand_init (cairo_gl_composite_operand_t *operand,
&((cairo_solid_pattern_t *) pattern)->color);
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL:
- status = _cairo_gl_gradient_operand_init (operand, dst);
+ status = _cairo_gl_gradient_operand_init (ctx, operand, dst);
if (!_cairo_status_is_error (status))
return status;
@@ -1531,7 +1532,7 @@ _cairo_gl_operand_init (cairo_gl_composite_operand_t *operand,
default:
case CAIRO_PATTERN_TYPE_SURFACE:
operand->type = OPERAND_TEXTURE;
- return _cairo_gl_pattern_texture_setup (operand,
+ return _cairo_gl_pattern_texture_setup (ctx, operand,
pattern, dst,
src_x, src_y,
dst_x, dst_y,
@@ -1972,31 +1973,31 @@ _cairo_gl_surface_composite_component_alpha (cairo_operator_t op,
memset (&setup, 0, sizeof (setup));
- status = _cairo_gl_operand_init (&setup.src, src, dst,
+ status = _cairo_gl_context_acquire (dst->base.device, &ctx);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_gl_operand_init (ctx, &setup.src, src, dst,
src_x, src_y,
dst_x, dst_y,
width, height);
- if (unlikely (status))
+ if (unlikely (status)) {
+ _cairo_gl_context_release (ctx);
return status;
+ }
src_attributes = &setup.src.operand.texture.attributes;
- status = _cairo_gl_operand_init (&setup.mask, mask, dst,
+ status = _cairo_gl_operand_init (ctx, &setup.mask, mask, dst,
mask_x, mask_y,
dst_x, dst_y,
width, height);
if (unlikely (status)) {
+ _cairo_gl_context_release (ctx);
_cairo_gl_operand_destroy (&setup.src);
return status;
}
mask_attributes = &setup.mask.operand.texture.attributes;
- status = _cairo_gl_context_acquire (dst->base.device, &ctx);
- if (unlikely (status)) {
- _cairo_gl_operand_destroy (&setup.src);
- _cairo_gl_operand_destroy (&setup.mask);
- return status;
- }
-
status = _cairo_gl_get_program (ctx,
setup.src.source,
setup.mask.mask,
@@ -2029,7 +2030,7 @@ _cairo_gl_surface_composite_component_alpha (cairo_operator_t op,
4*3*sizeof (vertices[0]));
if (unlikely (vertices == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto CONTEXT_RELEASE;
+ goto CLEANUP;
}
texcoord_src = vertices + num_rectangles * 4;
@@ -2135,13 +2136,13 @@ _cairo_gl_surface_composite_component_alpha (cairo_operator_t op,
while ((err = glGetError ()))
fprintf (stderr, "GL error 0x%08x\n", (int) err);
- CONTEXT_RELEASE:
- _cairo_gl_context_release (ctx);
-
+ CLEANUP:
_cairo_gl_operand_destroy (&setup.src);
if (mask != NULL)
_cairo_gl_operand_destroy (&setup.mask);
+ _cairo_gl_context_release (ctx);
+
if (vertices != vertices_stack)
free (vertices);
@@ -2199,21 +2200,28 @@ _cairo_gl_surface_composite (cairo_operator_t op,
memset (&setup, 0, sizeof (setup));
- status = _cairo_gl_operand_init (&setup.src, src, dst,
+ status = _cairo_gl_context_acquire (dst->base.device, &ctx);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_gl_operand_init (ctx, &setup.src, src, dst,
src_x, src_y,
dst_x, dst_y,
width, height);
- if (unlikely (status))
+ if (unlikely (status)) {
+ _cairo_gl_context_release (ctx);
return status;
+ }
src_attributes = &setup.src.operand.texture.attributes;
if (mask != NULL) {
- status = _cairo_gl_operand_init (&setup.mask, mask, dst,
+ status = _cairo_gl_operand_init (ctx, &setup.mask, mask, dst,
mask_x, mask_y,
dst_x, dst_y,
width, height);
if (unlikely (status)) {
_cairo_gl_operand_destroy (&setup.src);
+ _cairo_gl_context_release (ctx);
return status;
}
mask_attributes = &setup.mask.operand.texture.attributes;
@@ -2221,10 +2229,6 @@ _cairo_gl_surface_composite (cairo_operator_t op,
setup.mask.mask = CAIRO_GL_SHADER_MASK_NONE;
}
- status = _cairo_gl_context_acquire (dst->base.device, &ctx);
- if (unlikely (status))
- goto CLEANUP_SHADER;
-
status = _cairo_gl_get_program (ctx,
setup.src.source,
setup.mask.mask,
@@ -2288,7 +2292,7 @@ _cairo_gl_surface_composite (cairo_operator_t op,
4*3*sizeof (vertices[0]));
if (unlikely (vertices == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto CONTEXT_RELEASE;
+ goto CLEANUP_SHADER;
}
texcoord_src = vertices + num_rectangles * 4;
@@ -2382,14 +2386,13 @@ _cairo_gl_surface_composite (cairo_operator_t op,
while ((err = glGetError ()))
fprintf (stderr, "GL error 0x%08x\n", (int) err);
- CONTEXT_RELEASE:
- _cairo_gl_context_release (ctx);
-
CLEANUP_SHADER:
_cairo_gl_operand_destroy (&setup.src);
if (mask != NULL)
_cairo_gl_operand_destroy (&setup.mask);
+ _cairo_gl_context_release (ctx);
+
if (vertices != vertices_stack)
free (vertices);
@@ -2963,21 +2966,22 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
renderer->dst = dst;
renderer->clip = clip_region;
- status = _cairo_gl_operand_init (&renderer->setup.src, src, dst,
- rects->source.x, rects->source.y,
- extents->x, extents->y,
- extents->width, extents->height);
+ status = _cairo_gl_context_acquire (dst->base.device, &renderer->ctx);
if (unlikely (status)) {
free (renderer);
return _cairo_span_renderer_create_in_error (status);
}
- status = _cairo_gl_context_acquire (dst->base.device, &renderer->ctx);
+ status = _cairo_gl_operand_init (ctx, &renderer->setup.src, src, dst,
+ rects->source.x, rects->source.y,
+ extents->x, extents->y,
+ extents->width, extents->height);
if (unlikely (status)) {
- _cairo_gl_operand_destroy (&renderer->setup.src);
+ _cairo_gl_context_release (ctx);
free (renderer);
return _cairo_span_renderer_create_in_error (status);
}
+
_cairo_gl_set_destination (dst);
status = _cairo_gl_get_program (renderer->ctx,
More information about the cairo-commit
mailing list