[cairo] Shared GL surface?

Christophe de Dinechin christophe at taodyne.com
Fri Mar 5 00:13:41 PST 2010


I have been experimenting with GL surfaces on MacOSX.

What I wanted to try is to use Cairo to draw in a particular GL context, without the overhead of context switches, pixel buffers, textures or whatever. I was hoping to render glyphs or paths as outlines while any kind of 3D GL transform is in effect.

I tried to find a way to use the current GL context as a GL surface. So I tried the patch attached below. The intent was to use the current GL context, whatever that might be. In my case, I'm creating it with Qt, but it could be GLUT, whatever. That didn't work, for reasons that may be totally obvious to people on this list. Basically, rendering still happens off-screen. It does happen, I proved that by dumping the surface to a .PNG file, but it's not immediate, it's not using the current context. As far as I can tell, there's no way to achieve that on OSX today.

Anybody trying to use Cairo that way today?


Thanks
Christophe

---
 src/cairo-gl-surface.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/cairo-gl.h         |    3 +++
 2 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 076fc3f..1a4d2b7 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -41,6 +41,7 @@
 #include "cairo-error-private.h"
 #include "cairo-gl-private.h"
 
+
 static cairo_int_status_t
 _cairo_gl_surface_fill_rectangles (void			   *abstract_surface,
 				   cairo_operator_t	    op,
@@ -587,6 +588,53 @@ cairo_gl_surface_create (cairo_device_t		*abstract_device,
 }
 slim_hidden_def (cairo_gl_surface_create);
 
+static void
+_current_gl_context_make_current (void *abstract_ctx,
+                                  cairo_gl_surface_t *abstract_surface)
+{
+    // No operation: it's supposed to be current
+}
+
+static void
+_current_gl_context_swap_buffers (void *abstract_ctx,
+                                  cairo_gl_surface_t *abstract_surface)
+{
+    // No operation, it's supposed to be dealt with by the user
+}
+
+static void
+_current_gl_context_destroy (void *abstract_ctx)
+{
+}
+
+
+cairo_surface_t *
+cairo_gl_surface_create_for_current_gl_context(void)
+{
+    GLint viewport[4];
+    cairo_gl_context_t *ctx;
+    cairo_status_t status;
+
+    ctx = calloc(1, sizeof(cairo_gl_context_t));
+    if (unlikely (ctx == NULL))
+	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
+
+    ctx->make_current = _current_gl_context_make_current;
+    ctx->swap_buffers = _current_gl_context_swap_buffers;
+    ctx->destroy = _current_gl_context_destroy;
+
+    status = _cairo_gl_context_init (ctx);
+    if (unlikely (status)) {
+	free (ctx);
+	return _cairo_surface_create_in_error (status);
+    }
+
+    // Get current viewport size
+    glGetIntegerv(GL_VIEWPORT, viewport);
+    return cairo_gl_surface_create(&ctx->base, CAIRO_CONTENT_COLOR_ALPHA,
+                                   viewport[2], viewport[3]);
+}
+
 void
 cairo_gl_surface_set_size (cairo_surface_t *abstract_surface,
 			   int              width,
diff --git a/src/cairo-gl.h b/src/cairo-gl.h
index 9df9bb7..05274ea 100644
--- a/src/cairo-gl.h
+++ b/src/cairo-gl.h
@@ -72,6 +72,9 @@ cairo_gl_surface_create_for_window (cairo_device_t *device,
 				    int width, int height);
 #endif
 
+cairo_public cairo_surface_t *
+cairo_gl_surface_create_for_current_gl_context(void);
+
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_GL_SURFACE */
-- 
1.6.6.1



More information about the cairo mailing list