mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-09 02:38:07 +02:00
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]
This commit is contained in:
parent
b52296a435
commit
8c3b86787a
1 changed files with 40 additions and 7 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue