[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