Exemple #1
0
static void
_cairo_gl_texture_set_extend (cairo_gl_context_t *ctx,
                              GLuint              target,
                              cairo_extend_t      extend)
{
    assert (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base) ||
            (extend != CAIRO_EXTEND_REPEAT && extend != CAIRO_EXTEND_REFLECT));

    switch (extend) {
    case CAIRO_EXTEND_NONE:
	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) {
	    glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	    glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}
	else {
	    glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
	    glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
	}
	break;
    case CAIRO_EXTEND_PAD:
	glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	break;
    case CAIRO_EXTEND_REPEAT:
	glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_REPEAT);
	break;
    case CAIRO_EXTEND_REFLECT:
	glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
	glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
	break;
    }
}
Exemple #2
0
static void
_cairo_gl_texture_set_extend (cairo_gl_context_t *ctx,
                              GLuint              target,
                              cairo_extend_t      extend,
                              cairo_bool_t 	      use_atlas)
{
    GLint wrap_mode;
    assert (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base) ||
            (extend != CAIRO_EXTEND_REPEAT && extend != CAIRO_EXTEND_REFLECT));

    switch (extend) {
    case CAIRO_EXTEND_NONE:
	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES)
	    wrap_mode = GL_CLAMP_TO_EDGE;
	else
	    wrap_mode = GL_CLAMP_TO_BORDER;
	break;
    case CAIRO_EXTEND_PAD:
	wrap_mode = GL_CLAMP_TO_EDGE;
	break;
    case CAIRO_EXTEND_REPEAT:
	if (ctx->has_npot_repeat)
	    wrap_mode = GL_REPEAT;
	else
	    wrap_mode = GL_CLAMP_TO_EDGE;
	break;
    case CAIRO_EXTEND_REFLECT:
	if (ctx->has_npot_repeat)
	    wrap_mode = GL_MIRRORED_REPEAT;
	else
	    wrap_mode = GL_CLAMP_TO_EDGE;
	break;
    default:
	wrap_mode = 0;
    }

    if (likely (wrap_mode)) {
	glTexParameteri (target, GL_TEXTURE_WRAP_S, wrap_mode);
	glTexParameteri (target, GL_TEXTURE_WRAP_T, wrap_mode);
    }
}
Exemple #3
0
static void
_cairo_gl_surface_embedded_operand_init (cairo_gl_surface_t *surface)
{
    cairo_gl_operand_t *operand = &surface->operand;
    cairo_surface_attributes_t *attributes = &operand->texture.attributes;

    memset (operand, 0, sizeof (cairo_gl_operand_t));

    operand->type = CAIRO_GL_OPERAND_TEXTURE;
    operand->texture.surface = surface;
    operand->texture.tex = surface->tex;

    if (_cairo_gl_device_requires_power_of_two_textures (surface->base.device)) {
	cairo_matrix_init_identity (&attributes->matrix);
    } else {
	cairo_matrix_init_scale (&attributes->matrix,
				 1.0 / surface->width,
				 1.0 / surface->height);
    }

    attributes->extend = CAIRO_EXTEND_NONE;
    attributes->filter = CAIRO_FILTER_NEAREST;
}
Exemple #4
0
static cairo_int_status_t
_cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
				 cairo_gl_glyph_cache_t *cache,
				 cairo_scaled_glyph_t  *scaled_glyph)
{
    cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
    cairo_gl_glyph_t *glyph_private;
    cairo_rtree_node_t *node = NULL;
    cairo_int_status_t status;
    int width, height;

    width = glyph_surface->width;
    if (width < GLYPH_CACHE_MIN_SIZE)
	width = GLYPH_CACHE_MIN_SIZE;
    height = glyph_surface->height;
    if (height < GLYPH_CACHE_MIN_SIZE)
	height = GLYPH_CACHE_MIN_SIZE;

    /* search for an available slot */
    status = _cairo_rtree_insert (&cache->rtree, width, height, &node);
    /* search for an unlocked slot */
    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
	status = _cairo_rtree_evict_random (&cache->rtree,
				            width, height, &node);
	if (status == CAIRO_INT_STATUS_SUCCESS) {
	    status = _cairo_rtree_node_insert (&cache->rtree,
		                               node, width, height, &node);
	}
    }
    if (status)
	return status;

    /* XXX: Make sure we use the mask texture. This should work automagically somehow */
    if(ctx->states_cache.active_texture != GL_TEXTURE1)
    {
        glActiveTexture (GL_TEXTURE1);
        ctx->states_cache.active_texture = GL_TEXTURE1;
    }
    status = _cairo_gl_surface_draw_image (cache->surface, glyph_surface,
                                           0, 0,
                                           glyph_surface->width, glyph_surface->height,
                                           node->x, node->y);
    if (unlikely (status))
	return status;

    glyph_private = (cairo_gl_glyph_t *) node;
    glyph_private->cache = cache;
    glyph_private->glyph = scaled_glyph;
    _cairo_scaled_glyph_attach_private (scaled_glyph,
					&glyph_private->base,
					cache,
					_cairo_gl_glyph_fini);

    scaled_glyph->dev_private = glyph_private;
    scaled_glyph->dev_private_key = cache;

    /* compute tex coords */
    glyph_private->p1.x = node->x;
    glyph_private->p1.y = node->y;
    glyph_private->p2.x = node->x + glyph_surface->width;
    glyph_private->p2.y = node->y + glyph_surface->height;
    if (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base)) {
	glyph_private->p1.x /= GLYPH_CACHE_WIDTH;
	glyph_private->p2.x /= GLYPH_CACHE_WIDTH;
	glyph_private->p1.y /= GLYPH_CACHE_HEIGHT;
	glyph_private->p2.y /= GLYPH_CACHE_HEIGHT;
    }

    return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
					 const cairo_pattern_t *_src,
					 cairo_gl_surface_t *dst,
					 const cairo_rectangle_int_t *sample,
					 const cairo_rectangle_int_t *extents,
					 cairo_bool_t use_texgen)
{
    const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
    cairo_surface_pattern_t local_pattern;
    cairo_surface_subsurface_t *sub;
    cairo_gl_surface_t *surface;
    cairo_gl_context_t *ctx;
    cairo_surface_attributes_t *attributes;
    cairo_status_t status;

    sub = (cairo_surface_subsurface_t *) src->surface;

    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
    {
	status = _cairo_gl_context_acquire (dst->base.device, &ctx);
	if (unlikely (status))
	    return status;

	/* XXX Trim surface to the sample area within the subsurface? */
	surface = (cairo_gl_surface_t *)
	    _cairo_gl_surface_create_scratch (ctx,
					      sub->target->content,
					      sub->extents.width,
					      sub->extents.height);
	if (surface->base.status)
	    return _cairo_gl_context_release (ctx, surface->base.status);

	_cairo_pattern_init_for_surface (&local_pattern, sub->target);
	cairo_matrix_init_translate (&local_pattern.base.matrix,
				     sub->extents.x, sub->extents.y);
	local_pattern.base.filter = CAIRO_FILTER_NEAREST;
	status = _cairo_surface_paint (&surface->base,
				       CAIRO_OPERATOR_SOURCE,
				       &local_pattern.base,
				       NULL);
	_cairo_pattern_fini (&local_pattern.base);

	status = _cairo_gl_context_release (ctx, status);
	if (unlikely (status)) {
	    cairo_surface_destroy (&surface->base);
	    return status;
	}

	_cairo_surface_subsurface_set_snapshot (&sub->base, &surface->base);
    }

    status = _cairo_gl_surface_resolve_multisampling (surface);
    if (unlikely (status))
        return status;

    attributes = &operand->texture.attributes;

    operand->type = CAIRO_GL_OPERAND_TEXTURE;
    operand->texture.surface = surface;
    operand->texture.owns_surface = surface;
    operand->texture.tex = surface->tex;

    if (_cairo_gl_device_requires_power_of_two_textures (dst->base.device)) {
	attributes->matrix = src->base.matrix;
    } else {
	cairo_matrix_t m;

	cairo_matrix_init_scale (&m,
				 1.0 / surface->width,
				 1.0 / surface->height);
	cairo_matrix_multiply (&attributes->matrix, &src->base.matrix, &m);
    }

    attributes->extend = src->base.extend;
    attributes->filter = src->base.filter;
    attributes->has_component_alpha = src->base.has_component_alpha;

    operand->texture.texgen = use_texgen;
    return CAIRO_STATUS_SUCCESS;
}