static cairo_int_status_t
composite (void			*_dst,
	   cairo_operator_t	op,
	   cairo_surface_t	*abstract_src,
	   cairo_surface_t	*abstract_mask,
	   int			src_x,
	   int			src_y,
	   int			mask_x,
	   int			mask_y,
	   int			dst_x,
	   int			dst_y,
	   unsigned int		width,
	   unsigned int		height)
{
    cairo_gl_composite_t setup;
    cairo_gl_context_t *ctx;
    cairo_int_status_t status;

    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
    if (unlikely (status))
        goto FAIL;

    _cairo_gl_composite_set_source_operand (&setup,
					    source_to_operand (abstract_src));
    _cairo_gl_operand_translate (&setup.src, dst_x-src_x, dst_y-src_y);

    _cairo_gl_composite_set_mask_operand (&setup,
					  source_to_operand (abstract_mask));
    _cairo_gl_operand_translate (&setup.mask, dst_x-mask_x, dst_y-mask_y);

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

    /* XXX clip */
    _cairo_gl_context_emit_rect (ctx, dst_x, dst_y, dst_x+width, dst_y+height);
    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);

FAIL:
    _cairo_gl_composite_fini (&setup);
    return status;
}
static cairo_int_status_t
composite_boxes (void			*_dst,
		 cairo_operator_t	op,
		 cairo_surface_t	*abstract_src,
		 cairo_surface_t	*abstract_mask,
		 int			src_x,
		 int			src_y,
		 int			mask_x,
		 int			mask_y,
		 int			dst_x,
		 int			dst_y,
		 cairo_boxes_t		*boxes,
		 const cairo_rectangle_int_t  *extents)
{
    cairo_gl_composite_t setup;
    cairo_gl_context_t *ctx;
    cairo_int_status_t status;

    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
    if (unlikely (status))
        goto FAIL;

    _cairo_gl_composite_set_source_operand (&setup,
					    source_to_operand (abstract_src));
    _cairo_gl_operand_translate (&setup.src, dst_x-src_x, dst_y-src_y);

    _cairo_gl_composite_set_mask_operand (&setup,
					  source_to_operand (abstract_mask));
    _cairo_gl_operand_translate (&setup.mask, dst_x-mask_x, dst_y-mask_y);

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

    emit_aligned_boxes (ctx, boxes);
    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);

FAIL:
    _cairo_gl_composite_fini (&setup);
    return status;
}
static cairo_int_status_t
composite_tristrip (void		*_dst,
		    cairo_operator_t	op,
		    cairo_surface_t	*abstract_src,
		    int			src_x,
		    int			src_y,
		    int			dst_x,
		    int			dst_y,
		    const cairo_rectangle_int_t *extents,
		    cairo_antialias_t	antialias,
		    cairo_tristrip_t	*strip)
{
    cairo_gl_composite_t setup;
    cairo_gl_context_t *ctx;
    cairo_gl_surface_t *mask;
    cairo_int_status_t status;

    mask = tristrip_to_surface (_dst, extents, antialias, strip);
    if (unlikely (mask->base.status))
	return mask->base.status;

    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
    if (unlikely (status))
        goto FAIL;

    _cairo_gl_composite_set_source_operand (&setup,
					    source_to_operand (abstract_src));

    //_cairo_gl_composite_set_mask_surface (&setup, mask, 0, 0);

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

    /* XXX clip */
    _cairo_gl_context_emit_rect (ctx,
				 dst_x, dst_y,
				 dst_x+extents->width,
				 dst_y+extents->height);
    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);

FAIL:
    _cairo_gl_composite_fini (&setup);
    cairo_surface_destroy (&mask->base);
    return status;
}
static cairo_int_status_t
composite_traps (void			*_dst,
		 cairo_operator_t	op,
		 cairo_surface_t	*abstract_src,
		 int			src_x,
		 int			src_y,
		 int			dst_x,
		 int			dst_y,
		 const cairo_rectangle_int_t *extents,
		 cairo_antialias_t	antialias,
		 cairo_traps_t		*traps)
{
    cairo_gl_composite_t setup;
    cairo_gl_context_t *ctx;
    cairo_int_status_t status;

    status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
    if (unlikely (status))
        goto FAIL;

    _cairo_gl_composite_set_source_operand (&setup,
					    source_to_operand (abstract_src));
    _cairo_gl_operand_translate (&setup.src, -src_x-dst_x, -src_y-dst_y);
    status = traps_to_operand (_dst, extents, antialias, traps, &setup.mask, dst_x, dst_y);
    if (unlikely (status))
	goto FAIL;

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

    /* XXX clip */
    _cairo_gl_context_emit_rect (ctx,
				 extents->x-dst_x, extents->y-dst_y,
				 extents->x-dst_x+extents->width,
				 extents->y-dst_y+extents->height);
    status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);

FAIL:
    _cairo_gl_composite_fini (&setup);
    return status;
}
Example #5
0
static cairo_status_t
render_glyphs (cairo_gl_surface_t *dst,
	       int dst_x, int dst_y,
	       cairo_operator_t op,
	       cairo_surface_t *source,
	       cairo_composite_glyphs_info_t *info,
	       cairo_bool_t *has_component_alpha,
	       cairo_clip_t *clip,
	       cairo_bool_t via_msaa_compositor)
{
    cairo_format_t last_format = CAIRO_FORMAT_INVALID;
    cairo_gl_glyph_cache_t *cache = NULL;
    cairo_gl_context_t *ctx;
    cairo_gl_composite_t setup;
    cairo_int_status_t status;
    int i = 0;
    cairo_bool_t is_argb32;

    TRACE ((stderr, "%s (%d, %d)x(%d, %d)\n", __FUNCTION__,
	    info->extents.x, info->extents.y,
	    info->extents.width, info->extents.height));

    *has_component_alpha = FALSE;

    status = _cairo_gl_context_acquire (dst->base.device, &ctx);
    if (unlikely (status))
	return status;

    /* Traps compositor never has CLEAR operator. */
    is_argb32 =
	info->font->options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ||
	info->font->options.antialias == CAIRO_ANTIALIAS_BEST;

    /* If we are invoked by traps compositor, we keep what is in code
       otherwise, we handle non-subpixel/best directly in msaa
       compositor. */
    if (!via_msaa_compositor)
            status = _cairo_gl_composite_init (&setup, op, dst, TRUE);
    else if (info->font->options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ||
       info->font->options.antialias == CAIRO_ANTIALIAS_BEST)
        status = _cairo_gl_composite_init (&setup, op, dst, TRUE);
    else
        status = _cairo_gl_composite_init (&setup, op, dst, FALSE);

    if (unlikely (status))
	goto FINISH;

    if (source == NULL) {
	    _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_WHITE);
    } else {
	    _cairo_gl_composite_set_source_operand (&setup,
						    source_to_operand (source));

    }

    if (setup.src.type == CAIRO_GL_OPERAND_CONSTANT)
        setup.src.use_color_attribute = TRUE;

    _cairo_gl_composite_set_clip (&setup, clip);

    for (i = 0; i < info->num_glyphs; i++) {
	cairo_scaled_glyph_t *scaled_glyph;
	cairo_gl_glyph_t *glyph;
	double x_offset, y_offset;
	double x1, x2, y1, y2;

	status = _cairo_scaled_glyph_lookup (info->font,
					     info->glyphs[i].index,
					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
					     &scaled_glyph);
	if (unlikely (status))
	    goto FINISH;

	if (scaled_glyph->surface->width  == 0 ||
	    scaled_glyph->surface->height == 0)
	{
	    continue;
	}
	if (scaled_glyph->surface->format != last_format) {
	    status = cairo_gl_context_get_glyph_cache (ctx,
						       scaled_glyph->surface->format,
                                                       &cache);
            if (unlikely (status))
                goto FINISH;

	    last_format = scaled_glyph->surface->format;

	    /* In msaa compositor, clear operator needs component alpha,
	       we need to reset to FALSE if previously clear operator
	       has set it to TRUE. */
	    if (via_msaa_compositor) {
		if (op == CAIRO_OPERATOR_CLEAR || is_argb32)
		    cache->surface->operand.texture.attributes.has_component_alpha = TRUE;
		else
		    cache->surface->operand.texture.attributes.has_component_alpha = FALSE;
	    }
	    _cairo_gl_composite_set_mask_operand (&setup, &cache->surface->operand);
	    *has_component_alpha |= cache->surface->operand.texture.attributes.has_component_alpha;

	    /* XXX Shoot me. */
            status = _cairo_gl_composite_begin (&setup, &ctx);
            status = _cairo_gl_context_release (ctx, status);
	    if (unlikely (status))
		goto FINISH;
	}

	if (scaled_glyph->dev_private_key != cache) {
	    cairo_scaled_glyph_private_t *priv;

	    priv = _cairo_scaled_glyph_find_private (scaled_glyph, cache);
	    if (priv) {
		scaled_glyph->dev_private_key = cache;
		scaled_glyph->dev_private = cairo_container_of (priv,
								cairo_gl_glyph_t,
								base);
	    } else {
		status = _cairo_gl_glyph_cache_add_glyph (ctx, cache, scaled_glyph);

		if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
		    /* Cache is full, so flush existing prims and try again. */
		    _cairo_gl_composite_flush (ctx);
		    _cairo_gl_glyph_cache_unlock (cache);
		    status = _cairo_gl_glyph_cache_add_glyph (ctx, cache, scaled_glyph);
		}

		if (unlikely (_cairo_int_status_is_error (status)))
		    goto FINISH;
	    }
	}

	x_offset = scaled_glyph->surface->base.device_transform.x0;
	y_offset = scaled_glyph->surface->base.device_transform.y0;

	x1 = _cairo_lround (info->glyphs[i].x - x_offset - dst_x);
	y1 = _cairo_lround (info->glyphs[i].y - y_offset - dst_y);
	x2 = x1 + scaled_glyph->surface->width;
	y2 = y1 + scaled_glyph->surface->height;

	glyph = _cairo_gl_glyph_cache_lock (cache, scaled_glyph);
	_cairo_gl_composite_emit_glyph (ctx,
					x1, y1, x2, y2,
                                        glyph->p1.x, glyph->p1.y,
                                        glyph->p2.x, glyph->p2.y);
    }

    status = CAIRO_STATUS_SUCCESS;

  FINISH:
    status = _cairo_gl_context_release (ctx, status);

    _cairo_gl_composite_fini (&setup);
    return status;
}
Example #6
0
static cairo_status_t
render_glyphs (cairo_gl_surface_t *dst,
	       int dst_x, int dst_y,
	       cairo_operator_t op,
	       cairo_surface_t *source,
	       cairo_composite_glyphs_info_t *info,
	       cairo_bool_t *has_component_alpha,
	       cairo_clip_t *clip)
{
    cairo_format_t last_format = CAIRO_FORMAT_INVALID;
    cairo_gl_glyph_cache_t *cache = NULL;
    cairo_gl_context_t *ctx;
    cairo_gl_emit_glyph_t emit = NULL;
    cairo_gl_composite_t setup;
    cairo_int_status_t status;
    int i = 0;

    TRACE ((stderr, "%s (%d, %d)x(%d, %d)\n", __FUNCTION__,
	    info->extents.x, info->extents.y,
	    info->extents.width, info->extents.height));

    *has_component_alpha = FALSE;

    status = _cairo_gl_context_acquire (dst->base.device, &ctx);
    if (unlikely (status))
	return status;

    status = _cairo_gl_composite_init (&setup, op, dst, TRUE);
    if (unlikely (status))
	goto FINISH;

    if (source == NULL) {
	    _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_WHITE);
    } else {
	    _cairo_gl_composite_set_source_operand (&setup,
						    source_to_operand (source));

    }

    _cairo_gl_composite_set_clip (&setup, clip);

    for (i = 0; i < info->num_glyphs; i++) {
	cairo_scaled_glyph_t *scaled_glyph;
	cairo_gl_glyph_t *glyph;
	double x_offset, y_offset;
	double x1, x2, y1, y2;

	status = _cairo_scaled_glyph_lookup (info->font,
					     info->glyphs[i].index,
					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
					     &scaled_glyph);
	if (unlikely (status))
	    goto FINISH;

	if (scaled_glyph->surface->width  == 0 ||
	    scaled_glyph->surface->height == 0)
	{
	    continue;
	}
	if (scaled_glyph->surface->format != last_format) {
	    status = cairo_gl_context_get_glyph_cache (ctx,
						       scaled_glyph->surface->format,
                                                       &cache);
            if (unlikely (status))
                goto FINISH;

	    last_format = scaled_glyph->surface->format;

	    _cairo_gl_composite_set_mask_operand (&setup, &cache->surface->operand);
	    *has_component_alpha |= cache->surface->operand.texture.attributes.has_component_alpha;

	    /* XXX Shoot me. */
            status = _cairo_gl_composite_begin (&setup, &ctx);
            status = _cairo_gl_context_release (ctx, status);
	    if (unlikely (status))
		goto FINISH;

	    emit = _cairo_gl_context_choose_emit_glyph (ctx);
	}

	if (scaled_glyph->dev_private_key != cache) {
	    cairo_scaled_glyph_private_t *priv;

	    priv = _cairo_scaled_glyph_find_private (scaled_glyph, cache);
	    if (priv) {
		scaled_glyph->dev_private_key = cache;
		scaled_glyph->dev_private = cairo_container_of (priv,
								cairo_gl_glyph_t,
								base);
	    } else {
		status = _cairo_gl_glyph_cache_add_glyph (ctx, cache, scaled_glyph);

		if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
		    /* Cache is full, so flush existing prims and try again. */
		    _cairo_gl_composite_flush (ctx);
		    _cairo_gl_glyph_cache_unlock (cache);
		    status = _cairo_gl_glyph_cache_add_glyph (ctx, cache, scaled_glyph);
		}

		if (unlikely (_cairo_int_status_is_error (status)))
		    goto FINISH;
	    }
	}

	x_offset = scaled_glyph->surface->base.device_transform.x0;
	y_offset = scaled_glyph->surface->base.device_transform.y0;

	x1 = _cairo_lround (info->glyphs[i].x - x_offset - dst_x);
	y1 = _cairo_lround (info->glyphs[i].y - y_offset - dst_y);
	x2 = x1 + scaled_glyph->surface->width;
	y2 = y1 + scaled_glyph->surface->height;

	glyph = _cairo_gl_glyph_cache_lock (cache, scaled_glyph);
	assert (emit);
	emit (ctx,
	      x1, y1, x2, y2,
	      glyph->p1.x, glyph->p1.y,
	      glyph->p2.x, glyph->p2.y);
    }

    status = CAIRO_STATUS_SUCCESS;
  FINISH:
    status = _cairo_gl_context_release (ctx, status);

    _cairo_gl_composite_fini (&setup);
    return status;
}