[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