diff options
author | Benjamin Otte <otte@redhat.com> | 2010-05-18 12:49:59 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-05-20 11:00:50 +0200 |
commit | 208d9f2a7e1f66ff2764c41fe67f65e27279b2ab (patch) | |
tree | 9de265f930faa0f6f40edce0a1c68c19149433e3 | |
parent | 050117996339cfe35add1f2cd44d0e5578d4a981 (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.c | 67 | ||||
-rw-r--r-- | src/cairo-gl-private.h | 3 |
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 { |