From db79880d9a836d50e9202caa5c73e22a2b6b97b3 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 26 May 2010 13:03:12 +0200 Subject: [PATCH] gl: Make gl_composite_begin() acquire the context Also remove the previous places for context acquisition. This completes fixing the potential ABBA deadlock I talked about a few commits ago. --- src/cairo-gl-composite.c | 21 +++++++++++++++++---- src/cairo-gl-glyphs.c | 7 ++++++- src/cairo-gl-private.h | 4 ++-- src/cairo-gl-surface.c | 26 +++++--------------------- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c index 80a7e4fe5..be9f83074 100644 --- a/src/cairo-gl-composite.c +++ b/src/cairo-gl-composite.c @@ -1041,19 +1041,26 @@ _cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx, } cairo_status_t -_cairo_gl_composite_begin (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup) +_cairo_gl_composite_begin (cairo_gl_composite_t *setup, + cairo_gl_context_t **ctx_out) { unsigned int dst_size, src_size, mask_size; + cairo_gl_context_t *ctx; cairo_status_t status; + assert (setup->dst); + + status = _cairo_gl_context_acquire (setup->dst->base.device, &ctx); + if (unlikely (status)) + return status; + assert (! _cairo_gl_context_is_in_progress (ctx)); /* Do various magic for component alpha */ if (setup->has_component_alpha) { status = _cairo_gl_composite_begin_component_alpha (ctx, setup); if (unlikely (status)) - return status; + goto FAIL; } status = _cairo_gl_set_shader_by_type (ctx, @@ -1063,7 +1070,7 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx, : CAIRO_GL_SHADER_IN_NORMAL); if (unlikely (status)) { setup->pre_shader = NULL; - return status; + goto FAIL; } status = CAIRO_STATUS_SUCCESS; @@ -1098,6 +1105,12 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx, if (setup->clip_region) glEnable (GL_SCISSOR_TEST); + *ctx_out = ctx; + +FAIL: + if (unlikely (status)) + _cairo_gl_context_release (ctx); + return status; } diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c index 1890ee2ed..ca0b596c1 100644 --- a/src/cairo-gl-glyphs.c +++ b/src/cairo-gl-glyphs.c @@ -309,9 +309,14 @@ _render_glyphs (cairo_gl_surface_t *dst, *has_component_alpha |= cache->pattern.base.has_component_alpha; - status = _cairo_gl_composite_begin (ctx, &setup); + status = _cairo_gl_composite_begin (&setup, &ctx); if (unlikely (status)) goto FINISH; + + /* XXX: _cairo_gl_composite_begin() acquires the context a + * second time. Need to refactor this loop so this doesn't happen. + */ + _cairo_gl_context_release (ctx); } if (scaled_glyph->surface_private == NULL) { diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index 9d36c453b..d15e57581 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -316,8 +316,8 @@ cairo_private void _cairo_gl_composite_set_mask_spans (cairo_gl_composite_t *setup); cairo_private cairo_status_t -_cairo_gl_composite_begin (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup); +_cairo_gl_composite_begin (cairo_gl_composite_t *setup, + cairo_gl_context_t **ctx); cairo_private void _cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx, diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 54526b3e2..53cba2003 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -913,10 +913,6 @@ _cairo_gl_surface_composite (cairo_operator_t op, } } - status = _cairo_gl_context_acquire (dst->base.device, &ctx); - if (unlikely (status)) - return status; - status = _cairo_gl_composite_init (&setup, op, dst, mask && mask->has_component_alpha, &rect); @@ -937,7 +933,7 @@ _cairo_gl_surface_composite (cairo_operator_t op, if (unlikely (status)) goto CLEANUP; - status = _cairo_gl_composite_begin (ctx, &setup); + status = _cairo_gl_composite_begin (&setup, &ctx); if (unlikely (status)) goto CLEANUP; @@ -963,9 +959,9 @@ _cairo_gl_surface_composite (cairo_operator_t op, } _cairo_gl_composite_end (ctx, &setup); + _cairo_gl_context_release (ctx); CLEANUP: - _cairo_gl_context_release (ctx); _cairo_gl_composite_fini (&setup); return status; @@ -1040,10 +1036,6 @@ _cairo_gl_surface_fill_rectangles (void *abstract_dst, cairo_gl_composite_t setup; int i; - status = _cairo_gl_context_acquire (dst->base.device, &ctx); - if (unlikely (status)) - return status; - status = _cairo_gl_composite_init (&setup, op, dst, FALSE, /* XXX */ NULL); @@ -1065,7 +1057,7 @@ _cairo_gl_surface_fill_rectangles (void *abstract_dst, if (unlikely (status)) goto CLEANUP; - status = _cairo_gl_composite_begin (ctx, &setup); + status = _cairo_gl_composite_begin (&setup, &ctx); if (unlikely (status)) goto CLEANUP; @@ -1079,9 +1071,9 @@ _cairo_gl_surface_fill_rectangles (void *abstract_dst, } _cairo_gl_composite_end (ctx, &setup); + _cairo_gl_context_release (ctx); CLEANUP: - _cairo_gl_context_release (ctx); _cairo_gl_composite_fini (&setup); return status; @@ -1238,12 +1230,6 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op, renderer->xmin = extents->x; renderer->xmax = extents->x + extents->width; - status = _cairo_gl_context_acquire (dst->base.device, &renderer->ctx); - if (unlikely (status)) { - free (renderer); - return _cairo_span_renderer_create_in_error (status); - } - status = _cairo_gl_composite_init (&renderer->setup, op, dst, FALSE, extents); @@ -1260,15 +1246,13 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op, _cairo_gl_composite_set_mask_spans (&renderer->setup); _cairo_gl_composite_set_clip_region (&renderer->setup, clip_region); - status = _cairo_gl_composite_begin (renderer->ctx, &renderer->setup); + status = _cairo_gl_composite_begin (&renderer->setup, &renderer->ctx); if (unlikely (status)) goto FAIL; return &renderer->base; - FAIL: - _cairo_gl_context_release (renderer->ctx); _cairo_gl_composite_fini (&renderer->setup); free (renderer); return _cairo_span_renderer_create_in_error (status);