[cairo-commit] 2 commits - src/cairo-gl-glyphs.c src/cairo-gl-surface.c

Eric Anholt anholt at kemper.freedesktop.org
Tue Feb 16 14:03:34 PST 2010


 src/cairo-gl-glyphs.c  |   16 +++-
 src/cairo-gl-surface.c |  157 ++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 134 insertions(+), 39 deletions(-)

New commits:
commit 89bdc2f8d55d951e15b77e6737c57b208d984b0a
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 4 23:17:59 2010 -0800

    gl: Implement draw_image for window targets.
    
    Creates a texture and draws with it instead of doing TexSubImage.
    Open question is whether this wouldn't be better in general.  Fixes
    several failures with ARB_texture_rectangle path due to fallbacks to
    window drawing.

diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index f86a4fd..84c8d88 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -683,6 +683,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
     cairo_image_surface_t *clone = NULL;
     cairo_gl_context_t *ctx = (cairo_gl_context_t *) dst->base.device;
     int cpp;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     if (! _cairo_gl_get_image_format_and_type (src->pixman_format,
 					       &internal_format,
@@ -709,45 +710,135 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
 
     cpp = PIXMAN_FORMAT_BPP (src->pixman_format) / 8;
 
-    glBindTexture (ctx->tex_target, dst->tex);
-    glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
     glPixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp);
-    glTexSubImage2D (ctx->tex_target, 0,
-	             dst_x, dst_y, width, height,
-		     format, GL_UNSIGNED_BYTE,
-		     src->data + src_y * src->stride + src_x * cpp);
-    glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+    if (dst->fb) {
+	glBindTexture (ctx->tex_target, dst->tex);
+	glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexSubImage2D (ctx->tex_target, 0,
+			 dst_x, dst_y, width, height,
+			 format, GL_UNSIGNED_BYTE,
+			 src->data + src_y * src->stride + src_x * cpp);
+
+	/* If we just treated some rgb-only data as rgba, then we have to
+	 * go back and fix up the alpha channel where we filled in this
+	 * texture data.
+	 */
+	if (!has_alpha) {
+	    cairo_rectangle_int_t rect;
+	    cairo_color_t color;
+
+	    rect.x = dst_x;
+	    rect.y = dst_y;
+	    rect.width = width;
+	    rect.height = height;
+
+	    color.red = 0.0;
+	    color.green = 0.0;
+	    color.blue = 0.0;
+	    color.alpha = 1.0;
+
+	    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
+	    _cairo_gl_surface_fill_rectangles (dst,
+					       CAIRO_OPERATOR_SOURCE,
+					       &color,
+					       &rect, 1);
+	    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+	}
+    } else {
+	GLuint tex;
+	float vertices[8], texcoords[8];
+	cairo_gl_context_t *ctx;
+
+	status = _cairo_gl_context_acquire (dst->base.device, &ctx);
+	if (unlikely (status))
+	    goto fail;
+
+	if (ctx->using_glsl) {
+	    cairo_gl_shader_program_t *program;
+
+	    status = _cairo_gl_get_program (ctx,
+					    CAIRO_GL_SHADER_SOURCE_TEXTURE,
+					    CAIRO_GL_SHADER_MASK_NONE,
+					    CAIRO_GL_SHADER_IN_NORMAL,
+					    &program);
+	    if (_cairo_status_is_error (status)) {
+		_cairo_gl_context_release (ctx);
+		goto fail;
+	    }
 
-    cairo_surface_destroy (&clone->base);
+	    _cairo_gl_use_program (program);
+	} else {
+	    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+	}
 
-    /* If we just treated some rgb-only data as rgba, then we have to
-     * go back and fix up the alpha channel where we filled in this
-     * texture data.
-     */
-    if (!has_alpha) {
-	cairo_rectangle_int_t rect;
-	cairo_color_t color;
-
-	rect.x = dst_x;
-	rect.y = dst_y;
-	rect.width = width;
-	rect.height = height;
-
-	color.red = 0.0;
-	color.green = 0.0;
-	color.blue = 0.0;
-	color.alpha = 1.0;
-
-	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
-	_cairo_gl_surface_fill_rectangles (dst,
-					   CAIRO_OPERATOR_SOURCE,
-					   &color,
-					   &rect, 1);
-	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+	_cairo_gl_set_destination (dst);
+
+	glGenTextures (1, &tex);
+	glActiveTexture (GL_TEXTURE0);
+	glBindTexture (ctx->tex_target, tex);
+	glTexImage2D (ctx->tex_target, 0, internal_format, width, height, 0,
+		      format, type, src->data + src_y * src->stride + src_x * cpp);
+
+	glEnable (ctx->tex_target);
+	glDisable (GL_BLEND);
+
+	vertices[0] = dst_x;
+	vertices[1] = dst_y;
+	vertices[2] = dst_x + width;
+	vertices[3] = dst_y;
+	vertices[4] = dst_x + width;
+	vertices[5] = dst_y + height;
+	vertices[6] = dst_x;
+	vertices[7] = dst_y + height;
+
+	if (ctx->tex_target != GL_TEXTURE_RECTANGLE_EXT) {
+	    texcoords[0] = 0;
+	    texcoords[1] = 0;
+	    texcoords[2] = 1;
+	    texcoords[3] = 0;
+	    texcoords[4] = 1;
+	    texcoords[5] = 1;
+	    texcoords[6] = 0;
+	    texcoords[7] = 1;
+	} else {
+	    texcoords[0] = 0;
+	    texcoords[1] = 0;
+	    texcoords[2] = width;
+	    texcoords[3] = 0;
+	    texcoords[4] = width;
+	    texcoords[5] = height;
+	    texcoords[6] = 0;
+	    texcoords[7] = height;
+	}
+
+	glVertexPointer (2, GL_FLOAT, sizeof (float) * 2, vertices);
+	glEnableClientState (GL_VERTEX_ARRAY);
+
+	glClientActiveTexture (GL_TEXTURE0);
+	glTexCoordPointer (2, GL_FLOAT, sizeof (float) * 2, texcoords);
+	glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+
+	glDrawArrays (GL_QUADS, 0, 4);
+
+	glDisableClientState (GL_COLOR_ARRAY);
+	glDisableClientState (GL_VERTEX_ARRAY);
+	glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+
+	if (ctx->using_glsl)
+	    _cairo_gl_use_program (NULL);
+	glDeleteTextures (1, &tex);
+	glDisable (ctx->tex_target);
+
+	_cairo_gl_context_release (ctx);
     }
 
+fail:
+    glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+
+    cairo_surface_destroy (&clone->base);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
commit fcd29473ff71b74bf541199293a966df2232fd63
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 16 13:47:41 2010 -0800

    gl: Fix glyphs texture coordinates for ARB_texture_rectangle.
    
    Fixes most of the text testcases to match the
    ARB_texture_non_power_of_two results.

diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index dbd24c5..8ea04ef 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -125,12 +125,16 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
     glyph_private->cache = cache;
 
     /* compute tex coords */
-    glyph_private->p1.x = node->x / (double) cache->width;
-    glyph_private->p1.y = node->y / (double) cache->height;
-    glyph_private->p2.x =
-	(node->x + glyph_surface->width) / (double) cache->width;
-    glyph_private->p2.y =
-	(node->y + glyph_surface->height) / (double) cache->height;
+    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 (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;
+    }
 
     cairo_surface_destroy (&clone->base);
 


More information about the cairo-commit mailing list