[cairo-commit] src/cairo-gl-operand.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Feb 4 13:08:32 PST 2012


 src/cairo-gl-operand.c |   47 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 40 insertions(+), 7 deletions(-)

New commits:
commit 8c3b86787acf525df24a3b147da73398b7d1571c
Author: Martin Robinson <mrobinson at igalia.com>
Date:   Fri Jan 27 15:30:12 2012 -0800

    gl: Fix gl-source-surface test
    
    When painting a GL surface pattern from one context to a
    a surface of another context, be careful to manage the
    multiple contexts so that they do not stomp on each other.
    
    [ickle: Preserve fast path for GL subsurfaces]

diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
index bc5e541..660b407 100644
--- a/src/cairo-gl-operand.c
+++ b/src/cairo-gl-operand.c
@@ -86,10 +86,15 @@ _cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
 
     sub = (cairo_surface_subsurface_t *) src->surface;
 
-    if (sub->snapshot && sub->snapshot->type == CAIRO_SURFACE_TYPE_GL) {
+    if (sub->snapshot &&
+	sub->snapshot->type == CAIRO_SURFACE_TYPE_GL &&
+	sub->snapshot->device == dst->base.device)
+    {
 	surface = (cairo_gl_surface_t *)
 	    cairo_surface_reference (sub->snapshot);
-    } else {
+    }
+    else
+    {
 	status = _cairo_gl_context_acquire (dst->base.device, &ctx);
 	if (unlikely (status))
 	    return status;
@@ -167,6 +172,8 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
     }
 
     surface = (cairo_gl_surface_t *) sub->target;
+    if (surface->base.device != dst->base.device)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     /* Translate the matrix from
      * (unnormalized src -> unnormalized src) to
@@ -211,6 +218,9 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
+    if (surface->base.device != dst->base.device)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
     *operand = surface->operand;
 
     attributes = &operand->texture.attributes;
@@ -234,6 +244,12 @@ _cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand,
     cairo_gl_surface_t *surface;
     cairo_gl_context_t *ctx;
     cairo_surface_t *image;
+    cairo_bool_t src_is_gl_surface = FALSE;
+
+    if (_src->type == CAIRO_PATTERN_TYPE_SURFACE) {
+	cairo_surface_t* src_surface = ((cairo_surface_pattern_t *) _src)->surface;
+	src_is_gl_surface = src_surface->type == CAIRO_SURFACE_TYPE_GL;
+    }
 
     status = _cairo_gl_context_acquire (dst->base.device, &ctx);
     if (unlikely (status))
@@ -243,22 +259,39 @@ _cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand,
 	_cairo_gl_surface_create_scratch (ctx,
 					  CAIRO_CONTENT_COLOR_ALPHA,
 					  extents->width, extents->height);
-
     image = cairo_surface_map_to_image (&surface->base, NULL);
+
+    /* If the pattern is a GL surface, it belongs to some other GL context,
+       so we need to release this device while we paint it to the image. */
+    if (src_is_gl_surface) {
+	status = _cairo_gl_context_release (ctx, status);
+	if (unlikely (status))
+	    goto fail;
+    }
+
     status = _cairo_surface_offset_paint (image, extents->x, extents->y,
 					  CAIRO_OPERATOR_SOURCE, _src, NULL);
+
+    if (src_is_gl_surface) {
+	status = _cairo_gl_context_acquire (dst->base.device, &ctx);
+	if (unlikely (status))
+	    goto fail;
+    }
+
     cairo_surface_unmap_image (&surface->base, image);
     status = _cairo_gl_context_release (ctx, status);
-    if (unlikely (status)) {
-	cairo_surface_destroy (&surface->base);
-	return status;
-    }
+    if (unlikely (status))
+	goto fail;
 
     *operand = surface->operand;
     operand->texture.owns_surface = surface;
     operand->texture.attributes.matrix.x0 -= extents->x * operand->texture.attributes.matrix.xx;
     operand->texture.attributes.matrix.y0 -= extents->y * operand->texture.attributes.matrix.yy;
     return CAIRO_STATUS_SUCCESS;
+
+fail:
+    cairo_surface_destroy (&surface->base);
+    return status;
 }
 
 void


More information about the cairo-commit mailing list