summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-05-18 12:49:59 +0200
committerBenjamin Otte <otte@redhat.com>2010-05-20 11:00:50 +0200
commit208d9f2a7e1f66ff2764c41fe67f65e27279b2ab (patch)
tree9de265f930faa0f6f40edce0a1c68c19149433e3
parent050117996339cfe35add1f2cd44d0e5578d4a981 (diff)
gl: Make glyph cache a real surface
This has the huge advantage that we can use real surface functions on it.
-rw-r--r--src/cairo-gl-glyphs.c67
-rw-r--r--src/cairo-gl-private.h3
2 files changed, 26 insertions, 44 deletions
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 7d187c5d..b49f8894 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -60,6 +60,7 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
+ cairo_gl_surface_t *cache_surface;
cairo_gl_glyph_private_t *glyph_private;
cairo_rtree_node_t *node = NULL;
cairo_image_surface_t *clone = NULL;
@@ -111,8 +112,10 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
if (status)
return status;
+ cache_surface = (cairo_gl_surface_t *) cache->pattern.surface;
+
glActiveTexture (GL_TEXTURE1);
- glBindTexture (ctx->tex_target, cache->tex);
+ glBindTexture (ctx->tex_target, cache_surface->tex);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glPixelStorei (GL_UNPACK_ROW_LENGTH,
@@ -137,10 +140,10 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
glyph_private->p2.x = node->x + glyph_surface->width;
glyph_private->p2.y = node->y + glyph_surface->height;
if (ctx->tex_target != GL_TEXTURE_RECTANGLE_EXT) {
- glyph_private->p1.x /= cache->width;
- glyph_private->p1.y /= cache->height;
- glyph_private->p2.x /= cache->width;
- glyph_private->p2.y /= cache->height;
+ glyph_private->p1.x /= cache_surface->width;
+ glyph_private->p1.y /= cache_surface->height;
+ glyph_private->p2.x /= cache_surface->width;
+ glyph_private->p2.y /= cache_surface->height;
}
cairo_surface_destroy (&clone->base);
@@ -160,53 +163,35 @@ cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
cairo_format_t format)
{
cairo_gl_glyph_cache_t *cache;
+ cairo_content_t content;
switch (format) {
case CAIRO_FORMAT_RGB16_565:
case CAIRO_FORMAT_ARGB32:
case CAIRO_FORMAT_RGB24:
cache = &ctx->glyph_cache[0];
- format = CAIRO_FORMAT_ARGB32;
+ content = CAIRO_CONTENT_COLOR_ALPHA;
break;
case CAIRO_FORMAT_A8:
case CAIRO_FORMAT_A1:
cache = &ctx->glyph_cache[1];
- format = CAIRO_FORMAT_A8;
+ content = CAIRO_CONTENT_ALPHA;
break;
case CAIRO_FORMAT_INVALID:
ASSERT_NOT_REACHED;
return NULL;
}
- if (unlikely (cache->tex == 0)) {
- GLenum internal_format;
-
- cache->width = GLYPH_CACHE_WIDTH;
- cache->height = GLYPH_CACHE_HEIGHT;
-
- switch (format) {
- case CAIRO_FORMAT_A1:
- case CAIRO_FORMAT_RGB16_565:
- case CAIRO_FORMAT_RGB24:
- ASSERT_NOT_REACHED;
- case CAIRO_FORMAT_ARGB32:
- internal_format = GL_RGBA;
- break;
- case CAIRO_FORMAT_A8:
- internal_format = GL_ALPHA;
- break;
- case CAIRO_FORMAT_INVALID:
- ASSERT_NOT_REACHED;
- return NULL;
- }
-
- glGenTextures (1, &cache->tex);
- glBindTexture (ctx->tex_target, cache->tex);
- glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D (ctx->tex_target, 0, internal_format,
- GLYPH_CACHE_WIDTH, GLYPH_CACHE_HEIGHT, 0,
- internal_format, GL_FLOAT, NULL);
+ if (unlikely (cache->pattern.surface == NULL)) {
+ cairo_surface_t *surface;
+ surface = cairo_gl_surface_create (&ctx->base,
+ content,
+ GLYPH_CACHE_WIDTH,
+ GLYPH_CACHE_HEIGHT);
+ _cairo_surface_release_device_reference (surface);
+ _cairo_pattern_init_for_surface (&cache->pattern, surface);
+ cairo_surface_destroy (surface);
+ cache->pattern.base.has_component_alpha = (content == CAIRO_CONTENT_COLOR_ALPHA);
}
return cache;
@@ -350,7 +335,7 @@ _render_glyphs (cairo_gl_surface_t *dst,
_cairo_gl_composite_set_mask_texture (ctx,
&setup,
- cache->tex,
+ ((cairo_gl_surface_t *) cache->pattern.surface)->tex,
last_format == CAIRO_FORMAT_ARGB32);
if (last_format == CAIRO_FORMAT_ARGB32)
@@ -627,8 +612,6 @@ EMPTY:
void
_cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache)
{
- cache->tex = 0;
-
_cairo_rtree_init (&cache->rtree,
GLYPH_CACHE_WIDTH,
GLYPH_CACHE_HEIGHT,
@@ -642,9 +625,9 @@ _cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
{
_cairo_rtree_fini (&cache->rtree);
- if (cache->tex) {
- /* XXX Is this safe? */
- glDeleteTextures (1, &cache->tex);
+ if (cache->pattern.surface) {
+ _cairo_pattern_fini (&cache->pattern.base);
+ cache->pattern.surface = NULL;
}
}
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 724814a9..d7298c9d 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -85,8 +85,7 @@ typedef struct _cairo_gl_surface {
typedef struct cairo_gl_glyph_cache {
cairo_rtree_t rtree;
- GLuint tex;
- unsigned int width, height;
+ cairo_surface_pattern_t pattern;
} cairo_gl_glyph_cache_t;
typedef enum cairo_gl_operand_type {