[cairo-commit] 6 commits - perf/cairo-perf.c perf/Makefile.am src/cairo-glitz-surface.c src/cairo-matrix.c src/cairo-skiplist.c test/cairo-test-runner.c test/glitz-surface-source.c test/glitz-surface-source.ps2.ref.png test/glitz-surface-source.ps3.ref.png test/Makefile.am test/quartz-surface-source.c test/quartz-surface-source.ps2.ref.png test/quartz-surface-source.ps3.ref.png test/quartz-surface-source.ref.png

Chris Wilson ickle at kemper.freedesktop.org
Wed Nov 26 09:00:26 PST 2008


 perf/Makefile.am                       |    4 
 perf/cairo-perf.c                      |    4 
 src/cairo-glitz-surface.c              |  458 +++++++++------------------------
 src/cairo-matrix.c                     |    4 
 src/cairo-skiplist.c                   |   11 
 test/Makefile.am                       |   10 
 test/cairo-test-runner.c               |    4 
 test/glitz-surface-source.c            |   96 ++++++
 test/glitz-surface-source.ps2.ref.png  |binary
 test/glitz-surface-source.ps3.ref.png  |binary
 test/quartz-surface-source.c           |   42 +++
 test/quartz-surface-source.ps2.ref.png |binary
 test/quartz-surface-source.ps3.ref.png |binary
 test/quartz-surface-source.ref.png     |binary
 14 files changed, 298 insertions(+), 335 deletions(-)

New commits:
commit 60282b866aab359840b4bcaa6aaccaca2eccd3d2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 26 16:58:29 2008 +0000

    [glitz] Fix clone_similar().
    
    Clone similar open-coded various image surface functions and failed to
    clone a sub-region resulting in failures for mask-transformed-* and
    large-source.

diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 3916f8f..d4eb068 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -33,7 +33,8 @@ typedef struct _cairo_glitz_surface {
 
     glitz_surface_t   *surface;
     glitz_format_t    *format;
-    cairo_bool_t      has_clip;
+
+    cairo_bool_t       has_clip;
     glitz_box_t       *clip_boxes;
     int                num_clip_boxes;
 } cairo_glitz_surface_t;
@@ -46,10 +47,8 @@ _cairo_glitz_surface_finish (void *abstract_surface)
 {
     cairo_glitz_surface_t *surface = abstract_surface;
 
-    if (surface->has_clip) {
-        glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
+    if (surface->clip_boxes)
 	free (surface->clip_boxes);
-    }
 
     glitz_surface_destroy (surface->surface);
 
@@ -108,7 +107,9 @@ _cairo_glitz_surface_create_similar (void	    *abstract_src,
 }
 
 static cairo_status_t
-_cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes, int *nboxes)
+_cairo_glitz_get_boxes_from_region (cairo_region_t *region,
+				    glitz_box_t **boxes,
+				    int *nboxes)
 {
     pixman_box32_t *pboxes;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
@@ -118,15 +119,16 @@ _cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes,
     n = 0;
     pboxes = pixman_region32_rectangles (&region->rgn, &n);
     if (n == 0) {
-       *nboxes = 0;
-       *boxes = NULL;
-	goto done;
+	*nboxes = 0;
+	return CAIRO_STATUS_SUCCESS;
     }
 
-    *boxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
-    if (*boxes == NULL) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto done;
+    if (n > *nboxes) {
+	*boxes = _cairo_malloc_ab (n, sizeof (glitz_box_t));
+	if (*boxes == NULL) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    goto done;
+	}
     }
 
     for (i = 0; i < n; i++) {
@@ -141,8 +143,6 @@ done:
     return status;
 }
 
-#define STRIDE_ALIGNMENT (sizeof (uint32_t))
-
 static cairo_status_t
 _cairo_glitz_surface_get_image (cairo_glitz_surface_t   *surface,
 				cairo_rectangle_int_t   *interest,
@@ -150,95 +150,62 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t   *surface,
 				cairo_rectangle_int_t   *rect_out)
 {
     cairo_image_surface_t *image;
-    int			  x1, y1, x2, y2;
-    int			  width, height;
-    unsigned char	  *pixels;
+    cairo_rectangle_int_t extents;
+    cairo_format_t format;
     cairo_format_masks_t  masks;
     glitz_buffer_t	  *buffer;
     glitz_pixel_format_t  pf;
-    cairo_status_t status;
-    pixman_format_code_t pixman_format;
 
-    x1 = 0;
-    y1 = 0;
-    x2 = glitz_surface_get_width (surface->surface);
-    y2 = glitz_surface_get_height (surface->surface);
+    extents.x = 0;
+    extents.y = 0;
+    extents.width  = glitz_surface_get_width (surface->surface);
+    extents.height = glitz_surface_get_height (surface->surface);
 
-    if (interest)
-    {
-	if (interest->x > x1)
-	    x1 = interest->x;
-	if (interest->y > y1)
-	    y1 = interest->y;
-	if (interest->x + interest->width < (unsigned int)x2)
-	    x2 = interest->x + interest->width;
-	if (interest->y + interest->height < (unsigned int)y2)
-	    y2 = interest->y + interest->height;
-
-	if (x1 >= x2 || y1 >= y2)
-	{
+    if (interest != NULL) {
+	if (! _cairo_rectangle_intersect (&extents, interest)) {
 	    *image_out = NULL;
 	    return CAIRO_STATUS_SUCCESS;
 	}
     }
 
-    width  = x2 - x1;
-    height = y2 - y1;
-
-    if (rect_out)
-    {
-	rect_out->x = x1;
-	rect_out->y = y1;
-	rect_out->width = width;
-	rect_out->height = height;
-    }
+    if (rect_out != NULL)
+	*rect_out = extents;
 
     if (surface->format->color.fourcc == GLITZ_FOURCC_RGB) {
 	if (surface->format->color.red_size > 0) {
-	    masks.bpp = 32;
-
 	    if (surface->format->color.alpha_size > 0)
-		masks.alpha_mask = 0xff000000;
+		format = CAIRO_FORMAT_ARGB32;
 	    else
-		masks.alpha_mask = 0x0;
-
-	    masks.red_mask = 0xff0000;
-	    masks.green_mask = 0xff00;
-	    masks.blue_mask = 0xff;
+		format = CAIRO_FORMAT_RGB24;
 	} else {
-	    masks.bpp = 8;
-	    masks.blue_mask = masks.green_mask = masks.red_mask = 0x0;
-	    masks.alpha_mask = 0xff;
+	    format = CAIRO_FORMAT_A8;
 	}
-    } else {
-	masks.bpp = 32;
-	masks.alpha_mask = 0xff000000;
-	masks.red_mask = 0xff0000;
-	masks.green_mask = 0xff00;
-	masks.blue_mask = 0xff;
-    }
+    } else
+	format = CAIRO_FORMAT_ARGB32;
 
+    image = (cairo_image_surface_t*)
+	cairo_image_surface_create (format, extents.width, extents.height);
+    if (image->base.status)
+	return image->base.status;
+
+    _pixman_format_to_masks (image->pixman_format, &masks);
     pf.fourcc = GLITZ_FOURCC_RGB;
     pf.masks.bpp = masks.bpp;
     pf.masks.alpha_mask = masks.alpha_mask;
-    pf.masks.red_mask = masks.red_mask;
+    pf.masks.red_mask   = masks.red_mask;
     pf.masks.green_mask = masks.green_mask;
-    pf.masks.blue_mask = masks.blue_mask;
+    pf.masks.blue_mask  = masks.blue_mask;
     pf.xoffset = 0;
     pf.skip_lines = 0;
 
     /* XXX: we should eventually return images with negative stride,
        need to verify that libpixman have no problem with this first. */
-    pf.bytes_per_line = ((masks.bpp * width + 7) / 8 + STRIDE_ALIGNMENT - 1) & ~(STRIDE_ALIGNMENT - 1);
+    pf.bytes_per_line = image->stride;
     pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
 
-    pixels = _cairo_malloc_ab (height, pf.bytes_per_line);
-    if (!pixels)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    buffer = glitz_buffer_create_for_data (pixels);
-    if (!buffer) {
-	free (pixels);
+    buffer = glitz_buffer_create_for_data (image->data);
+    if (buffer == NULL) {
+	cairo_surface_destroy (&image->base);
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
@@ -248,83 +215,24 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t   *surface,
 				       0, 0, NULL, 0);
 
     glitz_get_pixels (surface->surface,
-		      x1, y1,
-		      width, height,
+		      extents.x, extents.y,
+		      extents.width, extents.height,
 		      &pf,
 		      buffer);
 
     glitz_buffer_destroy (buffer);
 
     /* restore the clip, if any */
-    if (surface->has_clip)
-	glitz_surface_set_clip_region (surface->surface, 0, 0,
+    if (surface->has_clip) {
+	glitz_surface_set_clip_region (surface->surface,
+				       0, 0,
 				       surface->clip_boxes,
 				       surface->num_clip_boxes);
-
-    if (! _pixman_format_from_masks (&masks, &pixman_format))
-    {
-	status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
-	goto FAIL;
     }
 
-    image = (cairo_image_surface_t*)
-	_cairo_image_surface_create_with_pixman_format ((unsigned char *) pixels,
-							pixman_format,
-							width,
-							height,
-							pf.bytes_per_line);
-    if (image->base.status)
-    {
-	status = image->base.status;
-	goto FAIL;
-    }
-
-    _cairo_image_surface_assume_ownership_of_data (image);
-
     *image_out = image;
 
     return CAIRO_STATUS_SUCCESS;
-
- FAIL:
-    free (pixels);
-    return status;
-}
-
-static void
-cairo_format_get_masks (cairo_format_t  format,
-			uint32_t       *bpp,
-                        uint32_t       *alpha,
-			uint32_t       *red,
-			uint32_t       *green,
-			uint32_t       *blue)
-{
-    *red = 0x0;
-    *green = 0x0;
-    *blue = 0x0;
-    *alpha = 0x0;
-
-    switch (format)
-    {
-    case CAIRO_FORMAT_ARGB32:
-        *alpha = 0xff000000;
-    case CAIRO_FORMAT_RGB24:
-    default:
-	*bpp =   32;
-	*red =   0x00ff0000;
-	*green = 0x0000ff00;
-	*blue =  0x000000ff;
-	break;
-
-    case CAIRO_FORMAT_A8:
-	*bpp = 8;
-        *alpha = 0xff;
-	break;
-
-    case CAIRO_FORMAT_A1:
-	*bpp = 1;
-        *alpha = 0x1;
-	break;
-    }
 }
 
 static cairo_status_t
@@ -340,36 +248,33 @@ _cairo_glitz_surface_set_image (void		      *abstract_surface,
     cairo_glitz_surface_t *surface = abstract_surface;
     glitz_buffer_t	  *buffer;
     glitz_pixel_format_t  pf;
-    uint32_t		  bpp, am, rm, gm, bm;
+    cairo_format_masks_t  masks;
     char		  *data;
 
-    cairo_format_get_masks (image->format, &bpp, &am, &rm, &gm, &bm);
+    _pixman_format_to_masks (image->pixman_format, &masks);
 
     pf.fourcc = GLITZ_FOURCC_RGB;
-    pf.masks.bpp = bpp;
-    pf.masks.alpha_mask = am;
-    pf.masks.red_mask = rm;
-    pf.masks.green_mask = gm;
-    pf.masks.blue_mask = bm;
+    pf.masks.bpp = masks.bpp;
+    pf.masks.alpha_mask = masks.alpha_mask;
+    pf.masks.red_mask   = masks.red_mask;
+    pf.masks.green_mask = masks.green_mask;
+    pf.masks.blue_mask  = masks.blue_mask;
     pf.xoffset = src_x;
     pf.skip_lines = src_y;
 
     /* check for negative stride */
-    if (image->stride < 0)
-    {
+    if (image->stride < 0) {
 	pf.bytes_per_line = -image->stride;
 	pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
 	data = (char *) image->data + image->stride * (image->height - 1);
-    }
-    else
-    {
+    } else {
 	pf.bytes_per_line = image->stride;
 	pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
 	data = (char *) image->data;
     }
 
     buffer = glitz_buffer_create_for_data (data);
-    if (!buffer)
+    if (buffer == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     glitz_set_pixels (surface->surface,
@@ -473,46 +378,27 @@ _cairo_glitz_surface_clone_similar (void	    *abstract_surface,
     else if (_cairo_surface_is_image (src))
     {
 	cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
-	cairo_content_t	      content;
-	cairo_rectangle_int_t image_extent;
-	cairo_rectangle_int_t extent;
-
-	content = _cairo_content_from_format (image_src->format);
 
 	clone = (cairo_glitz_surface_t *)
-	    _cairo_glitz_surface_create_similar (surface, content,
-						 image_src->width,
-						 image_src->height);
+	    _cairo_glitz_surface_create_similar (surface, src->content,
+						 width, height);
 	if (clone == NULL)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	if (clone->base.status)
 	    return clone->base.status;
 
-	image_extent.x = 0;
-	image_extent.y = 0;
-	image_extent.width = image_src->width;
-	image_extent.height = image_src->height;
-	extent.x = src_x;
-	extent.y = src_y;
-	extent.width = width;
-	extent.height = height;
-
-	if (_cairo_rectangle_intersect (&extent, &image_extent))
-	{
-	    status = _cairo_glitz_surface_set_image (clone, image_src,
-						     extent.x, extent.y,
-						     extent.width, extent.height,
-						     extent.x, extent.y);
-	    if (status) {
-		cairo_surface_destroy (&clone->base);
-		return status;
-	    }
+	status = _cairo_glitz_surface_set_image (clone, image_src,
+					         src_x, src_y,
+						 width, height,
+						 0, 0);
+	if (status) {
+	    cairo_surface_destroy (&clone->base);
+	    return status;
 	}
 
 	*clone_out = &clone->base;
-	*clone_offset_x = 0;
-	*clone_offset_y = 0;
-
+	*clone_offset_x = src_x;
+	*clone_offset_y = src_y;
 	return CAIRO_STATUS_SUCCESS;
     }
 
@@ -1206,8 +1092,6 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 					   cairo_trapezoid_t *traps,
 					   int		     n_traps)
 {
-    cairo_pattern_union_t	     tmp_src_pattern;
-    const cairo_pattern_t	    *src_pattern;
     cairo_glitz_surface_attributes_t attributes;
     cairo_glitz_surface_t	     *dst = abstract_dst;
     cairo_glitz_surface_t	     *src;
@@ -1216,10 +1100,22 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
     void			     *data = NULL;
     cairo_int_status_t		     status;
     unsigned short		     alpha;
-    pixman_trapezoid_t	     	     stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)];
-    pixman_trapezoid_t	     	     *pixman_traps = stack_traps;
+    pixman_trapezoid_t		 stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)];
+    pixman_trapezoid_t		*pixman_traps = stack_traps;
     int i;
 
+    if (antialias != CAIRO_ANTIALIAS_DEFAULT &&
+	antialias != CAIRO_ANTIALIAS_GRAY)
+    {
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+
+    if (op == CAIRO_OPERATOR_SATURATE)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if (_glitz_ensure_target (dst->surface))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
     /* Convert traps to pixman traps */
     if (n_traps > ARRAY_LENGTH (stack_traps)) {
 	pixman_traps = _cairo_malloc_ab (n_traps, sizeof (pixman_trapezoid_t));
@@ -1240,59 +1136,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 	pixman_traps[i].right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
     }
 
-    if (antialias != CAIRO_ANTIALIAS_DEFAULT &&
-	antialias != CAIRO_ANTIALIAS_GRAY)
-    {
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-	goto finish;
-    }
-
-    if (dst->base.status)
-    {
-	status = dst->base.status;
-	goto finish;
-    }
-
-    if (op == CAIRO_OPERATOR_SATURATE)
-    {
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-	goto finish;
-    }
-
-    if (_glitz_ensure_target (dst->surface))
-    {
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-	goto finish;
-    }
-
-    if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
-    {
-	status = _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
-	if (status)
-	    goto finish;
+    status = _cairo_glitz_pattern_acquire_surface (pattern, dst,
+						   src_x, src_y,
+						   width, height,
+						   &src, &attributes);
+    if (status)
+	goto FAIL;
 
-	status = _cairo_glitz_pattern_acquire_surface (&tmp_src_pattern.base,
-						       dst,
-						       src_x, src_y,
-						       width, height,
-						       &src, &attributes);
-	src_pattern = &tmp_src_pattern.base;
-    }
-    else
-    {
-	status = _cairo_glitz_pattern_acquire_surface (pattern, dst,
-						       src_x, src_y,
-						       width, height,
-						       &src, &attributes);
-	src_pattern = pattern;
-    }
     alpha = 0xffff;
 
-    if (status)
-	goto finish;
-
-    if (op == CAIRO_OPERATOR_ADD || n_traps <= 1)
-    {
+    if (op == CAIRO_OPERATOR_ADD || n_traps <= 1) {
 	static const glitz_color_t	clear_black = { 0, 0, 0, 0 };
 	glitz_color_t		color;
 	glitz_geometry_format_t	format;
@@ -1314,19 +1167,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 						 CAIRO_CONTENT_ALPHA,
 						 2, 1);
 	if (mask == NULL) {
-	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
-	    if (src_pattern == &tmp_src_pattern.base)
-		_cairo_pattern_fini (&tmp_src_pattern.base);
-	    status = CAIRO_INT_STATUS_UNSUPPORTED;
-	    goto finish;
+	    status =  CAIRO_INT_STATUS_UNSUPPORTED;
+	    goto FAIL;
 	}
 	if (mask->base.status) {
-	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
-	    if (src_pattern == &tmp_src_pattern.base)
-		_cairo_pattern_fini (&tmp_src_pattern.base);
-
 	    status = mask->base.status;
-	    goto finish;
+	    goto FAIL;
 	}
 
 	color.red = color.green = color.blue = color.alpha = 0xffff;
@@ -1341,21 +1187,15 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 
 	size *= format.vertex.bytes_per_vertex;
 
-	while (n_traps)
-	{
-	    if (data_size < size)
-	    {
+	while (n_traps) {
+	    if (data_size < size) {
 		void *p;
+
 		data_size = size;
 		p = realloc (data, data_size);
-		if (!p)
-		{
-		    _cairo_glitz_pattern_release_surface (src_pattern, src,
-							  &attributes);
-		    if (src_pattern == &tmp_src_pattern.base)
-			_cairo_pattern_fini (&tmp_src_pattern.base);
+		if (p == NULL) {
 		    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-		    goto finish;
+		    goto FAIL;
 		}
 		data = p;
 
@@ -1363,14 +1203,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 		    glitz_buffer_destroy (buffer);
 
 		buffer = glitz_buffer_create_for_data (data);
-		if (!buffer) {
-		    free (data);
-		    _cairo_glitz_pattern_release_surface (src_pattern, src,
-							  &attributes);
-		    if (src_pattern == &tmp_src_pattern.base)
-			_cairo_pattern_fini (&tmp_src_pattern.base);
+		if (buffer == NULL) {
 		    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-		    goto finish;
+		    free (data);
+		    goto FAIL;
 		}
 	    }
 
@@ -1392,22 +1228,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 	glitz_set_array (dst->surface, 0, 3,
 			 offset / format.vertex.bytes_per_vertex,
 			 0, 0);
-    }
-    else
-    {
+    } else {
 	cairo_image_surface_t *image;
 	unsigned char	      *ptr;
 	int		      stride;
 
 	stride = (width + 3) & -4;
 	data = calloc (stride, height);
-	if (!data)
-	{
-	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
-	    if (src_pattern == &tmp_src_pattern.base)
-		_cairo_pattern_fini (&tmp_src_pattern.base);
+	if (data == NULL) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    goto finish;
+	    goto FAIL;
 	}
 
 	/* using negative stride */
@@ -1418,12 +1248,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 						 CAIRO_FORMAT_A8,
 						 width, height,
 						 -stride);
-	if (image->base.status)
-	{
-	    cairo_surface_destroy (&src->base);
+	status = image->base.status;
+	if (status) {
 	    free (data);
-	    status = image->base.status;
-	    goto finish;
+	    goto FAIL;
 	}
 
 	pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
@@ -1433,21 +1261,20 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 	    _cairo_surface_create_similar_scratch (&dst->base,
 						   CAIRO_CONTENT_ALPHA,
 						   width, height);
-	if (mask->base.status) {
-	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
+	status = mask->base.status;
+	if (status) {
 	    free (data);
 	    cairo_surface_destroy (&image->base);
-	    status = mask->base.status;
-	    goto finish;
+	    goto FAIL;
 	}
 
 	status = _cairo_glitz_surface_set_image (mask, image,
 		                                 0, 0, width, height, 0, 0);
 
-	cairo_surface_destroy(&image->base);
+	cairo_surface_destroy (&image->base);
 
 	if (status)
-	    goto finish;
+	    goto FAIL;
     }
 
     _cairo_glitz_surface_set_attributes (src, &attributes);
@@ -1474,18 +1301,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 
     free (data);
 
-    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
+    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED) {
 	status = CAIRO_INT_STATUS_UNSUPPORTED;
+	goto FAIL;
+    }
 
-    if (status == CAIRO_STATUS_SUCCESS && ! _cairo_operator_bounded_by_mask (op))
-    {
-	int src_width, src_height;
-
-	src_width = glitz_surface_get_width (src->surface);
-	src_height = glitz_surface_get_height (src->surface);
+    if (! _cairo_operator_bounded_by_mask (op)) {
 	status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
 								 &attributes.base,
-								 src_width, src_height,
+								 glitz_surface_get_width  (src->surface),
+								 glitz_surface_get_height (src->surface),
 								 width, height,
 								 src_x, src_y,
 								 0, 0,
@@ -1493,14 +1318,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 								 width, height);
     }
 
-    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
-    if (src_pattern == &tmp_src_pattern.base)
-	_cairo_pattern_fini (&tmp_src_pattern.base);
+FAIL:
+    _cairo_glitz_pattern_release_surface (pattern, src, &attributes);
 
-    if (mask)
+    if (mask != NULL)
 	cairo_surface_destroy (&mask->base);
 
-finish:
     if (pixman_traps != stack_traps)
 	free (pixman_traps);
 
@@ -1513,33 +1336,23 @@ _cairo_glitz_surface_set_clip_region (void		*abstract_surface,
 {
     cairo_glitz_surface_t *surface = abstract_surface;
 
-    if (region)
-    {
-	glitz_box_t *box;
-	int	    n;
+    if (region != NULL) {
 	cairo_status_t status;
 
-	status = _cairo_glitz_get_boxes_from_region (region, &box, &n);
+	status = _cairo_glitz_get_boxes_from_region (region,
+						     &surface->clip_boxes,
+						     &surface->num_clip_boxes);
 	if (status)
-	    return status;
-
-	if (surface->has_clip)
-	    free (surface->clip_boxes);
-
-	glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
+            return status;
 
+	glitz_surface_set_clip_region (surface->surface,
+				       0, 0,
+				       surface->clip_boxes,
+				       surface->num_clip_boxes);
 	surface->has_clip = TRUE;
-	surface->clip_boxes = box;
-	surface->num_clip_boxes = n;
-    }
-    else
-    {
+    } else {
 	glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
-
-	if (surface->has_clip) {
-	    free (surface->clip_boxes);
-	    surface->has_clip = FALSE;
-        }
+	surface->has_clip = FALSE;
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -1553,7 +1366,7 @@ _cairo_glitz_surface_get_extents (void		          *abstract_surface,
 
     rectangle->x = 0;
     rectangle->y = 0;
-    rectangle->width = glitz_surface_get_width  (surface->surface);
+    rectangle->width  = glitz_surface_get_width  (surface->surface);
     rectangle->height = glitz_surface_get_height (surface->surface);
 
     return CAIRO_STATUS_SUCCESS;
@@ -2535,14 +2348,17 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
 
     format = glitz_surface_get_format (surface);
     _cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend,
-			 _glitz_format_to_content(format));
+			 _glitz_format_to_content (format));
 
     glitz_surface_reference (surface);
 
     crsurface->surface  = surface;
     crsurface->format   = format;
-    crsurface->has_clip = FALSE;
 
-    return (cairo_surface_t *) crsurface;
+    crsurface->has_clip       = FALSE;
+    crsurface->clip_boxes     = NULL;
+    crsurface->num_clip_boxes = 0;
+
+    return &crsurface->base;
 }
 slim_hidden_def (cairo_glitz_surface_create);
commit 47275c7ece06c0d02f2d7c9aa81d87a7144392b0
Author: Paolo Bonzini <bonzini at gnu.org>
Date:   Wed Nov 26 15:56:48 2008 +0100

    [test] Fix glitz-surface-source test
    
    The recent changes to separate glitz/agl broke the compilation of the
    glitz-surface-source test.

diff --git a/test/glitz-surface-source.c b/test/glitz-surface-source.c
index 2dfa735..89094e4 100644
--- a/test/glitz-surface-source.c
+++ b/test/glitz-surface-source.c
@@ -25,8 +25,6 @@
 
 #include "cairo-test.h"
 #include <cairo-glitz.h>
-#include <cairo-xlib.h>
-#include <cairo-xlib-xrender.h>
 
 #define NAME "glitz"
 #include "surface-source.c"
@@ -34,6 +32,8 @@
 static cairo_user_data_key_t closure_key;
 
 #if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE
+#include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
 #include <glitz-glx.h>
 
 struct closure {
@@ -198,4 +198,96 @@ create_source_surface (int size)
 
     return surface;
 }
+
+#elif CAIRO_CAN_TEST_GLITZ_AGL_SURFACE
+#include <glitz-agl.h>
+
+static void
+cleanup (void *data)
+{
+    glitz_agl_fini ();
+}
+
+static glitz_surface_t *
+_glitz_agl_create_surface (glitz_format_name_t           formatname,
+                          int                            width,
+                          int                            height)
+{
+    glitz_drawable_format_t * dformat = NULL;
+    glitz_drawable_t        * drawable = NULL;
+    glitz_format_t          * format;
+    glitz_format_t           templ;
+    glitz_surface_t         * sr;
+    int                              i;
+    int                              alpha_size;
+
+    glitz_agl_init ();
+
+    /* Find a reasonably lame window format and use it to create a pbuffer.  */
+    i = 0;
+    alpha_size = (formatname == GLITZ_STANDARD_ARGB32) ? 8 : 0;
+    while ((dformat = glitz_agl_find_window_format (0, 0, i)) != NULL
+            && !(dformat->doublebuffer == 0
+                 && dformat->stencil_size == 0
+                 && dformat->depth_size == 0
+                && dformat->color.fourcc == GLITZ_FOURCC_RGB
+                && dformat->color.alpha_size == alpha_size))
+        i++;
+
+    if (!dformat)
+       goto FAIL;
+
+    /* Try for a pbuffer first */
+    drawable = glitz_agl_create_pbuffer_drawable (dformat, width, height);
+    if (!drawable)
+       goto FAIL;
+
+    templ.color = dformat->color;
+    format = glitz_find_format (drawable,
+                                GLITZ_FORMAT_FOURCC_MASK     |
+                                GLITZ_FORMAT_RED_SIZE_MASK   |
+                                GLITZ_FORMAT_GREEN_SIZE_MASK |
+                                GLITZ_FORMAT_BLUE_SIZE_MASK  |
+                                GLITZ_FORMAT_ALPHA_SIZE_MASK,
+                                &templ,
+                                0);
+    if (!format) {
+        fprintf (stderr, "Error: couldn't find surface format\n");
+        return NULL;
+    }
+
+    sr = glitz_surface_create (drawable, format, width, height, 0, NULL);
+    if (!sr)
+       goto DESTROY_DRAWABLE;
+
+    glitz_surface_attach (sr, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
+    glitz_drawable_destroy (drawable);
+
+    return sr;
+ DESTROY_DRAWABLE:
+    glitz_drawable_destroy (drawable);
+ FAIL:
+    return NULL;
+}
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+    glitz_surface_t  *glitz_surface;
+    cairo_surface_t *surface;
+
+    glitz_surface = _glitz_agl_create_surface (GLITZ_STANDARD_ARGB32,
+                                              size, size);
+
+    surface = cairo_glitz_surface_create (glitz_surface);
+    cairo_surface_set_user_data (surface, &closure_key, NULL, cleanup);
+    return surface;
+}
 #endif
+
+CAIRO_TEST (glitz_surface_source,
+	    "Test using a Glitz surface as the source",
+	    "source", /* keywords */
+	    NULL, /* requirements */
+	    SIZE, SIZE,
+	    preamble, draw)
diff --git a/test/glitz-surface-source.ps2.ref.png b/test/glitz-surface-source.ps2.ref.png
new file mode 100644
index 0000000..1023158
Binary files /dev/null and b/test/glitz-surface-source.ps2.ref.png differ
diff --git a/test/glitz-surface-source.ps3.ref.png b/test/glitz-surface-source.ps3.ref.png
new file mode 100644
index 0000000..1023158
Binary files /dev/null and b/test/glitz-surface-source.ps3.ref.png differ
commit a84ea7829065b7e1d33d6fed6bcf0c7c8abd383a
Author: Paolo Bonzini <bonzini at gnu.org>
Date:   Wed Nov 26 15:49:00 2008 +0100

    [test] Add quartz-surface-source test
    
    Add a simple test to exercise using a Quartz surface as a source.

diff --git a/test/Makefile.am b/test/Makefile.am
index 9c664b1..9534198 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -212,7 +212,11 @@ test_sources += ft-text-vertical-layout-type3.c
 test_sources += ft-text-antialias-none.c
 endif
 
-# Need to add win32-surface-source, quartz-surface-source
+# Need to add quartz-surface-source
+if CAIRO_HAS_QUARTZ_SURFACE
+test_sources += quartz-surface-source.c
+endif
+
 if CAIRO_HAS_GLITZ_SURFACE
 test_sources += glitz-surface-source.c
 endif
diff --git a/test/quartz-surface-source.c b/test/quartz-surface-source.c
new file mode 100644
index 0000000..b0c86d0
--- /dev/null
+++ b/test/quartz-surface-source.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include "cairo-quartz.h"
+
+#include "surface-source.c"
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+    return cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, size, size);
+}
+
+CAIRO_TEST (quartz_surface_source,
+	    "Test using a Quartz surface as the source",
+	    "source", /* keywords */
+	    NULL, /* requirements */
+	    SIZE, SIZE,
+	    preamble, draw)
diff --git a/test/quartz-surface-source.ps2.ref.png b/test/quartz-surface-source.ps2.ref.png
new file mode 100644
index 0000000..1023158
Binary files /dev/null and b/test/quartz-surface-source.ps2.ref.png differ
diff --git a/test/quartz-surface-source.ps3.ref.png b/test/quartz-surface-source.ps3.ref.png
new file mode 100644
index 0000000..1023158
Binary files /dev/null and b/test/quartz-surface-source.ps3.ref.png differ
diff --git a/test/quartz-surface-source.ref.png b/test/quartz-surface-source.ref.png
new file mode 100644
index 0000000..9fbbedd
Binary files /dev/null and b/test/quartz-surface-source.ref.png differ
commit 993941cfd701eb222b81cdddeabf6f7ff2daa150
Author: Paolo Bonzini <bonzini at gnu.org>
Date:   Wed Nov 26 13:32:11 2008 +0000

    [perf] Fix SDL compilation for MacOS X
    
    The attached patch makes the SDL tests compile under Mac OS X.  The
    problem is:
    
    1) that <SDL_main.h> should be included in files that define the main
    function for SDL Mac OS X programs (this is not true with the upcoming
    SDL 1.3 release).
    
    2) that -lSDLmain, because it is statically linked, needs the Cocoa
    framework in the LDADD of the main program.  Again, 1.3 will not require
    this.

diff --git a/perf/Makefile.am b/perf/Makefile.am
index 737e96a..18eed9f 100644
--- a/perf/Makefile.am
+++ b/perf/Makefile.am
@@ -55,6 +55,10 @@ cairo_perf_SOURCES += cairo-perf-posix.c
 endif
 endif
 
+if CAIRO_HAS_SDL_SURFACE
+cairo_perf_LDADD = $(LDADD) $(sdl_LIBS)
+endif
+
 libcairoperf_la_SOURCES = \
 	cairo-perf-report.c	\
 	cairo-stats.c		\
diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c
index d5f6920..c96e6c2 100644
--- a/perf/cairo-perf.c
+++ b/perf/cairo-perf.c
@@ -33,6 +33,10 @@
 
 #include "cairo-boilerplate-getopt.h"
 
+#if CAIRO_HAS_SDL_SURFACE
+#include <SDL_main.h>
+#endif
+
 /* For basename */
 #ifdef HAVE_LIBGEN_H
 #include <libgen.h>
diff --git a/test/Makefile.am b/test/Makefile.am
index 3afac51..9c664b1 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -294,6 +294,10 @@ if HAVE_PTHREAD
 cairo_test_suite_LDADD += -lpthread
 endif
 
+if CAIRO_HAS_SDL_SURFACE
+cairo_test_suite_LDADD += $(sdl_LIBS)
+endif
+
 BUILT_SOURCES += cairo-test-constructors.c
 noinst_SCRIPTS = make-cairo-test-constructors.pl
 EXTRA_DIST += $(BUILT_SOURCES) $(noinst_SCRIPTS) COPYING
diff --git a/test/cairo-test-runner.c b/test/cairo-test-runner.c
index 4fb0cbe..aec90ff 100644
--- a/test/cairo-test-runner.c
+++ b/test/cairo-test-runner.c
@@ -33,6 +33,10 @@
 #undef CAIRO_VERSION_MICRO
 #include "../cairo-version.h"
 
+#if CAIRO_HAS_SDL_SURFACE
+#include <SDL_main.h>
+#endif
+
 #include <pixman.h> /* for version information */
 
 #if HAVE_FORK && HAVE_WAITPID
commit 8a5b55ca6c69671a138f65ab15bcf93163f24a37
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 26 13:26:40 2008 +0000

    [matrix] Impose a maximum number of refinement iterations
    
    Ensure we do not loop forever trying to minimise the error between the
    pixman and cairo matrices - for instance when the FPU is not running at
    full precision.

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 0558983..6dfe537 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -879,6 +879,7 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
         *pixman_transform = pixman_identity_transform;
     } else {
         cairo_matrix_t inv;
+	unsigned max_iterations;
 
         pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
         pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
@@ -913,6 +914,7 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
 
         /* find the pattern space coordinate that maps to (xc, yc) */
 	xc += .5; yc += .5; /* offset for the pixel centre */
+	max_iterations = 5;
 	do {
 	    double x,y;
 	    pixman_vector_t vector;
@@ -942,6 +944,6 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
 
 	    if (dx == 0 && dy == 0)
 		break;
-	} while (TRUE);
+	} while (--max_iterations);
     }
 }
commit 4218699642c621eb3098a5251ef88d8c7d8a96d2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 26 11:54:29 2008 +0000

    [skiplist] Use ffs()
    
    Use ffs() [find-first-set-bit] instead of open-coding, which is about 25%
    faster on my test machine.

diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c
index b08453b..5f46ec0 100644
--- a/src/cairo-skiplist.c
+++ b/src/cairo-skiplist.c
@@ -91,20 +91,11 @@ _cairo_skip_list_fini (cairo_skip_list_t *list)
 static int
 random_level (void)
 {
-    int	level = 0;
     /* tricky bit -- each bit is '1' 75% of the time.
      * This works because we only use the lower MAX_LEVEL
      * bits, and MAX_LEVEL < 16 */
     uint32_t bits = hars_petruska_f54_1_random ();
-    bits |= bits >> 16;
-
-    while (++level < MAX_LEVEL)
-    {
-	if (bits & 1)
-	    break;
-	bits >>= 1;
-    }
-    return level;
+    return ffs (-(1<<MAX_LEVEL) | bits | bits >> 16);
 }
 
 static void *


More information about the cairo-commit mailing list