[cairo-commit] 5 commits - perf/cairo-perf-chart.c src/cairo-gl-composite.c src/cairo-gl-glyphs.c src/cairo-gl-private.h src/cairo-gl-spans-compositor.c src/cairo-gl-surface.c src/cairo-gl-traps-compositor.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Dec 30 04:55:05 PST 2012


 perf/cairo-perf-chart.c         |  116 ++++++++++++++++++++-
 src/cairo-gl-composite.c        |  220 ++++++++++++++++++++++++++++++++--------
 src/cairo-gl-glyphs.c           |   11 +-
 src/cairo-gl-private.h          |   48 +++++---
 src/cairo-gl-spans-compositor.c |  115 +++++++++++---------
 src/cairo-gl-surface.c          |    2 
 src/cairo-gl-traps-compositor.c |   21 ++-
 7 files changed, 399 insertions(+), 134 deletions(-)

New commits:
commit c29ab389fb2b3b91c895f2df684b0e9af8225d12
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Dec 30 12:32:45 2012 +0000

    gl: Provide a fast emitter for solid spans
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 61dc745..39dec54 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -910,10 +910,8 @@ _cairo_gl_context_emit_rect (cairo_gl_context_t *ctx,
 
 static void
 _cairo_gl_composite_emit_span (cairo_gl_context_t *ctx,
-                               GLfloat x1,
-                               GLfloat y1,
-                               GLfloat x2,
-                               GLfloat y2,
+                               GLfloat x1, GLfloat y1,
+                               GLfloat x2, GLfloat y2,
                                uint8_t alpha)
 {
     _cairo_gl_composite_prepare_buffer (ctx, 6,
@@ -928,10 +926,57 @@ _cairo_gl_composite_emit_span (cairo_gl_context_t *ctx,
     _cairo_gl_composite_emit_alpha_vertex (ctx, x1, y2, alpha);
 }
 
+static void
+_cairo_gl_composite_emit_solid_span (cairo_gl_context_t *ctx,
+				     GLfloat x1, GLfloat y1,
+				     GLfloat x2, GLfloat y2,
+				     uint8_t alpha)
+{
+    GLfloat *v;
+    union fi {
+	float f;
+	GLbyte bytes[4];
+    } fi;
+
+    _cairo_gl_composite_prepare_buffer (ctx, 6,
+					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
+    v = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
+
+    v[15] = v[ 6] = v[0] = x1;
+    v[10] = v[ 4] = v[1] = y1;
+    v[12] = v[ 9] = v[3] = x2;
+    v[16] = v[13] = v[7] = y2;
+
+    fi.bytes[0] = 0;
+    fi.bytes[1] = 0;
+    fi.bytes[2] = 0;
+    fi.bytes[3] = alpha;
+    v[17] =v[14] = v[11] = v[8] = v[5] = v[2] = fi.f;
+
+    ctx->vb_offset += 6*3 * sizeof(GLfloat);
+}
+
 cairo_gl_emit_span_t
 _cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
 {
-    return _cairo_gl_composite_emit_span;
+    if (ctx->operands[CAIRO_GL_TEX_MASK].type != CAIRO_GL_OPERAND_NONE)
+	return _cairo_gl_composite_emit_span;
+
+    switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
+    default:
+    case CAIRO_GL_OPERAND_COUNT:
+        ASSERT_NOT_REACHED;
+    case CAIRO_GL_OPERAND_NONE:
+    case CAIRO_GL_OPERAND_CONSTANT:
+	return _cairo_gl_composite_emit_solid_span;
+
+    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
+    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
+    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
+    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
+    case CAIRO_GL_OPERAND_TEXTURE:
+	return _cairo_gl_composite_emit_span;
+    }
 }
 
 static inline void
commit d3848521c497dbcd3d9ae0fab34fa70c72752e60
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Dec 30 12:32:45 2012 +0000

    gl: Provide a fast emitter for solid glyphs
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 90feb6a..61dc745 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -936,10 +936,8 @@ _cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
 
 static inline void
 _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
-                                       GLfloat x,
-                                       GLfloat y,
-                                       GLfloat glyph_x,
-                                       GLfloat glyph_y)
+				       GLfloat x, GLfloat y,
+				       GLfloat glyph_x, GLfloat glyph_y)
 {
     GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
 
@@ -956,14 +954,10 @@ _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
 
 static void
 _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
-                                GLfloat x1,
-                                GLfloat y1,
-                                GLfloat x2,
-                                GLfloat y2,
-                                GLfloat glyph_x1,
-                                GLfloat glyph_y1,
-                                GLfloat glyph_x2,
-                                GLfloat glyph_y2)
+                                GLfloat x1, GLfloat y1,
+                                GLfloat x2, GLfloat y2,
+                                GLfloat glyph_x1, GLfloat glyph_y1,
+                                GLfloat glyph_x2, GLfloat glyph_y2)
 {
     _cairo_gl_composite_prepare_buffer (ctx, 6,
 					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
@@ -977,10 +971,52 @@ _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
     _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
 }
 
+static void
+_cairo_gl_composite_emit_solid_glyph (cairo_gl_context_t *ctx,
+				      GLfloat x1, GLfloat y1,
+				      GLfloat x2, GLfloat y2,
+				      GLfloat glyph_x1, GLfloat glyph_y1,
+				      GLfloat glyph_x2, GLfloat glyph_y2)
+{
+    GLfloat *v;
+
+    _cairo_gl_composite_prepare_buffer (ctx, 6,
+					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
+
+    v = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
+
+    v[20] = v[ 8] = v[0] = x1;
+    v[13] = v[ 5] = v[1] = y1;
+    v[22] = v[10] = v[2] = glyph_x1;
+    v[15] = v[ 7] = v[3] = glyph_y1;
+
+    v[16] = v[12] = v[4] = x2;
+    v[18] = v[14] = v[6] = glyph_x2;
+
+    v[21] = v[17] = v[ 9] = y2;
+    v[23] = v[19] = v[11] = glyph_y2;
+
+    ctx->vb_offset += 4 * 6 * sizeof (GLfloat);
+}
+
 cairo_gl_emit_glyph_t
 _cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx)
 {
-    return _cairo_gl_composite_emit_glyph;
+    switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
+    default:
+    case CAIRO_GL_OPERAND_COUNT:
+        ASSERT_NOT_REACHED;
+    case CAIRO_GL_OPERAND_NONE:
+    case CAIRO_GL_OPERAND_CONSTANT:
+	return _cairo_gl_composite_emit_solid_glyph;
+
+    case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
+    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
+    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
+    case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
+    case CAIRO_GL_OPERAND_TEXTURE:
+	return _cairo_gl_composite_emit_glyph;
+    }
 }
 
 void
commit 127dd466695dcb05e6178e4ed2471dba1b229d17
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Dec 30 12:21:11 2012 +0000

    gl: Use vfunc for vertex emission
    
    In order to overload the emitters in future to provide specialised
    routines for the common types of operands, begin by switching the
    current users over to a vfunc interface.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index fa62a87..90feb6a 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -828,9 +828,7 @@ _cairo_gl_composite_prepare_buffer (cairo_gl_context_t *ctx,
 
 static inline void
 _cairo_gl_composite_emit_vertex (cairo_gl_context_t *ctx,
-                                 GLfloat x,
-                                 GLfloat y,
-                                 uint8_t alpha)
+				 GLfloat x, GLfloat y)
 {
     GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
 
@@ -840,18 +838,30 @@ _cairo_gl_composite_emit_vertex (cairo_gl_context_t *ctx,
     _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y);
     _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_MASK  ], &vb, x, y);
 
-    if (ctx->spans) {
-	union fi {
-	    float f;
-	    GLbyte bytes[4];
-	} fi;
-
-	fi.bytes[0] = 0;
-	fi.bytes[1] = 0;
-	fi.bytes[2] = 0;
-	fi.bytes[3] = alpha;
-	*vb++ = fi.f;
-    }
+    ctx->vb_offset += ctx->vertex_size;
+}
+
+static inline void
+_cairo_gl_composite_emit_alpha_vertex (cairo_gl_context_t *ctx,
+				       GLfloat x, GLfloat y, uint8_t alpha)
+{
+    GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
+    union fi {
+	float f;
+	GLbyte bytes[4];
+    } fi;
+
+    *vb++ = x;
+    *vb++ = y;
+
+    _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y);
+    _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_MASK  ], &vb, x, y);
+
+    fi.bytes[0] = 0;
+    fi.bytes[1] = 0;
+    fi.bytes[2] = 0;
+    fi.bytes[3] = alpha;
+    *vb++ = fi.f;
 
     ctx->vb_offset += ctx->vertex_size;
 }
@@ -861,14 +871,45 @@ _cairo_gl_composite_emit_point (cairo_gl_context_t	*ctx,
 				const cairo_point_t	*point,
 				uint8_t alpha)
 {
-    _cairo_gl_composite_emit_vertex (ctx,
-				     _cairo_fixed_to_double (point->x),
-				     _cairo_fixed_to_double (point->y),
-				     alpha);
+    _cairo_gl_composite_emit_alpha_vertex (ctx,
+					   _cairo_fixed_to_double (point->x),
+					   _cairo_fixed_to_double (point->y),
+					   alpha);
 }
 
-void
+static void
 _cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
+                               GLfloat x1, GLfloat y1,
+                               GLfloat x2, GLfloat y2)
+{
+    _cairo_gl_composite_prepare_buffer (ctx, 6,
+					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
+
+    _cairo_gl_composite_emit_vertex (ctx, x1, y1);
+    _cairo_gl_composite_emit_vertex (ctx, x2, y1);
+    _cairo_gl_composite_emit_vertex (ctx, x1, y2);
+
+    _cairo_gl_composite_emit_vertex (ctx, x2, y1);
+    _cairo_gl_composite_emit_vertex (ctx, x2, y2);
+    _cairo_gl_composite_emit_vertex (ctx, x1, y2);
+}
+
+cairo_gl_emit_rect_t
+_cairo_gl_context_choose_emit_rect (cairo_gl_context_t *ctx)
+{
+    return _cairo_gl_composite_emit_rect;
+}
+
+void
+_cairo_gl_context_emit_rect (cairo_gl_context_t *ctx,
+			     GLfloat x1, GLfloat y1,
+			     GLfloat x2, GLfloat y2)
+{
+    _cairo_gl_composite_emit_rect (ctx, x1, y1, x2, y2);
+}
+
+static void
+_cairo_gl_composite_emit_span (cairo_gl_context_t *ctx,
                                GLfloat x1,
                                GLfloat y1,
                                GLfloat x2,
@@ -878,13 +919,19 @@ _cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
     _cairo_gl_composite_prepare_buffer (ctx, 6,
 					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
 
-    _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_alpha_vertex (ctx, x1, y1, alpha);
+    _cairo_gl_composite_emit_alpha_vertex (ctx, x2, y1, alpha);
+    _cairo_gl_composite_emit_alpha_vertex (ctx, 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_alpha_vertex (ctx, x2, y1, alpha);
+    _cairo_gl_composite_emit_alpha_vertex (ctx, x2, y2, alpha);
+    _cairo_gl_composite_emit_alpha_vertex (ctx, x1, y2, alpha);
+}
+
+cairo_gl_emit_span_t
+_cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
+{
+    return _cairo_gl_composite_emit_span;
 }
 
 static inline void
@@ -907,7 +954,7 @@ _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
     ctx->vb_offset += ctx->vertex_size;
 }
 
-void
+static void
 _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
                                 GLfloat x1,
                                 GLfloat y1,
@@ -930,6 +977,12 @@ _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
     _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
 }
 
+cairo_gl_emit_glyph_t
+_cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx)
+{
+    return _cairo_gl_composite_emit_glyph;
+}
+
 void
 _cairo_gl_composite_fini (cairo_gl_composite_t *setup)
 {
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 431f5ee..03aeb67 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -231,6 +231,7 @@ render_glyphs (cairo_gl_surface_t *dst,
     cairo_format_t last_format = CAIRO_FORMAT_INVALID;
     cairo_gl_glyph_cache_t *cache = NULL;
     cairo_gl_context_t *ctx;
+    cairo_gl_emit_glyph_t emit;
     cairo_gl_composite_t setup;
     cairo_int_status_t status;
     int i = 0;
@@ -294,6 +295,8 @@ render_glyphs (cairo_gl_surface_t *dst,
             status = _cairo_gl_context_release (ctx, status);
 	    if (unlikely (status))
 		goto FINISH;
+
+	    emit = _cairo_gl_context_choose_emit_glyph (ctx);
 	}
 
 	if (scaled_glyph->dev_private_key != cache) {
@@ -329,10 +332,10 @@ render_glyphs (cairo_gl_surface_t *dst,
 	y2 = y1 + scaled_glyph->surface->height;
 
 	glyph = _cairo_gl_glyph_cache_lock (cache, scaled_glyph);
-	_cairo_gl_composite_emit_glyph (ctx,
-					x1, y1, x2, y2,
-                                        glyph->p1.x, glyph->p1.y,
-                                        glyph->p2.x, glyph->p2.y);
+	emit (ctx,
+	      x1, y1, x2, y2,
+	      glyph->p1.x, glyph->p1.y,
+	      glyph->p2.x, glyph->p2.y);
     }
 
     status = CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 57242a4..258fa78 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -218,6 +218,21 @@ typedef enum cairo_gl_primitive_type {
     CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS
 } cairo_gl_primitive_type_t;
 
+typedef void (*cairo_gl_emit_rect_t) (cairo_gl_context_t *ctx,
+				      GLfloat x1, GLfloat y1,
+				      GLfloat x2, GLfloat y2);
+
+typedef void (*cairo_gl_emit_span_t) (cairo_gl_context_t *ctx,
+				      GLfloat x1, GLfloat y1,
+				      GLfloat x2, GLfloat y2,
+				      uint8_t alpha);
+
+typedef void (*cairo_gl_emit_glyph_t) (cairo_gl_context_t *ctx,
+				       GLfloat x1, GLfloat y1,
+				       GLfloat x2, GLfloat y2,
+				       GLfloat glyph_x1, GLfloat glyph_y1,
+				       GLfloat glyph_x2, GLfloat glyph_y2);
+
 #define cairo_gl_var_type_hash(src,mask,spans,dest) ((spans) << 3) | ((mask) << 2 | (src << 1) | (dest))
 #define CAIRO_GL_VAR_TYPE_MAX ((CAIRO_GL_VAR_TEXCOORDS << 3) | (CAIRO_GL_VAR_TEXCOORDS << 2) | (CAIRO_GL_VAR_TEXCOORDS << 1) | CAIRO_GL_VAR_TEXCOORDS)
 
@@ -477,6 +492,20 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
 				   cairo_gl_surface_t *surface,
 				   cairo_bool_t multisampling);
 
+cairo_private cairo_gl_emit_rect_t
+_cairo_gl_context_choose_emit_rect (cairo_gl_context_t *ctx);
+
+cairo_private void
+_cairo_gl_context_emit_rect (cairo_gl_context_t *ctx,
+			     GLfloat x1, GLfloat y1,
+			     GLfloat x2, GLfloat y2);
+
+cairo_private cairo_gl_emit_span_t
+_cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx);
+
+cairo_private cairo_gl_emit_glyph_t
+_cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx);
+
 cairo_private void
 _cairo_gl_context_activate (cairo_gl_context_t *ctx,
                             cairo_gl_tex_t      tex_unit);
@@ -540,25 +569,6 @@ _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
                            cairo_gl_context_t **ctx);
 
 cairo_private void
-_cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
-                               GLfloat x1,
-                               GLfloat y1,
-                               GLfloat x2,
-                               GLfloat y2,
-                               uint8_t alpha);
-
-cairo_private void
-_cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
-                                GLfloat x1,
-                                GLfloat y1,
-                                GLfloat x2,
-                                GLfloat y2,
-                                GLfloat glyph_x1,
-                                GLfloat glyph_y1,
-                                GLfloat glyph_x2,
-                                GLfloat glyph_y2);
-
-cairo_private void
 _cairo_gl_composite_flush (cairo_gl_context_t *ctx);
 
 cairo_private cairo_int_status_t
diff --git a/src/cairo-gl-spans-compositor.c b/src/cairo-gl-spans-compositor.c
index 62da1eb..98efd46 100644
--- a/src/cairo-gl-spans-compositor.c
+++ b/src/cairo-gl-spans-compositor.c
@@ -57,6 +57,8 @@ typedef struct _cairo_gl_span_renderer {
     cairo_gl_composite_t setup;
     double opacity;
 
+    cairo_gl_emit_span_t emit;
+
     int xmin, xmax;
     int ymin, ymax;
 
@@ -70,16 +72,17 @@ _cairo_gl_bounded_opaque_spans (void *abstract_renderer,
 				unsigned num_spans)
 {
     cairo_gl_span_renderer_t *r = abstract_renderer;
+    cairo_gl_emit_span_t emit = r->emit;
 
     if (num_spans == 0)
 	return CAIRO_STATUS_SUCCESS;
 
     do {
 	if (spans[0].coverage) {
-            _cairo_gl_composite_emit_rect (r->ctx,
-                                           spans[0].x, y,
-                                           spans[1].x, y + height,
-                                           spans[0].coverage);
+	    emit (r->ctx,
+		  spans[0].x, y,
+		  spans[1].x, y + height,
+		  spans[0].coverage);
 	}
 
 	spans++;
@@ -95,16 +98,17 @@ _cairo_gl_bounded_spans (void *abstract_renderer,
 			 unsigned num_spans)
 {
     cairo_gl_span_renderer_t *r = abstract_renderer;
+    cairo_gl_emit_span_t emit = r->emit;
 
     if (num_spans == 0)
 	return CAIRO_STATUS_SUCCESS;
 
     do {
 	if (spans[0].coverage) {
-            _cairo_gl_composite_emit_rect (r->ctx,
-                                           spans[0].x, y,
-                                           spans[1].x, y + height,
-                                           r->opacity * spans[0].coverage);
+	    emit (r->ctx,
+		  spans[0].x, y,
+		  spans[1].x, y + height,
+		  r->opacity * spans[0].coverage);
 	}
 
 	spans++;
@@ -120,40 +124,41 @@ _cairo_gl_unbounded_spans (void *abstract_renderer,
 			   unsigned num_spans)
 {
     cairo_gl_span_renderer_t *r = abstract_renderer;
+    cairo_gl_emit_span_t emit = r->emit;
 
     if (y > r->ymin) {
-        _cairo_gl_composite_emit_rect (r->ctx,
-                                       r->xmin, r->ymin,
-                                       r->xmax, y,
-                                       0);
+	emit (r->ctx,
+	      r->xmin, r->ymin,
+	      r->xmax, y,
+	      0);
     }
 
     if (num_spans == 0) {
-        _cairo_gl_composite_emit_rect (r->ctx,
-                                       r->xmin, y,
-                                       r->xmax, y + height,
-                                       0);
+	emit (r->ctx,
+	      r->xmin, y,
+	      r->xmax, y + height,
+	      0);
     } else {
         if (spans[0].x != r->xmin) {
-            _cairo_gl_composite_emit_rect (r->ctx,
-                                           r->xmin, y,
-                                           spans[0].x,     y + height,
-                                           0);
+	    emit (r->ctx,
+		  r->xmin, y,
+		  spans[0].x,     y + height,
+		  0);
         }
 
         do {
-            _cairo_gl_composite_emit_rect (r->ctx,
-                                           spans[0].x, y,
-                                           spans[1].x, y + height,
-                                           r->opacity * spans[0].coverage);
+	    emit (r->ctx,
+		  spans[0].x, y,
+		  spans[1].x, y + height,
+		  r->opacity * spans[0].coverage);
             spans++;
         } while (--num_spans > 1);
 
         if (spans[0].x != r->xmax) {
-            _cairo_gl_composite_emit_rect (r->ctx,
-                                           spans[0].x,     y,
-                                           r->xmax, y + height,
-                                           0);
+	    emit (r->ctx,
+		  spans[0].x,     y,
+		  r->xmax, y + height,
+		  0);
         }
     }
 
@@ -169,40 +174,41 @@ _cairo_gl_clipped_spans (void *abstract_renderer,
 			   unsigned num_spans)
 {
     cairo_gl_span_renderer_t *r = abstract_renderer;
+    cairo_gl_emit_span_t emit = r->emit;
 
     if (y > r->ymin) {
-        _cairo_gl_composite_emit_rect (r->ctx,
-                                       r->xmin, r->ymin,
-                                       r->xmax, y,
-                                       0);
+	emit (r->ctx,
+	      r->xmin, r->ymin,
+	      r->xmax, y,
+	      0);
     }
 
     if (num_spans == 0) {
-        _cairo_gl_composite_emit_rect (r->ctx,
-                                       r->xmin, y,
-                                       r->xmax, y + height,
-                                       0);
+	emit (r->ctx,
+	      r->xmin, y,
+	      r->xmax, y + height,
+	      0);
     } else {
         if (spans[0].x != r->xmin) {
-            _cairo_gl_composite_emit_rect (r->ctx,
-                                           r->xmin, y,
-                                           spans[0].x,     y + height,
-                                           0);
+	    emit (r->ctx,
+		  r->xmin, y,
+		  spans[0].x,     y + height,
+		  0);
         }
 
         do {
-            _cairo_gl_composite_emit_rect (r->ctx,
-                                           spans[0].x, y,
-                                           spans[1].x, y + height,
-                                           r->opacity * spans[0].coverage);
+	    emit (r->ctx,
+		  spans[0].x, y,
+		  spans[1].x, y + height,
+		  r->opacity * spans[0].coverage);
             spans++;
         } while (--num_spans > 1);
 
         if (spans[0].x != r->xmax) {
-            _cairo_gl_composite_emit_rect (r->ctx,
-                                           spans[0].x,     y,
-                                           r->xmax, y + height,
-                                           0);
+	    emit (r->ctx,
+		  spans[0].x,     y,
+		  r->xmax, y + height,
+		  0);
         }
     }
 
@@ -214,12 +220,13 @@ static cairo_status_t
 _cairo_gl_finish_unbounded_spans (void *abstract_renderer)
 {
     cairo_gl_span_renderer_t *r = abstract_renderer;
+    cairo_gl_emit_span_t emit = r->emit;
 
     if (r->ymax > r->ymin) {
-        _cairo_gl_composite_emit_rect (r->ctx,
-                                       r->xmin, r->ymin,
-                                       r->xmax, r->ymax,
-                                       0);
+	emit (r->ctx,
+	      r->xmin, r->ymin,
+	      r->xmax, r->ymax,
+	      0);
     }
 
     return _cairo_gl_context_release (r->ctx, CAIRO_STATUS_SUCCESS);
@@ -238,6 +245,7 @@ emit_aligned_boxes (cairo_gl_context_t *ctx,
 		    const cairo_boxes_t *boxes)
 {
     const struct _cairo_boxes_chunk *chunk;
+    cairo_gl_emit_rect_t emit = _cairo_gl_context_choose_emit_rect (ctx);
     int i;
 
     TRACE ((stderr, "%s: num_boxes=%d\n", __FUNCTION__, boxes->num_boxes));
@@ -247,7 +255,7 @@ emit_aligned_boxes (cairo_gl_context_t *ctx,
 	    int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
 	    int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
 	    int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
-	    _cairo_gl_composite_emit_rect (ctx, x1, y1, x2, y2, 255);
+	    emit (ctx, x1, y1, x2, y2);
 	}
     }
 }
@@ -468,6 +476,7 @@ _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t	*_r,
     if (unlikely (status))
         goto FAIL;
 
+    r->emit = _cairo_gl_context_choose_emit_span (r->ctx);
     if (composite->is_bounded) {
 	if (r->opacity == 1.)
 	    r->base.render_rows = _cairo_gl_bounded_opaque_spans;
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 83efa17..4b74cf0 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -774,7 +774,7 @@ _cairo_gl_surface_fill_alpha_channel (cairo_gl_surface_t *dst,
     if (unlikely (status))
         goto CLEANUP;
 
-    _cairo_gl_composite_emit_rect (ctx, x, y, x + width, y + height, 0);
+    _cairo_gl_context_emit_rect (ctx, x, y, x + width, y + height);
 
     status = _cairo_gl_context_release (ctx, status);
 
diff --git a/src/cairo-gl-traps-compositor.c b/src/cairo-gl-traps-compositor.c
index 4bae0d1..b6c2333 100644
--- a/src/cairo-gl-traps-compositor.c
+++ b/src/cairo-gl-traps-compositor.c
@@ -110,6 +110,7 @@ emit_aligned_boxes (cairo_gl_context_t *ctx,
 		    const cairo_boxes_t *boxes)
 {
     const struct _cairo_boxes_chunk *chunk;
+    cairo_gl_emit_rect_t emit = _cairo_gl_context_choose_emit_rect (ctx);
     int i;
 
     for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
@@ -118,7 +119,7 @@ emit_aligned_boxes (cairo_gl_context_t *ctx,
 	    int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
 	    int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
 	    int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
-	    _cairo_gl_composite_emit_rect (ctx, x1, y1, x2, y2, 0);
+	    emit (ctx, x1, y1, x2, y2);
 	}
     }
 }
@@ -228,7 +229,7 @@ composite (void			*_dst,
         goto FAIL;
 
     /* XXX clip */
-    _cairo_gl_composite_emit_rect (ctx, dst_x, dst_y, dst_x+width, dst_y+height, 0);
+    _cairo_gl_context_emit_rect (ctx, dst_x, dst_y, dst_x+width, dst_y+height);
     status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
 
 FAIL:
@@ -403,10 +404,10 @@ composite_traps (void			*_dst,
         goto FAIL;
 
     /* XXX clip */
-    _cairo_gl_composite_emit_rect (ctx,
-				   extents->x-dst_x, extents->y-dst_y,
-				   extents->x-dst_x+extents->width,
-				   extents->y-dst_y+extents->height, 0);
+    _cairo_gl_context_emit_rect (ctx,
+				 extents->x-dst_x, extents->y-dst_y,
+				 extents->x-dst_x+extents->width,
+				 extents->y-dst_y+extents->height);
     status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
 
 FAIL:
@@ -499,10 +500,10 @@ composite_tristrip (void		*_dst,
         goto FAIL;
 
     /* XXX clip */
-    _cairo_gl_composite_emit_rect (ctx,
-				   dst_x, dst_y,
-				   dst_x+extents->width,
-				   dst_y+extents->height, 0);
+    _cairo_gl_context_emit_rect (ctx,
+				 dst_x, dst_y,
+				 dst_x+extents->width,
+				 dst_y+extents->height);
     status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
 
 FAIL:
commit 9558cb62c6a3ed59a53f00f740a261251b9b64b2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 29 18:30:48 2012 +0000

    perf/chart: Contract the default output filenames
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/perf/cairo-perf-chart.c b/perf/cairo-perf-chart.c
index 67bedd4..5a41d02 100644
--- a/perf/cairo-perf-chart.c
+++ b/perf/cairo-perf-chart.c
@@ -1065,9 +1065,7 @@ main (int	  argc,
 	add_legend (&chart);
 
 	cairo_surface_write_to_png (cairo_get_target (chart.cr),
-				    chart.relative ?
-				    "cairo-perf-chart-relative.png" :
-				    "cairo-perf-chart-absolute.png");
+				    chart.relative ? "relative.png" : "absolute.png");
 	cairo_destroy (chart.cr);
     }
 
commit fbd4864995e261a4cfc5e53273b53ce8a22d72db
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 29 18:30:48 2012 +0000

    perf/chart: Show the geometric average as an extra column
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/perf/cairo-perf-chart.c b/perf/cairo-perf-chart.c
index a993ce8..67bedd4 100644
--- a/perf/cairo-perf-chart.c
+++ b/perf/cairo-perf-chart.c
@@ -45,6 +45,7 @@ struct chart {
     int width, height;
     int num_tests, num_reports;
     double min_value, max_value;
+    double *average;
 
     cairo_bool_t use_html;
     cairo_bool_t relative;
@@ -142,12 +143,20 @@ find_ranges (struct chart *chart)
     int num_tests = 0;
     double slow_sum = 0, fast_sum = 0, sum;
     int slow_count = 0, fast_count = 0;
+    int *count;
     int i;
 
     num_values = 0;
     size_values = 64;
     values = xmalloc (size_values * sizeof (double));
 
+    chart->average = xmalloc(chart->num_reports * sizeof(double));
+    count = xmalloc(chart->num_reports * sizeof(int));
+    for (i = 0; i < chart->num_reports; i++) {
+	chart->average[i] = 0;
+	count[i] = 0;
+    }
+
     tests = xmalloc (chart->num_reports * sizeof (test_report_t *));
     for (i = 0; i < chart->num_reports; i++)
 	tests[i] = chart->reports[i].tests;
@@ -202,6 +211,9 @@ find_ranges (struct chart *chart)
 		if (test_time == 0)
 		    test_time = report_time;
 
+		chart->average[i] += report_time / test_time;
+		count[i]++;
+
 		if (chart->relative) {
 		    if (test_time != report_time) {
 			double v = to_factor (test_time / report_time);
@@ -232,14 +244,22 @@ find_ranges (struct chart *chart)
 	}
     }
 
+    for (i = 0; i < chart->num_reports; i++) {
+	if (count[i])
+	    chart->average[i] = count[i] / chart->average[i];
+	else
+	    chart->average[i] = 1.;
+    }
+
     if (chart->relative)
 	trim_outliers (values, num_values, &min, &max);
     chart->min_value = min;
     chart->max_value = max;
-    chart->num_tests = num_tests;
+    chart->num_tests = num_tests + !!chart->relative;
 
     free (values);
     free (tests);
+    free (count);
 
     printf ("%d: slow[%d] average: %f, fast[%d] average: %f, %f\n",
 	    num_values, slow_count, slow_sum / slow_count, fast_count, fast_sum / fast_count, sum / num_values);
@@ -451,6 +471,91 @@ add_chart (struct chart *c,
 }
 
 static void
+add_average (struct chart *c,
+	     int		 test,
+	     int		 report,
+	     double	 value)
+{
+    double dx, dy, x;
+    cairo_text_extents_t extents;
+    char buf[80];
+    double y;
+
+    if (fabs (value) < 0.1)
+	return;
+
+    dy = (c->height/2. - PAD) / MAX (-c->min_value, c->max_value);
+    /* the first report is always skipped, as it is used as the baseline */
+    dx = c->width / (double) (c->num_tests * c->num_reports);
+    x = dx * (c->num_reports * test + report - .5);
+
+    cairo_rectangle (c->cr,
+		     floor (x), c->height / 2.,
+		     floor (x + dx) - floor (x),
+		     ceil (-dy*value - c->height/2.) + c->height/2.);
+    if (dx < 5) {
+	set_report_color (c, report);
+	cairo_fill (c->cr);
+    } else {
+	set_report_gradient (c, report,
+			     floor (x), c->height / 2.,
+			     floor (x + dx) - floor (x),
+			     ceil (-dy*value - c->height/2.) + c->height/2.);
+
+	cairo_fill_preserve (c->cr);
+	cairo_save (c->cr);
+	cairo_clip_preserve (c->cr);
+	set_report_color (c, report);
+	cairo_stroke (c->cr);
+	cairo_restore (c->cr);
+    }
+
+    /* Skip the label if the difference between the two is less than 0.1% */
+    if (fabs (value) < 0.1)
+	return;
+
+    cairo_save (c->cr);
+    cairo_set_font_size (c->cr, dx - 2);
+
+    if (value < 0) {
+	sprintf (buf, "%.1f", -value/100 + 1);
+    } else {
+	sprintf (buf, "%.1f", value/100 + 1);
+    }
+    cairo_text_extents (c->cr, buf, &extents);
+
+    /* will it be clipped? */
+    y = -dy * value;
+    if (y < -c->height/2) {
+	y = -c->height/2;
+    } else if (y > c->height/2) {
+	y = c->height/2;
+    }
+
+    if (y < 0) {
+	if (y > -extents.width - 6)
+	    y -= extents.width + 6;
+    } else {
+	if (y < extents.width + 6)
+	    y += extents.width + 6;
+    }
+
+    cairo_translate (c->cr,
+		     floor (x) + (floor (x + dx) - floor (x))/2,
+		     floor (y) + c->height/2.);
+    cairo_rotate (c->cr, -M_PI/2);
+    if (y < 0) {
+	cairo_move_to (c->cr, -extents.x_bearing -extents.width - 4, -extents.y_bearing/2);
+    } else {
+	cairo_move_to (c->cr, 2, -extents.y_bearing/2);
+    }
+
+    cairo_set_source_rgb (c->cr, .95, .95, .95);
+    cairo_show_text (c->cr, buf);
+    cairo_restore (c->cr);
+}
+
+static void
 add_label (struct chart *c,
 	   int		 test,
 	   const char	*label)
@@ -825,6 +930,11 @@ cairo_perf_reports_compare (struct chart *chart,
 
 	num_test++;
     }
+    if (chart->relative) {
+	add_label (chart, num_test, "(geometric mean)");
+	for (i = 0; i < chart->num_reports; i++)
+	    add_average (chart, num_test, i, to_factor (chart->average[i]));
+    }
     free (tests);
 
     if (print) {


More information about the cairo-commit mailing list