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; } }
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); } }
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; }
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; }