gl: Add a non-thread-aware mode for GL devices

GLX and EGL devices are thread-aware currently. This
is safe, but on certain GPUs can be very expensive. In
this patch, we expose a new API which turns off the
safety feature in cases where performance is a priority.
This commit is contained in:
Martin Robinson 2012-02-28 10:50:16 -08:00
parent 9741099093
commit 5c4087af81
5 changed files with 25 additions and 3 deletions

View file

@ -80,6 +80,8 @@ static void
_egl_release (void *abstract_ctx)
{
cairo_egl_context_t *ctx = abstract_ctx;
if (!ctx->base.thread_aware)
return;
eglMakeCurrent (ctx->display,
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

View file

@ -185,6 +185,8 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
ctx->compositor = _cairo_gl_span_compositor_get ();
ctx->thread_aware = TRUE;
memset (ctx->glyph_cache, 0, sizeof (ctx->glyph_cache));
cairo_list_init (&ctx->fonts);
@ -703,3 +705,14 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
_gl_identity_ortho (ctx->modelviewprojection_matrix,
0, surface->width, surface->height, 0);
}
void
cairo_gl_device_set_thread_aware (cairo_device_t *device,
cairo_bool_t thread_aware)
{
if (device->backend->type != CAIRO_DEVICE_TYPE_GL) {
_cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
return;
}
((cairo_gl_context_t *) device)->thread_aware = thread_aware;
}

View file

@ -349,6 +349,8 @@ struct _cairo_gl_context {
cairo_bool_t has_packed_depth_stencil;
cairo_bool_t has_npot_repeat;
cairo_bool_t thread_aware;
void (*acquire) (void *ctx);
void (*release) (void *ctx);

View file

@ -88,6 +88,10 @@ cairo_gl_surface_get_height (cairo_surface_t *abstract_surface);
cairo_public void
cairo_gl_surface_swapbuffers (cairo_surface_t *surface);
cairo_public void
cairo_gl_device_set_thread_aware (cairo_device_t *device,
cairo_bool_t thread_aware);
#if CAIRO_HAS_GLX_FUNCTIONS
#include <GL/glx.h>

View file

@ -94,9 +94,10 @@ _glx_release (void *abstract_ctx)
{
cairo_glx_context_t *ctx = abstract_ctx;
if (!ctx->has_multithread_makecurrent) {
glXMakeCurrent (ctx->display, None, None);
}
if (ctx->has_multithread_makecurrent || !ctx->base.thread_aware)
return;
glXMakeCurrent (ctx->display, None, None);
}
static void