diff --git a/src/cairo-egl-context.c b/src/cairo-egl-context.c index 7093ea032..c373bd8ed 100644 --- a/src/cairo-egl-context.c +++ b/src/cairo-egl-context.c @@ -104,6 +104,8 @@ cairo_egl_device_create (EGLDisplay dpy, EGLContext egl) ctx->display = dpy; ctx->context = egl; + ctx->base.acquire = NULL; /* FIXME */ + ctx->base.release = NULL; /* FIXME */ ctx->base.make_current = _egl_make_current; ctx->base.swap_buffers = _egl_swap_buffers; ctx->base.destroy = _egl_destroy; diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index cfb563b5b..c283620d9 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -136,7 +136,10 @@ typedef struct _cairo_gl_context { cairo_gl_glyph_cache_t glyph_cache[2]; cairo_list_t fonts; - void (*make_current)(void *ctx, cairo_gl_surface_t *surface); + void (*acquire) (void *ctx); + void (*release) (void *ctx); + + void (*make_current) (void *ctx, cairo_gl_surface_t *surface); void (*swap_buffers)(void *ctx, cairo_gl_surface_t *surface); void (*destroy) (void *ctx); } cairo_gl_context_t; diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 9107d4d8e..5fca01814 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -67,6 +67,23 @@ static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface) return surface->backend == &_cairo_gl_surface_backend; } +static void +_gl_lock (void *device) +{ + cairo_gl_context_t *ctx = (cairo_gl_context_t *) device; + + ctx->acquire (ctx); +} + +static void +_gl_unlock (void *device) +{ + cairo_gl_context_t *ctx = (cairo_gl_context_t *) device; + + ctx->release (ctx); + ctx->current_target = NULL; +} + static void _gl_destroy (void *device) { @@ -94,7 +111,8 @@ _gl_destroy (void *device) static const cairo_device_backend_t _cairo_gl_device_backend = { CAIRO_DEVICE_TYPE_GL, - NULL, NULL, /* lock, unlock */ + _gl_lock, + _gl_unlock, NULL, /* flush */ NULL, /* finish */ diff --git a/src/cairo-glx-context.c b/src/cairo-glx-context.c index 0cc31d35c..f519443d2 100644 --- a/src/cairo-glx-context.c +++ b/src/cairo-glx-context.c @@ -52,6 +52,9 @@ typedef struct _cairo_glx_context { Display *display; Window dummy_window; GLXContext context; + + GLXContext prev_context; + GLXDrawable prev_drawable; } cairo_glx_context_t; typedef struct _cairo_glx_surface { @@ -61,8 +64,20 @@ typedef struct _cairo_glx_surface { } cairo_glx_surface_t; static void -_glx_make_current (void *abstract_ctx, - cairo_gl_surface_t *abstract_surface) +_glx_acquire (void *abstract_ctx) +{ + cairo_glx_context_t *ctx = abstract_ctx; + + ctx->prev_context = glXGetCurrentContext (); + ctx->prev_drawable = glXGetCurrentDrawable (); + + /* XXX: This is necessary with current code, but shouldn't be */ + if (ctx->prev_context != ctx->context) + glXMakeCurrent (ctx->display, ctx->dummy_window, ctx->context); +} + +static void +_glx_make_current (void *abstract_ctx, cairo_gl_surface_t *abstract_surface) { cairo_glx_context_t *ctx = abstract_ctx; cairo_glx_surface_t *surface = (cairo_glx_surface_t *) abstract_surface; @@ -71,6 +86,18 @@ _glx_make_current (void *abstract_ctx, glXMakeCurrent (ctx->display, surface->win, ctx->context); } +static void +_glx_release (void *abstract_ctx) +{ + cairo_glx_context_t *ctx = abstract_ctx; + + if (ctx->prev_context != glXGetCurrentContext () || + ctx->prev_drawable != glXGetCurrentDrawable ()) + glXMakeCurrent (ctx->display, + ctx->prev_drawable, + ctx->prev_context); +} + static void _glx_swap_buffers (void *abstract_ctx, cairo_gl_surface_t *abstract_surface) @@ -162,7 +189,11 @@ cairo_glx_device_create (Display *dpy, GLXContext gl_ctx) ctx->display = dpy; ctx->dummy_window = dummy; ctx->context = gl_ctx; + ctx->prev_context = NULL; + ctx->prev_drawable = None; + ctx->base.acquire = _glx_acquire; + ctx->base.release = _glx_release; ctx->base.make_current = _glx_make_current; ctx->base.swap_buffers = _glx_swap_buffers; ctx->base.destroy = _glx_destroy; @@ -173,6 +204,8 @@ cairo_glx_device_create (Display *dpy, GLXContext gl_ctx) return _cairo_gl_context_create_in_error (status); } + ctx->base.release (ctx); + return &ctx->base.base; }