[cairo] [PATCH 2/2] gl: Remove GL fixed-function matrix usage.
Eric Anholt
eric at anholt.net
Mon Jan 31 20:20:00 PST 2011
No significant performance difference (though a simpler diff showed a
2% hit)
[ 0] after firefox-talos-gfx 66.689 66.913 0.41% 3/3
[ 0] before firefox-talos-gfx 66.150 66.491 0.84% 3/3
---
src/cairo-gl-composite.c | 46 ++++++++++++++++++++++++++++++----------------
src/cairo-gl-device.c | 25 ++++++++++++++++---------
src/cairo-gl-private.h | 5 +++++
src/cairo-gl-shaders.c | 4 +++-
4 files changed, 54 insertions(+), 26 deletions(-)
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index a32e00d..ef31165 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -1024,14 +1024,16 @@ _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
static inline void
_cairo_gl_composite_emit_vertex (cairo_gl_context_t *ctx,
+ GLfloat dest_x,
+ GLfloat dest_y,
GLfloat x,
GLfloat y,
uint8_t alpha)
{
GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
- *vb++ = x;
- *vb++ = y;
+ *vb++ = dest_x;
+ *vb++ = dest_y;
_cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y, alpha);
_cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_MASK ], &vb, x, y, alpha);
@@ -1047,19 +1049,26 @@ _cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
GLfloat y2,
uint8_t alpha)
{
+ double dest_x1 = x1, dest_y1 = y1, dest_x2 = x2, dest_y2 = y2;
+
+ cairo_matrix_transform_point (&ctx->dest_matrix, &dest_x1, &dest_y1);
+ cairo_matrix_transform_point (&ctx->dest_matrix, &dest_x2, &dest_y2);
+
_cairo_gl_composite_prepare_buffer (ctx, 6);
- _cairo_gl_composite_emit_vertex (ctx, x1, y1, alpha);
- _cairo_gl_composite_emit_vertex (ctx, x2, y1, alpha);
- _cairo_gl_composite_emit_vertex (ctx, x1, y2, alpha);
+ _cairo_gl_composite_emit_vertex (ctx, dest_x1, dest_y1, x1, y1, alpha);
+ _cairo_gl_composite_emit_vertex (ctx, dest_x2, dest_y1, x2, y1, alpha);
+ _cairo_gl_composite_emit_vertex (ctx, dest_x1, dest_y2, x1, y2, alpha);
- _cairo_gl_composite_emit_vertex (ctx, x2, y1, alpha);
- _cairo_gl_composite_emit_vertex (ctx, x2, y2, alpha);
- _cairo_gl_composite_emit_vertex (ctx, x1, y2, alpha);
+ _cairo_gl_composite_emit_vertex (ctx, dest_x2, dest_y1, x2, y1, alpha);
+ _cairo_gl_composite_emit_vertex (ctx, dest_x2, dest_y2, x2, y2, alpha);
+ _cairo_gl_composite_emit_vertex (ctx, dest_x1, dest_y2, x1, y2, alpha);
}
static inline void
_cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
+ GLfloat dest_x,
+ GLfloat dest_y,
GLfloat x,
GLfloat y,
GLfloat glyph_x,
@@ -1067,8 +1076,8 @@ _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
{
GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
- *vb++ = x;
- *vb++ = y;
+ *vb++ = dest_x;
+ *vb++ = dest_y;
_cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y, 0);
@@ -1089,15 +1098,20 @@ _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
GLfloat glyph_x2,
GLfloat glyph_y2)
{
+ double dest_x1 = x1, dest_y1 = y1, dest_x2 = x2, dest_y2 = y2;
+
+ cairo_matrix_transform_point (&ctx->dest_matrix, &dest_x1, &dest_y1);
+ cairo_matrix_transform_point (&ctx->dest_matrix, &dest_x2, &dest_y2);
+
_cairo_gl_composite_prepare_buffer (ctx, 6);
- _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y1, glyph_x1, glyph_y1);
- _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1);
- _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
+ _cairo_gl_composite_emit_glyph_vertex (ctx, dest_x1, dest_y1, x1, y1, glyph_x1, glyph_y1);
+ _cairo_gl_composite_emit_glyph_vertex (ctx, dest_x2, dest_y1, x2, y1, glyph_x2, glyph_y1);
+ _cairo_gl_composite_emit_glyph_vertex (ctx, dest_x1, dest_y2, x1, y2, glyph_x1, glyph_y2);
- _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1);
- _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y2, glyph_x2, glyph_y2);
- _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
+ _cairo_gl_composite_emit_glyph_vertex (ctx, dest_x2, dest_y1, x2, y1, glyph_x2, glyph_y1);
+ _cairo_gl_composite_emit_glyph_vertex (ctx, dest_x2, dest_y2, x2, y2, glyph_x2, glyph_y2);
+ _cairo_gl_composite_emit_glyph_vertex (ctx, dest_x1, dest_y2, x1, y2, glyph_x1, glyph_y2);
}
void
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index 3d3cf0e..abea630 100644
--- a/src/cairo-gl-device.c
+++ b/src/cairo-gl-device.c
@@ -295,13 +295,20 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
glViewport (0, 0, surface->width, surface->height);
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
- if (_cairo_gl_surface_is_texture (surface))
- glOrtho (0, surface->width, 0, surface->height, -1.0, 1.0);
- else
- glOrtho (0, surface->width, surface->height, 0, -1.0, 1.0);
-
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity ();
+ ctx->dest_matrix.xx = 2.0 / surface->width;
+ ctx->dest_matrix.yy = 2.0 / surface->height;
+ ctx->dest_matrix.xy = 0.0;
+ ctx->dest_matrix.yx = 0.0;
+ ctx->dest_matrix.x0 = -1.0;
+ ctx->dest_matrix.y0 = -1.0;
+
+ /* When rendering to windows, flip Y -- cairo's origin is upper
+ * left, while GL's is bottom left. For FBOs, we don't bother
+ * with this (meaning that (0, 0) of the resulting texture
+ * attached to the FBO is cairo's upper left).
+ */
+ if (!_cairo_gl_surface_is_texture(surface)) {
+ ctx->dest_matrix.y0 = 1.0;
+ ctx->dest_matrix.yy = -ctx->dest_matrix.yy;
+ }
}
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 6cea8c0..3aecb0d 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -258,6 +258,11 @@ struct _cairo_gl_context {
cairo_bool_t has_mesa_pack_invert;
cairo_gl_dispatch_t dispatch;
+ /* Current transformation from cairo coordinates to GL clip space
+ * ((0,0),(width, height) -> ((-1, 1),(1, -1)).
+ */
+ cairo_matrix_t dest_matrix;
+
void (*acquire) (void *ctx);
void (*release) (void *ctx);
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index a39883d..7e02d10 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -501,7 +501,9 @@ cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
_cairo_output_stream_printf (stream,
"void main()\n"
"{\n"
- " gl_Position = ftransform();\n");
+ " gl_Position.xy = gl_Vertex.xy;\n"
+ " gl_Position.zw = vec2(0.0, 1.0);\n"
+ );
cairo_gl_shader_emit_vertex (stream, src, CAIRO_GL_TEX_SOURCE);
cairo_gl_shader_emit_vertex (stream, mask, CAIRO_GL_TEX_MASK);
--
1.7.2.3
More information about the cairo
mailing list