[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