[cairo] [PATCH 2/2] gl: Take advantage of GLX_MESA_multithread_makecurrent to avoid unbinding.

Eric Anholt eric at anholt.net
Mon Feb 21 14:41:12 PST 2011


Because of GLX's unfortunate requirement that only one context have a
thread current at a time, we had to unbind the context, triggering a
flush, and eating of all the CPU.  With a small tweak to the GLX spec
by GLX_MESA_multithread_makecurrent, and a small tweak to Mesa that
consisted mostly of deleting the "is this thread already bound
elsewhere?" check, we can bind our context to any thread and use it
safely as long as our usage of it is mutexed, which is already
supposed to be a requirement of using cairo objects from multiple
threads.

[  0] before      firefox-talos-gfx   50.260   50.525   0.25%    3/3
[  0] after       firefox-talos-gfx   32.091   32.422   0.65%    3/3
---
 src/cairo-glx-context.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/src/cairo-glx-context.c b/src/cairo-glx-context.c
index 83963fb..f89fa32 100644
--- a/src/cairo-glx-context.c
+++ b/src/cairo-glx-context.c
@@ -52,6 +52,8 @@ typedef struct _cairo_glx_context {
     Display *display;
     Window dummy_window;
     GLXContext context;
+
+    cairo_bool_t has_multithread_makecurrent;
 } cairo_glx_context_t;
 
 typedef struct _cairo_glx_surface {
@@ -92,7 +94,9 @@ _glx_release (void *abstract_ctx)
 {
     cairo_glx_context_t *ctx = abstract_ctx;
 
-    glXMakeCurrent (ctx->display, None, None);
+    if (!ctx->has_multithread_makecurrent) {
+	glXMakeCurrent (ctx->display, None, None);
+    }
 }
 
 static void
@@ -174,6 +178,7 @@ 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;
 
     status = _glx_dummy_ctx (dpy, gl_ctx, &dummy);
     if (unlikely (status))
@@ -206,6 +211,11 @@ cairo_glx_device_create (Display *dpy, GLXContext gl_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;
-- 
1.7.4.1



More information about the cairo mailing list