[cairo] [PATCH 3/3] egl: Use MESA_no_surface extension when available

Kristian Høgsberg krh at bitplanet.net
Thu Jun 17 15:30:35 PDT 2010


This lets us avoid creating a throwaway pbuffer just to make the
context current.
---
 src/cairo-egl-context.c |   82 +++++++++++++++++++++++++++++++++++-----------
 1 files changed, 62 insertions(+), 20 deletions(-)

diff --git a/src/cairo-egl-context.c b/src/cairo-egl-context.c
index 77d8547..3b979e9 100644
--- a/src/cairo-egl-context.c
+++ b/src/cairo-egl-context.c
@@ -42,6 +42,8 @@
 
 #include "cairo-error-private.h"
 
+#include <EGL/eglext.h>
+
 typedef struct _cairo_egl_context {
     cairo_gl_context_t base;
 
@@ -118,6 +120,43 @@ _egl_destroy (void *abstract_ctx)
     eglDestroySurface (ctx->display, ctx->dummy_surface);
 }
 
+static cairo_bool_t
+_egl_make_current_no_surface(cairo_egl_context_t *ctx)
+{
+#ifdef EGL_MESA_no_surface
+    EGLConfig config;
+    EGLint value, count;
+    const char *extensions;
+    EGLint config_attribs[] = {
+	EGL_CONFIG_ID,		0,
+	EGL_NONE
+    };
+
+    extensions = eglQueryString(ctx->display, EGL_EXTENSIONS);
+    fprintf(stderr, "egl extensions: %s\n", extensions);
+    if (!strstr(extensions, "EGL_MESA_no_surface"))
+	return FALSE;
+    eglQueryContext(ctx->display, ctx->context,
+		    EGL_CONFIG_ID, &config_attribs[1]);
+    if (!eglChooseConfig(ctx->display, config_attribs, &config, 1, &count))
+	return FALSE;
+    if (count == 0)
+	return FALSE;
+    if (!eglGetConfigAttrib(ctx->display, config,
+			    EGL_NO_SURFACE_CAPABLE_MESA, &value))
+	return FALSE;
+    if (!(value & EGL_OPENGL_BIT))
+	return FALSE;
+    if (!eglMakeCurrent(ctx->display,
+			EGL_NO_SURFACE, EGL_NO_SURFACE, ctx->context))
+	return FALSE;
+
+    return TRUE;
+#endif
+
+    return FALSE;
+}
+
 cairo_device_t *
 cairo_egl_device_create (EGLDisplay dpy, EGLContext egl)
 {
@@ -144,30 +183,33 @@ cairo_egl_device_create (EGLDisplay dpy, EGLContext egl)
     ctx->base.swap_buffers = _egl_swap_buffers;
     ctx->base.destroy = _egl_destroy;
 
-    /* dummy surface, meh. */
-    eglGetConfigs (dpy, NULL, 0, &numConfigs);
-    configs = malloc (sizeof(*configs) *numConfigs);
-    if (configs == NULL) {
-	free (ctx);
-	return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
-    }
-    eglGetConfigs (dpy, configs, numConfigs, &numConfigs);
-    ctx->dummy_surface = eglCreatePbufferSurface (dpy, configs[0], attribs);
-    free (configs);
-
-    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);
+    if (!_egl_make_current_no_surface (ctx)) {
+	/* Fall back to dummy surface, meh. */
+	eglGetConfigs (dpy, NULL, 0, &numConfigs);
+	configs = malloc (sizeof(*configs) *numConfigs);
+	if (configs == NULL) {
+	    free (ctx);
+	    return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
+	}
+	eglGetConfigs (dpy, configs, numConfigs, &numConfigs);
+	ctx->dummy_surface = eglCreatePbufferSurface (dpy, configs[0], attribs);
+	free (configs);
+
+	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_context_init (&ctx->base);
     if (unlikely (status)) {
-	eglDestroySurface (dpy, ctx->dummy_surface);
+	if (ctx->dummy_surface != EGL_NO_SURFACE)
+	    eglDestroySurface (dpy, ctx->dummy_surface);
 	free (ctx);
 	return _cairo_gl_context_create_in_error (status);
     }
-- 
1.7.1



More information about the cairo mailing list