[cairo-commit] 4 commits - src/cairo-directfb-surface.c src/cairo-glitz-surface.c src/cairo-gl-surface.c src/cairo-image-surface.c src/cairoint.h src/cairo-pattern.c src/cairo-quartz-surface.c src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-surface-fallback-private.h src/cairo-xlib-surface.c src/test-fallback16-surface.c src/test-fallback-surface.c test/Makefile.am test/Makefile.sources test/radial-gradient-source.argb32.ref.png test/radial-gradient-source.c test/radial-gradient-source.rgb24.ref.png

Chris Wilson ickle at kemper.freedesktop.org
Sat Oct 17 02:39:02 PDT 2009


 src/cairo-directfb-surface.c               |    2 
 src/cairo-gl-surface.c                     |    4 -
 src/cairo-glitz-surface.c                  |    3 
 src/cairo-image-surface.c                  |   15 ++-
 src/cairo-pattern.c                        |   15 ---
 src/cairo-quartz-surface.c                 |    1 
 src/cairo-surface-fallback-private.h       |    1 
 src/cairo-surface-fallback.c               |   15 ++-
 src/cairo-surface.c                        |   14 +--
 src/cairo-xlib-surface.c                   |   18 ----
 src/cairoint.h                             |    4 -
 src/test-fallback-surface.c                |    1 
 src/test-fallback16-surface.c              |    2 
 test/Makefile.am                           |    2 
 test/Makefile.sources                      |    1 
 test/radial-gradient-source.argb32.ref.png |binary
 test/radial-gradient-source.c              |  115 +++++++++++++++++++++++++++++
 test/radial-gradient-source.rgb24.ref.png  |binary
 18 files changed, 144 insertions(+), 69 deletions(-)

New commits:
commit 96117c1212be2bf39a300a212dec85466f49f31e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Oct 17 10:36:10 2009 +0100

    [test] Add radial-gradient-source
    
    ranma42 found a bug in compositing with a radial gradient using the
    SOURCE operator with EXTEND_NONE, as exercised here.

diff --git a/test/Makefile.am b/test/Makefile.am
index d7813f7..54c82bd 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -778,6 +778,8 @@ REFERENCE_IMAGES = \
 	radial-gradient.quartz.ref.png \
 	radial-gradient.ref.png \
 	radial-gradient.svg.xfail.png \
+	radial-gradient-source.argb32.ref.png \
+	radial-gradient-source.rgb24.ref.png \
 	random-intersections-eo.ps.ref.png \
 	random-intersections-eo.quartz.ref.png \
 	random-intersections-eo.ref.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index c313852..840c1e4 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -159,6 +159,7 @@ test_sources = \
 	push-group.c					\
 	push-group-color.c				\
 	radial-gradient.c				\
+	radial-gradient-source.c			\
 	random-intersections-eo.c			\
 	random-intersections-nonzero.c			\
 	random-intersections-curves-eo.c		\
diff --git a/test/radial-gradient-source.argb32.ref.png b/test/radial-gradient-source.argb32.ref.png
new file mode 100644
index 0000000..4733471
Binary files /dev/null and b/test/radial-gradient-source.argb32.ref.png differ
diff --git a/test/radial-gradient-source.c b/test/radial-gradient-source.c
new file mode 100644
index 0000000..b546157
--- /dev/null
+++ b/test/radial-gradient-source.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2005, 2007 Red Hat, Inc.
+ *
+ * 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: Carl D. Worth <cworth at cworth.org>
+ */
+
+/* 20091017: A simple variant on radial-gradient, using the SOURCE operator
+ * instead as a potential bug was found in pixman under those conditions.
+ */
+
+#include "cairo-test.h"
+
+#define NUM_GRADIENTS 4
+#define NUM_EXTEND 4
+#define SIZE 60
+#define WIDTH (SIZE * NUM_GRADIENTS * NUM_GRADIENTS)
+#define HEIGHT (SIZE * NUM_EXTEND)
+
+static void
+draw_gradient (cairo_t		*cr,
+	       int		x,
+	       int		y,
+	       int		size,
+	       double		r1_offset,
+	       double		r1_radius,
+	       double		r2_offset,
+	       double		r2_radius,
+	       cairo_extend_t	extend)
+{
+    cairo_pattern_t *pattern;
+
+    cairo_save (cr);
+
+    pattern = cairo_pattern_create_radial (x + size/2.0 + r1_offset,
+					   y + size/2.0 + r1_offset,
+					   r1_radius,
+					   x + size/2.0 + r2_offset,
+					   y + size/2.0 + r2_offset,
+					   r2_radius);
+    cairo_pattern_add_color_stop_rgba (pattern, 0.0,
+				       1.0, 0.0, 0.0, 1.0);
+    cairo_pattern_add_color_stop_rgba (pattern, sqrt (1.0 / 2.0),
+				       0.0, 1.0, 0.0, 0.0);
+    cairo_pattern_add_color_stop_rgba (pattern, 1.0,
+				       0.0, 0.0, 1.0, 0.5);
+    cairo_pattern_set_extend (pattern, extend);
+
+    cairo_rectangle (cr, x, y, size, size);
+    cairo_clip (cr);
+
+    cairo_set_source (cr, pattern);
+    cairo_paint (cr);
+
+    cairo_pattern_destroy (pattern);
+
+    cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    int i, j, k;
+    cairo_extend_t extend[NUM_EXTEND] = {
+	CAIRO_EXTEND_NONE,
+	CAIRO_EXTEND_REPEAT,
+	CAIRO_EXTEND_REFLECT,
+	CAIRO_EXTEND_PAD
+    };
+
+    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+    for (j = 0; j < NUM_EXTEND; j++) {
+	for (i = 0; i < NUM_GRADIENTS; i++) {
+	    double r1_offset = i % 2 ? SIZE / 12.0 : 0.0;
+	    double r1_radius = i >= NUM_GRADIENTS / 2 ? SIZE / 6.0 : 0.0;
+	    for (k = 0; k < NUM_GRADIENTS; k++) {
+		double r2_offset = k % 2 ? SIZE / 12.0 : 0.0;
+		double r2_radius = k >= NUM_GRADIENTS / 2 ? SIZE / 3.0 : SIZE / 12.;
+		draw_gradient (cr,
+			       i * SIZE * NUM_GRADIENTS + k * SIZE, j * SIZE, SIZE,
+			       r1_offset, r1_radius,
+			       r2_offset, r2_radius,
+			       extend[j]);
+	    }
+	}
+    }
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (radial_gradient_source,
+	    "Simple test of radial gradients using the SOURCE operator",
+	    "gradient,source", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, draw)
diff --git a/test/radial-gradient-source.rgb24.ref.png b/test/radial-gradient-source.rgb24.ref.png
new file mode 100644
index 0000000..27e9927
Binary files /dev/null and b/test/radial-gradient-source.rgb24.ref.png differ
commit 54df07a3da2bfbbdbe2dde92ca298ac0d7b8d255
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 16 10:11:41 2009 +0100

    [surface] Don't AND in the desired content.
    
    Gah, that was a horrible mistake. It was a flawed hack to create Pixmaps
    of the correct depth when cloning patterns for blitting to the xlib
    backend. However, it had the nasty side-effect of discarding alpha when
    targeting Window surfaces. The correct solution is to simply correct the
    Pixmap of the desired depth and render a matching pattern onto the
    surface - i.e. a reversal the current acquire -> clone. See the
    forthcoming revised xcb backend on how I should have done it originally.

diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index 8247fb9..afad270 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -706,7 +706,6 @@ _cairo_directfb_surface_release_dest_image (void                  *abstract_surf
 static cairo_status_t
 _cairo_directfb_surface_clone_similar (void             *abstract_surface,
                                        cairo_surface_t  *src,
-				       cairo_content_t	 content,
                                        int               src_x,
                                        int               src_y,
                                        int               width,
@@ -846,7 +845,6 @@ _directfb_prepare_composite (cairo_directfb_surface_t    *dst,
     }
 
     status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
-					     CAIRO_CONTENT_COLOR_ALPHA,
 					     *src_x, *src_y, width, height,
 					     CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
 					     (cairo_surface_t **) &src,
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 17bf4bc..64ae29b 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -801,7 +801,6 @@ _cairo_gl_surface_release_dest_image (void		      *abstract_surface,
 static cairo_status_t
 _cairo_gl_surface_clone_similar (void		     *abstract_surface,
 				 cairo_surface_t     *src,
-				 cairo_content_t      content,
 				 int                  src_x,
 				 int                  src_y,
 				 int                  width,
@@ -825,7 +824,7 @@ _cairo_gl_surface_clone_similar (void		     *abstract_surface,
 
 	clone = (cairo_gl_surface_t *)
 	    _cairo_gl_surface_create_similar (&surface->base,
-		                              content,
+		                              src->content,
 					      width, height);
 	if (clone == NULL)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1051,7 +1050,6 @@ _cairo_gl_pattern_texture_setup (cairo_gl_composite_operand_t *operand,
     }
 
     status = _cairo_pattern_acquire_surface (src, &dst->base,
-					     CAIRO_CONTENT_COLOR_ALPHA,
 					     src_x, src_y,
 					     width, height,
 					     CAIRO_PATTERN_ACQUIRE_NONE,
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index a649d50..5f97f65 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -332,7 +332,6 @@ _cairo_glitz_surface_release_dest_image (void                    *abstract_surfa
 static cairo_status_t
 _cairo_glitz_surface_clone_similar (void	    *abstract_surface,
 				    cairo_surface_t *src,
-				    cairo_content_t  content,
 				    int              src_x,
 				    int              src_y,
 				    int              width,
@@ -737,7 +736,6 @@ _cairo_glitz_pattern_acquire_surface (const cairo_pattern_t	       *pattern,
 	cairo_int_status_t status;
 
 	status = _cairo_pattern_acquire_surface (pattern, &dst->base,
-						 CAIRO_CONTENT_COLOR_ALPHA,
 						 x, y, width, height,
 						 CAIRO_PATTERN_ACQUIRE_NONE,
 						 (cairo_surface_t **) &src,
@@ -2223,7 +2221,6 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
 		status =
 		    _cairo_glitz_surface_clone_similar (abstract_surface,
 							image,
-							CAIRO_CONTENT_COLOR_ALPHA,
 							0,
 							0,
 							glyph_width,
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 05b0edb..4dbc2fe 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -854,7 +854,6 @@ _cairo_image_surface_release_dest_image (void                    *abstract_surfa
 static cairo_status_t
 _cairo_image_surface_clone_similar (void		*abstract_surface,
 				    cairo_surface_t	*src,
-				    cairo_content_t	 content,
 				    int                  src_x,
 				    int                  src_y,
 				    int                  width,
@@ -1093,7 +1092,6 @@ _cairo_image_surface_composite (cairo_operator_t	 op,
 
     status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern,
 					      &dst->base,
-					      CAIRO_CONTENT_COLOR_ALPHA,
 					      src_x, src_y,
 					      mask_x, mask_y,
 					      width, height,
@@ -1313,7 +1311,6 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t	op,
 	return status;
 
     status = _cairo_pattern_acquire_surface (pattern, &dst->base,
-					     CAIRO_CONTENT_COLOR_ALPHA,
 					     src_x, src_y, width, height,
 					     CAIRO_PATTERN_ACQUIRE_NONE,
 					     (cairo_surface_t **) &src,
@@ -1565,7 +1562,6 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t	 op,
 
     status = _cairo_pattern_acquire_surface (
 	renderer->pattern, &renderer->dst->base,
-	CAIRO_CONTENT_COLOR_ALPHA,
 	rects->src.x, rects->src.y,
 	width, height,
 	CAIRO_PATTERN_ACQUIRE_NONE,
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 2990e2a..d72867a 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1603,9 +1603,6 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
     _cairo_debug_check_image_surface_is_defined (&image->base);
 
     status = _cairo_surface_clone_similar (dst, &image->base,
-					   opaque ?
-					   CAIRO_CONTENT_COLOR :
-					   CAIRO_CONTENT_COLOR_ALPHA,
 					   0, 0, width, height,
 					   &clone_offset_x,
 					   &clone_offset_y,
@@ -1931,7 +1928,6 @@ _pixman_nearest_sample (double d)
 static cairo_int_status_t
 _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t   *pattern,
 					    cairo_surface_t	       *dst,
-					    cairo_content_t	    content,
 					    int			       x,
 					    int			       y,
 					    unsigned int	       width,
@@ -2009,7 +2005,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t   *pat
 	is_bounded = _cairo_surface_get_extents (surface, &extents);
 	assert (is_bounded);
 
-	status = _cairo_surface_clone_similar (dst, surface, content,
+	status = _cairo_surface_clone_similar (dst, surface,
 					       extents.x, extents.y,
 					       extents.width, extents.height,
 					       &extents.x, &extents.y, &src);
@@ -2150,7 +2146,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t   *pat
 
     /* XXX can we use is_empty? */
 
-    status = _cairo_surface_clone_similar (dst, surface, content,
+    status = _cairo_surface_clone_similar (dst, surface,
 					   extents.x, extents.y,
 					   extents.width, extents.height,
 					   &x, &y, out);
@@ -2224,7 +2220,6 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t   *pat
 cairo_int_status_t
 _cairo_pattern_acquire_surface (const cairo_pattern_t	   *pattern,
 				cairo_surface_t		   *dst,
-				cairo_content_t		    content,
 				int			   x,
 				int			   y,
 				unsigned int		   width,
@@ -2318,7 +2313,6 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t	   *pattern,
 	cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) pattern;
 
 	status = _cairo_pattern_acquire_surface_for_surface (src, dst,
-							     content,
 							     x, y,
 							     width, height,
 							     flags,
@@ -2353,7 +2347,6 @@ cairo_int_status_t
 _cairo_pattern_acquire_surfaces (const cairo_pattern_t	    *src,
 				 const cairo_pattern_t	    *mask,
 				 cairo_surface_t	    *dst,
-				 cairo_content_t	    src_content,
 				 int			    src_x,
 				 int			    src_y,
 				 int			    mask_x,
@@ -2391,14 +2384,13 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t	    *src,
 	_cairo_color_multiply_alpha (&combined, mask_solid->color.alpha);
 
 	_cairo_pattern_init_solid (&src_tmp.solid, &combined,
-				   (src_solid->content | mask_solid->content) & src_content);
+				   src_solid->content | mask_solid->content);
 
 	src = &src_tmp.base;
 	mask = NULL;
     }
 
     status = _cairo_pattern_acquire_surface (src, dst,
-					     src_content,
 					     src_x, src_y,
 					     width, height,
 					     flags,
@@ -2412,7 +2404,6 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t	    *src,
     }
 
     status = _cairo_pattern_acquire_surface (mask, dst,
-					     CAIRO_CONTENT_ALPHA,
 					     mask_x, mask_y,
 					     width, height,
 					     flags,
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index cc4a8ae..17de3b1 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1633,7 +1633,6 @@ _cairo_quartz_surface_create_similar (void *abstract_surface,
 static cairo_status_t
 _cairo_quartz_surface_clone_similar (void *abstract_surface,
 				     cairo_surface_t *src,
-				     cairo_content_t  content,
 				     int              src_x,
 				     int              src_y,
 				     int              width,
diff --git a/src/cairo-surface-fallback-private.h b/src/cairo-surface-fallback-private.h
index 236b745..c63c36e 100644
--- a/src/cairo-surface-fallback-private.h
+++ b/src/cairo-surface-fallback-private.h
@@ -128,7 +128,6 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t		op,
 cairo_private cairo_status_t
 _cairo_surface_fallback_clone_similar (cairo_surface_t  *surface,
 				       cairo_surface_t  *src,
-				       cairo_content_t	 content,
 				       int               src_x,
 				       int               src_y,
 				       int               width,
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index f1453b8..15d2a63 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -1835,7 +1835,6 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t		op,
 cairo_status_t
 _cairo_surface_fallback_clone_similar (cairo_surface_t	*surface,
 				       cairo_surface_t	*src,
-				       cairo_content_t	 content,
 				       int		 src_x,
 				       int		 src_y,
 				       int		 width,
@@ -1849,7 +1848,7 @@ _cairo_surface_fallback_clone_similar (cairo_surface_t	*surface,
     cairo_status_t status;
 
     new_surface = _cairo_surface_create_similar_scratch (surface,
-							 src->content & content,
+							 src->content,
 							 width, height);
     if (new_surface == NULL)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index ab84bbf..51eb6f0 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1413,7 +1413,6 @@ _cairo_surface_release_dest_image (cairo_surface_t         *surface,
 static cairo_status_t
 _cairo_meta_surface_clone_similar (cairo_surface_t  *surface,
 			           cairo_surface_t  *src,
-				   cairo_content_t   content,
 				   int               src_x,
 				   int               src_y,
 				   int               width,
@@ -1428,7 +1427,7 @@ _cairo_meta_surface_clone_similar (cairo_surface_t  *surface,
 
     similar = _cairo_surface_has_snapshot (src,
 					   surface->backend,
-					   src->content & content);
+					   src->content);
     if (similar != NULL) {
 	*clone_out = cairo_surface_reference (similar);
 	*clone_offset_x = 0;
@@ -1441,7 +1440,7 @@ _cairo_meta_surface_clone_similar (cairo_surface_t  *surface,
     {
 	/* XXX use _solid to perform an initial CLEAR? */
 	similar = _cairo_surface_create_similar_scratch (surface,
-							 src->content & content,
+							 src->content,
 							 width, height);
 	if (similar == NULL)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1457,7 +1456,7 @@ _cairo_meta_surface_clone_similar (cairo_surface_t  *surface,
 	}
     } else {
 	similar = _cairo_surface_create_similar_scratch (surface,
-							 src->content & content,
+							 src->content,
 							 meta->extents.width,
 							 meta->extents.height);
 	if (similar == NULL)
@@ -1510,7 +1509,6 @@ _cairo_meta_surface_clone_similar (cairo_surface_t  *surface,
 cairo_status_t
 _cairo_surface_clone_similar (cairo_surface_t  *surface,
 			      cairo_surface_t  *src,
-			      cairo_content_t	content,
 			      int               src_x,
 			      int               src_y,
 			      int               width,
@@ -1534,14 +1532,13 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
 
 	match = _cairo_tee_surface_find_match (src,
 					       surface->backend,
-					       content);
+					       src->content);
 	if (match != NULL)
 	    src = match;
     }
 
     if (surface->backend->clone_similar != NULL) {
 	status = surface->backend->clone_similar (surface, src,
-						  content,
 						  src_x, src_y,
 						  width, height,
 						  clone_offset_x,
@@ -1554,7 +1551,6 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
 	    /* First check to see if we can replay to a similar surface */
 	    if (_cairo_surface_is_meta (src)) {
 		return _cairo_meta_surface_clone_similar (surface, src,
-							  content,
 							  src_x, src_y,
 							  width, height,
 							  clone_offset_x,
@@ -1567,7 +1563,6 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
 	    if (status == CAIRO_STATUS_SUCCESS) {
 		status =
 		    surface->backend->clone_similar (surface, &image->base,
-						     content,
 						     src_x, src_y,
 						     width, height,
 						     clone_offset_x,
@@ -1583,7 +1578,6 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	status =
 	    _cairo_surface_fallback_clone_similar (surface, src,
-						   content,
 						   src_x, src_y,
 						   width, height,
 						   clone_offset_x,
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 81f2ec3..994a4f9 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1317,7 +1317,6 @@ _cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst,
 static cairo_status_t
 _cairo_xlib_surface_clone_similar (void			*abstract_surface,
 				   cairo_surface_t	*src,
-				   cairo_content_t	 content,
 				   int                   src_x,
 				   int                   src_y,
 				   int                   width,
@@ -1350,7 +1349,7 @@ _cairo_xlib_surface_clone_similar (void			*abstract_surface,
 
 	clone = (cairo_xlib_surface_t *)
 	    _cairo_xlib_surface_create_similar (surface,
-						image_src->base.content & content,
+						image_src->base.content,
 						width, height);
 	if (clone == NULL)
 	    return UNSUPPORTED ("unhandled image format, no similar surface");
@@ -1878,7 +1877,6 @@ _render_operator (cairo_operator_t op)
 static cairo_int_status_t
 _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
 					     const cairo_pattern_t *pattern,
-					     cairo_content_t content,
 					     int x, int y,
 					     int width, int height,
 					     cairo_xlib_surface_t **surface_out,
@@ -2046,7 +2044,6 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
     }
 
     return _cairo_pattern_acquire_surface (pattern, &dst->base,
-					   content,
 					   x, y, width, height,
 					   dst->buggy_pad_reflect ?
 					   CAIRO_PATTERN_ACQUIRE_NO_REFLECT :
@@ -2059,7 +2056,6 @@ static cairo_int_status_t
 _cairo_xlib_surface_acquire_pattern_surfaces (cairo_xlib_surface_t	 *dst,
 					      const cairo_pattern_t	         *src,
 					      const cairo_pattern_t	         *mask,
-					      cairo_content_t		 src_content,
 					      int			 src_x,
 					      int			 src_y,
 					      int			 mask_x,
@@ -2080,7 +2076,6 @@ _cairo_xlib_surface_acquire_pattern_surfaces (cairo_xlib_surface_t	 *dst,
 	cairo_int_status_t status;
 
 	status = _cairo_xlib_surface_acquire_pattern_surface (dst, src,
-							      src_content,
 							      src_x, src_y,
 							      width, height,
 							      src_out,
@@ -2090,7 +2085,6 @@ _cairo_xlib_surface_acquire_pattern_surfaces (cairo_xlib_surface_t	 *dst,
 
 	if (mask) {
 	    status = _cairo_xlib_surface_acquire_pattern_surface (dst, mask,
-								  CAIRO_CONTENT_ALPHA,
 								  mask_x,
 								  mask_y,
 								  width,
@@ -2111,7 +2105,6 @@ _cairo_xlib_surface_acquire_pattern_surfaces (cairo_xlib_surface_t	 *dst,
 
     return _cairo_pattern_acquire_surfaces (src, mask,
 					    &dst->base,
-					    src_content,
 					    src_x, src_y,
 					    mask_x, mask_y,
 					    width, height,
@@ -2147,7 +2140,6 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
     int				itx, ity;
     cairo_bool_t		is_integer_translation;
     cairo_bool_t		needs_alpha_composite;
-    cairo_content_t		src_content;
     GC				gc;
 
     if (mask_pattern != NULL && ! CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
@@ -2164,16 +2156,12 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 	_operator_needs_alpha_composite (op,
 					 _surface_has_alpha (dst),
 					 ! _cairo_pattern_is_opaque (src_pattern));
-    src_content = CAIRO_CONTENT_COLOR_ALPHA;
-    if (! needs_alpha_composite)
-	src_content &= ~CAIRO_CONTENT_ALPHA;
 
     _cairo_xlib_display_notify (dst->display);
 
     status =
 	_cairo_xlib_surface_acquire_pattern_surfaces (dst,
 						      src_pattern, mask_pattern,
-						      src_content,
 						      src_x, src_y,
 						      mask_x, mask_y,
 						      width, height,
@@ -2371,7 +2359,6 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t    *surface,
     X_DEBUG ((surface->dpy, "solid_fill_rectangles (dst=%x)", (unsigned int) surface->drawable));
 
     status = _cairo_pattern_acquire_surface (&solid.base, &surface->base,
-					     CAIRO_CONTENT_COLOR_ALPHA,
 					     0, 0,
 					     ARRAY_LENGTH (dither_pattern[0]),
 					     ARRAY_LENGTH (dither_pattern),
@@ -2562,7 +2549,6 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
 
     status = _cairo_xlib_surface_acquire_pattern_surface (dst,
 							  pattern,
-							  CAIRO_CONTENT_COLOR_ALPHA,
 							  src_x, src_y,
 							  width, height,
 							  &src, &attributes);
@@ -4462,7 +4448,6 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 
     if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
         status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
-						 CAIRO_CONTENT_COLOR_ALPHA,
                                                  0, 0, 1, 1,
 						 CAIRO_PATTERN_ACQUIRE_NONE,
                                                  (cairo_surface_t **) &src,
@@ -4489,7 +4474,6 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 	}
 
         status = _cairo_xlib_surface_acquire_pattern_surface (dst, src_pattern,
-							      dst->base.content,
 							      glyph_extents.x,
 							      glyph_extents.y,
 							      glyph_extents.width,
diff --git a/src/cairoint.h b/src/cairoint.h
index ccf790a..b913913 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -622,7 +622,6 @@ struct _cairo_surface_backend {
     cairo_warn cairo_status_t
     (*clone_similar)            (void                   *surface,
 				 cairo_surface_t        *src,
-				 cairo_content_t	 content,
 				 int                     src_x,
 				 int                     src_y,
 				 int                     width,
@@ -2072,7 +2071,6 @@ _cairo_surface_release_dest_image (cairo_surface_t        *surface,
 cairo_private cairo_status_t
 _cairo_surface_clone_similar (cairo_surface_t  *surface,
 			      cairo_surface_t  *src,
-			      cairo_content_t	content,
 			      int               src_x,
 			      int               src_y,
 			      int               width,
@@ -2569,7 +2567,6 @@ enum {
 cairo_private cairo_int_status_t
 _cairo_pattern_acquire_surface (const cairo_pattern_t	   *pattern,
 				cairo_surface_t		   *dst,
-				cairo_content_t		    content,
 				int			   x,
 				int			   y,
 				unsigned int		   width,
@@ -2587,7 +2584,6 @@ cairo_private cairo_int_status_t
 _cairo_pattern_acquire_surfaces (const cairo_pattern_t	    *src,
 				 const cairo_pattern_t	    *mask,
 				 cairo_surface_t	    *dst,
-				 cairo_content_t	    src_content,
 				 int			    src_x,
 				 int			    src_y,
 				 int			    mask_x,
diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c
index f331cf2..3b62e55 100644
--- a/src/test-fallback-surface.c
+++ b/src/test-fallback-surface.c
@@ -172,7 +172,6 @@ _test_fallback_surface_release_dest_image (void			   *abstract_surface,
 static cairo_status_t
 _test_fallback_surface_clone_similar (void		  *abstract_surface,
 				      cairo_surface_t     *src,
-				      cairo_content_t      content,
 				      int                  src_x,
 				      int                  src_y,
 				      int                  width,
diff --git a/src/test-fallback16-surface.c b/src/test-fallback16-surface.c
index 5f6bee4..91699ef 100644
--- a/src/test-fallback16-surface.c
+++ b/src/test-fallback16-surface.c
@@ -166,7 +166,6 @@ _test_fallback16_surface_release_dest_image (void			   *abstract_surface,
 static cairo_status_t
 _test_fallback16_surface_clone_similar (void		  *abstract_surface,
 					cairo_surface_t     *src,
-					cairo_content_t	     content,
 					int                  src_x,
 					int                  src_y,
 					int                  width,
@@ -185,7 +184,6 @@ _test_fallback16_surface_clone_similar (void		  *abstract_surface,
 	return CAIRO_STATUS_SUCCESS;
     } else {
 	return _cairo_surface_clone_similar (surface->backing, src,
-					     content,
 					     src_x, src_y,
 					     width, height,
 					     clone_offset_x, clone_offset_y,
commit 6a19a82efd3afe8fb8bd30e5362b247de8efe159
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 16 08:43:21 2009 +0100

    [image] Clone the format for a similar surface with identical content
    
    Honour the incoming surface format when we are asked to create a similar
    surface with identical content. The goal of
    cairo_surface_create_similar() is to create an intermediate with similar
    characteristics to the original that can be used in place of the
    original and be quick to copy to the original. Matching the format for
    the same content, ensures that the blits between the two need only be a
    memcpy.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 9310a51..05b0edb 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -760,12 +760,19 @@ _cairo_format_bits_per_pixel (cairo_format_t format)
 }
 
 static cairo_surface_t *
-_cairo_image_surface_create_similar (void	       *abstract_src,
+_cairo_image_surface_create_similar (void	       *abstract_other,
 				     cairo_content_t	content,
 				     int		width,
 				     int		height)
 {
-    assert (CAIRO_CONTENT_VALID (content));
+    cairo_image_surface_t *other = abstract_other;
+
+    if (content == other->base.content) {
+	return _cairo_image_surface_create_with_pixman_format (NULL,
+							       other->pixman_format,
+							       width, height,
+							       0);
+    }
 
     return _cairo_image_surface_create_with_content (content,
 						     width, height);
commit ed94d7caad6b851f6f80fa4d67441ad0387a8cd4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 16 08:38:24 2009 +0100

    [fallback] Create intermediate surface with same content.
    
    The goal is to create a similar surface with an identical format to
    maximise performance in the subsequent blit, e.g. the xlib backend could
    make the similar surface with an identical depth and so use the core
    protocol, or the image surface could indeed make an identical copy so
    that pixman only has to do a fast memcpy. As there is no direct method
    to specify such a clone, we ask the backend for a similar surface of
    identical content, and trust that the semantics are clear enough for the
    intent to obvious.

diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 068f06d..f1453b8 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -227,17 +227,19 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
     cairo_status_t status;
 
     /* We'd be better off here creating a surface identical in format
-     * to dst, but we have no way of getting that information.
-     * A CAIRO_CONTENT_CLONE or something might be useful.
+     * to dst, but we have no way of getting that information. Instead
+     * we ask the backend to create a similar surface of identical content,
+     * in the belief that the backend will do something useful - like use
+     * an identical format. For example, the xlib backend will endeavor to
+     * use a compatible depth to enable core protocol routines.
      */
     intermediate =
-	_cairo_surface_create_similar_scratch (dst,
-					       CAIRO_CONTENT_COLOR_ALPHA,
+	_cairo_surface_create_similar_scratch (dst, dst->content,
 					       extents->width,
 					       extents->height);
     if (intermediate == NULL) {
 	intermediate =
-	    _cairo_image_surface_create_with_content (CAIRO_CONTENT_COLOR_ALPHA,
+	    _cairo_image_surface_create_with_content (dst->content,
 						      extents->width,
 						      extents->width);
     }


More information about the cairo-commit mailing list