[cairo-commit] 7 commits - perf/cairo-perf-chart.c perf/.gitignore src/cairo-surface-subsurface.c src/cairo-xcb-surface.c src/cairo-xlib-core-compositor.c test/arc-direction.c test/Makefile.sources test/reference

Chris Wilson ickle at kemper.freedesktop.org
Wed Jan 11 04:45:00 PST 2012


 perf/.gitignore                            |    1 
 perf/cairo-perf-chart.c                    |   84 ++++++++++++++++++-----
 src/cairo-surface-subsurface.c             |    8 ++
 src/cairo-xcb-surface.c                    |    7 +
 src/cairo-xlib-core-compositor.c           |   16 ++++
 test/Makefile.sources                      |    1 
 test/arc-direction.c                       |  105 +++++++++++++++++++++++++++++
 test/reference/arc-direction.base.ref.png  |binary
 test/reference/arc-direction.ps.ref.png    |binary
 test/reference/arc-direction.ref.png       |binary
 test/reference/arc-direction.traps.ref.png |binary
 test/reference/arc-direction.xlib.ref.png  |binary
 12 files changed, 204 insertions(+), 18 deletions(-)

New commits:
commit dc80e8328ce8be6414d6483a51bce074f6e740b0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 11 12:42:53 2012 +0000

    subsurface: Add guards for creating similar surface
    
    If the target backend doesn't provide the entry points, just return NULL
    (unsupported).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c
index 09f49d0..b2f7e0a 100644
--- a/src/cairo-surface-subsurface.c
+++ b/src/cairo-surface-subsurface.c
@@ -61,6 +61,10 @@ _cairo_surface_subsurface_create_similar (void *other,
 					  int width, int height)
 {
     cairo_surface_subsurface_t *surface = other;
+
+    if (surface->target->backend->create_similar == NULL)
+	return NULL;
+
     return surface->target->backend->create_similar (surface->target, content, width, height);
 }
 
@@ -70,6 +74,10 @@ _cairo_surface_subsurface_create_similar_image (void *other,
 						int width, int height)
 {
     cairo_surface_subsurface_t *surface = other;
+
+    if (surface->target->backend->create_similar_image == NULL)
+	return NULL;
+
     return surface->target->backend->create_similar_image (surface->target,
 							   format,
 							   width, height);
commit 9e4fb906b8ab3ac3ddf5372257112bc2afa62df1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 11 12:39:17 2012 +0000

    xcb: Add dimension guards to create-similar-image
    
    Just create a image wrapper for a 0x0 surface, and do not try to create
    an image surface that is larger than the maximum X coordinate.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 282b8f8..aa2bbbf 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -172,6 +172,12 @@ _cairo_xcb_surface_create_similar_image (void			*abstract_other,
     cairo_status_t status;
     pixman_format_code_t pixman_format;
 
+    if (unlikely(width  > XLIB_COORD_MAX ||
+		 height > XLIB_COORD_MAX ||
+		 width  <= 0 ||
+		 height <= 0))
+	return NULL;
+
     pixman_format = _cairo_format_to_pixman_format_code (format);
 
     status = _cairo_xcb_shm_image_create (connection, pixman_format,
@@ -179,6 +185,7 @@ _cairo_xcb_surface_create_similar_image (void			*abstract_other,
 					  &shm_info);
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
+
     return &image->base;
 }
 
commit 5045155de6fa7fcafc345365320f97d6a87ee063
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jan 9 09:43:31 2012 +0000

    xlib: Do not upload inplace if the image does not match the surface format
    
    Currently we perform the conversion using XPutPixel which is hideously
    slow and so it is faster to create a new surface that matches the
    format correctly, upload and allow X to perform the conversion. In other
    words disable the "fast" path for format mismatches.
    
    Based on a patch by Ginn Chen <ginn.chen at oracle.com>
    
    Bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=716462
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-xlib-core-compositor.c b/src/cairo-xlib-core-compositor.c
index fe871ab..191c9b9 100644
--- a/src/cairo-xlib-core-compositor.c
+++ b/src/cairo-xlib-core-compositor.c
@@ -268,6 +268,19 @@ static cairo_bool_t image_upload_box (cairo_box_t *box, void *closure)
 					   x, y) == CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_bool_t
+surface_matches_image_format (cairo_xlib_surface_t *surface,
+			      cairo_image_surface_t *image)
+{
+    cairo_format_masks_t format;
+
+    return (_pixman_format_to_masks (image->pixman_format, &format) &&
+	    (format.alpha_mask == surface->a_mask || surface->a_mask == 0) &&
+	    (format.red_mask   == surface->r_mask || surface->r_mask == 0) &&
+	    (format.green_mask == surface->g_mask || surface->g_mask == 0) &&
+	    (format.blue_mask  == surface->b_mask || surface->b_mask == 0))
+}
+
 static cairo_status_t
 upload_image_inplace (cairo_xlib_surface_t *dst,
 		      const cairo_pattern_t *source,
@@ -291,6 +304,9 @@ upload_image_inplace (cairo_xlib_surface_t *dst,
     if (image->depth != dst->depth)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
+    if (! surface_matches_image_format (dst, image))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
     /* XXX subsurface */
 
     if (! _cairo_matrix_is_integer_translation (&source->matrix,
commit 20a1676c28e57686dda3f7afab035d40228c0f6f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 8 09:51:15 2012 +0000

    test: Add arc-direction
    
    A simple example of how to draw arcs.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/Makefile.sources b/test/Makefile.sources
index f712699..54a2dae 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -12,6 +12,7 @@ test_sources = \
 	a8-mask.c					\
 	aliasing.c					\
 	alpha-similar.c					\
+	arc-direction.c					\
 	arc-infinite-loop.c				\
 	arc-looping-dash.c				\
 	api-special-cases.c				\
diff --git a/test/arc-direction.c b/test/arc-direction.c
new file mode 100644
index 0000000..fddb528
--- /dev/null
+++ b/test/arc-direction.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE		(2 * 20)
+#define PAD		(2)
+
+static cairo_test_status_t
+draw_arcs (cairo_t *cr)
+{
+    double start = M_PI/12, stop = 2*start;
+
+    cairo_move_to (cr, SIZE/2, SIZE/2);
+    cairo_arc (cr, SIZE/2, SIZE/2, SIZE/2, start, stop);
+    cairo_fill (cr);
+
+    cairo_translate (cr, SIZE+PAD, 0);
+    cairo_move_to (cr, SIZE/2, SIZE/2);
+    cairo_arc (cr, SIZE/2, SIZE/2, SIZE/2, 2*M_PI-stop, 2*M_PI-start);
+    cairo_fill (cr);
+
+    cairo_translate (cr, 0, SIZE+PAD);
+    cairo_move_to (cr, SIZE/2, SIZE/2);
+    cairo_arc_negative (cr, SIZE/2, SIZE/2, SIZE/2, 2*M_PI-stop, 2*M_PI-start);
+    cairo_fill (cr);
+
+    cairo_translate (cr, -SIZE-PAD, 0);
+    cairo_move_to (cr, SIZE/2, SIZE/2);
+    cairo_arc_negative (cr, SIZE/2, SIZE/2, SIZE/2, start, stop);
+    cairo_fill (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_save (cr);
+    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+    cairo_paint (cr);
+    cairo_restore (cr);
+
+    cairo_save (cr);
+    cairo_translate (cr, PAD, PAD);
+    draw_arcs(cr);
+    cairo_restore (cr);
+
+    cairo_set_source_rgb (cr, 1, 0, 0);
+    cairo_translate (cr, 2*SIZE+3*PAD, 0);
+    cairo_save (cr);
+    cairo_translate (cr, 2*SIZE+2*PAD, PAD);
+    cairo_scale (cr, -1, 1);
+    draw_arcs(cr);
+    cairo_restore (cr);
+
+    cairo_set_source_rgb (cr, 1, 0, 1);
+    cairo_translate (cr, 0, 2*SIZE+3*PAD);
+    cairo_save (cr);
+    cairo_translate (cr, 2*SIZE+2*PAD, 2*SIZE+2*PAD);
+    cairo_scale (cr, -1, -1);
+    draw_arcs(cr);
+    cairo_restore (cr);
+
+    cairo_set_source_rgb (cr, 0, 0, 1);
+    cairo_translate (cr, -(2*SIZE+3*PAD), 0);
+    cairo_save (cr);
+    cairo_translate (cr, PAD, 2*SIZE+2*PAD);
+    cairo_scale (cr, 1, -1);
+    draw_arcs(cr);
+    cairo_restore (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (arc_direction,
+	    "Test drawing positive/negative arcs",
+	    "arc fill", /* keywords */
+	    NULL, /* requirements */
+	    2*(3*PAD + 2*SIZE), 2*(3*PAD + 2*SIZE),
+	    NULL, draw)
+
diff --git a/test/reference/arc-direction.base.ref.png b/test/reference/arc-direction.base.ref.png
new file mode 100644
index 0000000..2790a2b
Binary files /dev/null and b/test/reference/arc-direction.base.ref.png differ
diff --git a/test/reference/arc-direction.ps.ref.png b/test/reference/arc-direction.ps.ref.png
new file mode 100644
index 0000000..902ab45
Binary files /dev/null and b/test/reference/arc-direction.ps.ref.png differ
diff --git a/test/reference/arc-direction.ref.png b/test/reference/arc-direction.ref.png
new file mode 100644
index 0000000..78be3e9
Binary files /dev/null and b/test/reference/arc-direction.ref.png differ
diff --git a/test/reference/arc-direction.traps.ref.png b/test/reference/arc-direction.traps.ref.png
new file mode 100644
index 0000000..2790a2b
Binary files /dev/null and b/test/reference/arc-direction.traps.ref.png differ
diff --git a/test/reference/arc-direction.xlib.ref.png b/test/reference/arc-direction.xlib.ref.png
new file mode 100644
index 0000000..2790a2b
Binary files /dev/null and b/test/reference/arc-direction.xlib.ref.png differ
commit 42ad7a2385604d6c2715bc2e638e1c75245c8ffe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 4 11:03:07 2012 +0000

    perf/chart: Make the columns transculent so that the label behind is visible
    
    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 8d3d514..df0bd88 100644
--- a/perf/cairo-perf-chart.c
+++ b/perf/cairo-perf-chart.c
@@ -297,6 +297,28 @@ static void set_report_color (struct chart *chart, int report)
     cairo_set_source_rgb (chart->cr, color.red, color.green, color.blue);
 }
 
+static void set_report_gradient (struct chart *chart, int report,
+				 double x, double y, double w, double h)
+{
+    struct color color;
+    cairo_pattern_t *p;
+
+    hsv_to_rgb (6. / chart->num_reports * report, .7, .7, &color);
+
+    p = cairo_pattern_create_linear (x, 0, x+w, 0);
+    cairo_pattern_add_color_stop_rgba (p, 0.0,
+				       color.red, color.green, color.blue,
+				       .50);
+    cairo_pattern_add_color_stop_rgba (p, 0.5,
+				       color.red, color.green, color.blue,
+				       .50);
+    cairo_pattern_add_color_stop_rgba (p, 1.0,
+				       color.red, color.green, color.blue,
+				       1.0);
+    cairo_set_source (chart->cr, p);
+    cairo_pattern_destroy (p);
+}
+
 static void
 test_background (struct chart *c,
 		 int	       test)
@@ -327,8 +349,6 @@ add_chart (struct chart *c,
     if (fabs (value) < 0.1)
 	return;
 
-    set_report_color (c, report);
-
     if (c->relative) {
 	cairo_text_extents_t extents;
 	char buf[80];
@@ -339,11 +359,21 @@ add_chart (struct chart *c,
 	dx = c->width / (double) (c->num_tests * c->num_reports);
 	x = dx * (c->num_reports * test + report - .5);
 
+	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_rectangle (c->cr,
 			 floor (x), c->height / 2.,
 			 floor (x + dx) - floor (x),
 			 ceil (-dy*value - c->height/2.) + c->height/2.);
-	cairo_fill (c->cr);
+	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)
@@ -393,11 +423,21 @@ add_chart (struct chart *c,
 	dx = c->width / (double) (c->num_tests * (c->num_reports+1));
 	x = dx * ((c->num_reports+1) * test + report + .5);
 
+	set_report_gradient (c, report,
+			 floor (x), c->height,
+			 floor (x + dx) - floor (x),
+			 floor (c->height - dy*value) - c->height);
+
 	cairo_rectangle (c->cr,
 			 floor (x), c->height,
 			 floor (x + dx) - floor (x),
 			 floor (c->height - dy*value) - c->height);
-	cairo_fill (c->cr);
+	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);
     }
 }
 
commit 23ca558a051ad7557476c77e6d53b5a76f3eb798
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 4 10:53:28 2012 +0000

    perf/chart: Show values next to the column if too small to fit inside
    
    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 6195f3d..8d3d514 100644
--- a/perf/cairo-perf-chart.c
+++ b/perf/cairo-perf-chart.c
@@ -331,7 +331,6 @@ add_chart (struct chart *c,
 
     if (c->relative) {
 	cairo_text_extents_t extents;
-	cairo_bool_t show_label;
 	char buf[80];
 	double y;
 
@@ -346,11 +345,15 @@ add_chart (struct chart *c,
 			 ceil (-dy*value - c->height/2.) + c->height/2.);
 	cairo_fill (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);
+	    sprintf (buf, "%.1f", -value/100 + 1);
 	} else {
 	    sprintf (buf, "%.1f", value/100 + 1);
 	}
@@ -364,21 +367,26 @@ add_chart (struct chart *c,
 	    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);
-	    show_label = y < -extents.width - 6;
 	} else {
 	    cairo_move_to (c->cr, 2, -extents.y_bearing/2);
-	    show_label = y > extents.width + 6;
 	}
 
 	cairo_set_source_rgb (c->cr, .95, .95, .95);
-	if (show_label)
-	    cairo_show_text (c->cr, buf);
+	cairo_show_text (c->cr, buf);
 	cairo_restore (c->cr);
     } else {
 	dy = (c->height - PAD) / c->max_value;
commit 56a835eb9df7055922dccbc77ba48bd12e07f342
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 4 10:26:04 2012 +0000

    perf/chart: Tweak labels on right not to fall off the edge
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/perf/.gitignore b/perf/.gitignore
index 3ac12bb..02af7a9 100644
--- a/perf/.gitignore
+++ b/perf/.gitignore
@@ -5,6 +5,7 @@ cairo-perf
 cairo-perf-micro
 cairo-perf-print
 cairo-perf-trace
+cairo-perf-chart
 cairo-perf-compare-backends
 cairo-perf-diff-files
 cairo-perf-graph-files
diff --git a/perf/cairo-perf-chart.c b/perf/cairo-perf-chart.c
index 0ecf8b4..6195f3d 100644
--- a/perf/cairo-perf-chart.c
+++ b/perf/cairo-perf-chart.c
@@ -487,10 +487,10 @@ done:
 	cairo_text_extents (c->cr, buf, &extents);
 
 	cairo_set_source_rgba (c->cr, .75, 0, 0, .95);
-	cairo_move_to (c->cr, -extents.x_bearing, floor (y) - (extents.height/2 + extents.y_bearing) + .5);
+	cairo_move_to (c->cr, 1-extents.x_bearing, floor (y) - (extents.height/2 + extents.y_bearing) + .5);
 	cairo_show_text (c->cr, buf);
 
-	cairo_move_to (c->cr, c->width-extents.width+extents.x_bearing, floor (y) - (extents.height/2 + extents.y_bearing) + .5);
+	cairo_move_to (c->cr, c->width-extents.width-1, floor (y) - (extents.height/2 + extents.y_bearing) + .5);
 	cairo_show_text (c->cr, buf);
 
 	cairo_set_source_rgba (c->cr, .75, 0, 0, .5);
@@ -548,17 +548,17 @@ done:
 	cairo_text_extents (c->cr, buf, &extents);
 
 	cairo_set_source_rgba (c->cr, .75, 0, 0, .95);
-	cairo_move_to (c->cr, -extents.x_bearing, floor (mid + y) - (extents.height/2 + extents.y_bearing)+ .5);
+	cairo_move_to (c->cr, 1-extents.x_bearing, floor (mid + y) - (extents.height/2 + extents.y_bearing) + .5);
 	cairo_show_text (c->cr, buf);
 
-	cairo_move_to (c->cr, c->width-extents.width+extents.x_bearing, floor (mid + y) - (extents.height/2 + extents.y_bearing)+ .5);
+	cairo_move_to (c->cr, c->width-extents.width-1, floor (mid + y) - (extents.height/2 + extents.y_bearing) + .5);
 	cairo_show_text (c->cr, buf);
 
 	cairo_set_source_rgba (c->cr, 0, .75, 0, .95);
-	cairo_move_to (c->cr, -extents.x_bearing, ceil (mid - y) - (extents.height/2 + extents.y_bearing)+ .5);
+	cairo_move_to (c->cr, 1-extents.x_bearing, ceil (mid - y) - (extents.height/2 + extents.y_bearing) + .5);
 	cairo_show_text (c->cr, buf);
 
-	cairo_move_to (c->cr, c->width-extents.width+extents.x_bearing, ceil (mid - y) - (extents.height/2 + extents.y_bearing)+ .5);
+	cairo_move_to (c->cr, c->width-extents.width-1, ceil (mid - y) - (extents.height/2 + extents.y_bearing) + .5);
 	cairo_show_text (c->cr, buf);
 
 	/* trim the dashes to no obscure the labels */
@@ -567,7 +567,7 @@ done:
 		       ceil (extents.width + extents.x_bearing + 2),
 		       floor (mid + y) + .5);
 	cairo_line_to (c->cr,
-		       floor (c->width - (extents.width + extents.x_bearing + 2)),
+		       floor (c->width - (extents.width + 2)),
 		       floor (mid + y) + .5);
 	cairo_stroke (c->cr);
 
@@ -576,7 +576,7 @@ done:
 		       ceil (extents.width + extents.x_bearing + 2),
 		       ceil (mid - y) + .5);
 	cairo_line_to (c->cr,
-		       floor (c->width - (extents.width + extents.x_bearing + 2)),
+		       floor (c->width - (extents.width + 2)),
 		       ceil (mid - y) + .5);
 	cairo_stroke (c->cr);
 


More information about the cairo-commit mailing list