cairo_status_t
_cairo_gl_composite_begin (cairo_gl_composite_t *setup,
			   cairo_gl_context_t **ctx_out)
{
    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;

    _cairo_gl_context_set_destination (ctx, setup->dst, setup->multisample);
    glEnable (GL_BLEND);

    status = _cairo_gl_set_operands_and_operator (setup, ctx);
    if (unlikely (status))
	goto FAIL;

    status = _cairo_gl_composite_setup_clipping (setup, ctx, ctx->vertex_size);
    if (unlikely (status))
	goto FAIL;

    *ctx_out = ctx;

FAIL:
    if (unlikely (status))
        status = _cairo_gl_context_release (ctx, status);

    return status;
}
/* Masking with the SOURCE operator requires two passes. In the first
 * pass we use the mask as the source to get:
 * result = (1 - ma) * dst
 * In the second pass we use the add operator to achieve:
 * result = (src * ma) + dst
 * Combined this produces:
 * result = (src * ma) + (1 - ma) * dst
 */
static cairo_int_status_t
_cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compositor,
        cairo_composite_rectangles_t *composite)
{
    cairo_gl_composite_t setup;
    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
    cairo_gl_context_t *ctx = NULL;
    cairo_int_status_t status;

    cairo_clip_t *clip = composite->clip;
    cairo_traps_t traps;

    /* If we have a non-rectangular clip, we can avoid using the stencil buffer
     * for clipping and just draw the clip polygon. */
    if (clip) {
        status = _clip_to_traps (clip, &traps);
        if (unlikely (status)) {
            _cairo_traps_fini (&traps);
            return status;
        }
    }

    status = _cairo_gl_composite_init (&setup,
                                       CAIRO_OPERATOR_DEST_OUT,
                                       dst,
                                       FALSE /* assume_component_alpha */);
    if (unlikely (status))
        return status;
    status = _cairo_gl_composite_set_source (&setup,
             &composite->mask_pattern.base,
             &composite->mask_sample_area,
             &composite->bounded,
             FALSE);
    if (unlikely (status))
        goto finish;
    _cairo_gl_composite_set_multisample (&setup);
    status = _cairo_gl_composite_begin (&setup, &ctx);
    if (unlikely (status))
        goto finish;

    if (! clip)
        status = _draw_int_rect (ctx, &setup, &composite->bounded);
    else
        status = _draw_traps (ctx, &setup, &traps);

    /* Now draw the second pass. */
    _cairo_gl_composite_set_operator (&setup, CAIRO_OPERATOR_ADD,
                                      FALSE /* assume_component_alpha */);
    if (unlikely (status))
        goto finish;
    status = _cairo_gl_composite_set_source (&setup,
             &composite->source_pattern.base,
             &composite->source_sample_area,
             &composite->bounded,
             FALSE);
    if (unlikely (status))
        goto finish;
    status = _cairo_gl_composite_set_mask (&setup,
                                           &composite->mask_pattern.base,
                                           &composite->source_sample_area,
                                           &composite->bounded,
                                           FALSE);
    if (unlikely (status))
        goto finish;
    status = _cairo_gl_set_operands_and_operator (&setup, ctx);
    if (unlikely (status))
        goto finish;

    if (! clip)
        status = _draw_int_rect (ctx, &setup, &composite->bounded);
    else
        status = _draw_traps (ctx, &setup, &traps);

finish:
    _cairo_gl_composite_fini (&setup);
    if (ctx)
        status = _cairo_gl_context_release (ctx, status);
    if (clip)
        _cairo_traps_fini (&traps);

    return status;
}