[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