[PATCH] Fix glitz backend

Peter Clifton pcjc2 at cam.ac.uk
Tue Jul 22 04:23:58 PDT 2008


---
 src/cairo-glitz-surface.c |  152 ++++++++++++++++++++++++++++++++-------------
 1 files changed, 109 insertions(+), 43 deletions(-)

diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 44e560c..671440b 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -576,17 +576,17 @@ _cairo_glitz_surface_set_matrix (cairo_glitz_surface_t *surface,
 {
     glitz_transform_t transform;
 
-    transform.matrix[0][0] = _cairo_fixed_from_double (matrix->xx);
-    transform.matrix[0][1] = _cairo_fixed_from_double (matrix->xy);
-    transform.matrix[0][2] = _cairo_fixed_from_double (matrix->x0);
+    transform.matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
+    transform.matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
+    transform.matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
 
-    transform.matrix[1][0] = _cairo_fixed_from_double (matrix->yx);
-    transform.matrix[1][1] = _cairo_fixed_from_double (matrix->yy);
-    transform.matrix[1][2] = _cairo_fixed_from_double (matrix->y0);
+    transform.matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx);
+    transform.matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy);
+    transform.matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0);
 
     transform.matrix[2][0] = 0;
     transform.matrix[2][1] = 0;
-    transform.matrix[2][2] = _cairo_fixed_from_double (1);
+    transform.matrix[2][2] = _cairo_fixed_16_16_from_double (1);
 
     glitz_surface_set_transform (surface->surface, &transform);
 }
@@ -823,7 +823,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t	              *pattern,
 	}
 
 	glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1,
-			  (glitz_pixel_format_t *)&format, buffer);
+			  &format, buffer);
 
 	glitz_buffer_destroy (buffer);
 
@@ -831,22 +831,22 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t	              *pattern,
 	{
 	    cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
 
-	    params[0] = grad->p1.x;
-	    params[1] = grad->p1.y;
-	    params[2] = grad->p2.x;
-	    params[3] = grad->p2.y;
+	    params[0] = _cairo_fixed_to_16_16 (grad->p1.x);
+	    params[1] = _cairo_fixed_to_16_16 (grad->p1.y);
+	    params[2] = _cairo_fixed_to_16_16 (grad->p2.x);
+	    params[3] = _cairo_fixed_to_16_16 (grad->p2.y);
 	    attr->filter = GLITZ_FILTER_LINEAR_GRADIENT;
 	}
 	else
 	{
 	    cairo_radial_pattern_t *grad = (cairo_radial_pattern_t *) pattern;
 
-	    params[0] = grad->c1.x;
-	    params[1] = grad->c1.y;
-	    params[2] = grad->r1;
-	    params[3] = grad->c2.x;
-	    params[4] = grad->c2.y;
-	    params[5] = grad->r2;
+	    params[0] = _cairo_fixed_to_16_16 (grad->c1.x);
+	    params[1] = _cairo_fixed_to_16_16 (grad->c1.y);
+	    params[2] = _cairo_fixed_to_16_16 (grad->r1);
+	    params[3] = _cairo_fixed_to_16_16 (grad->c2.x);
+	    params[4] = _cairo_fixed_to_16_16 (grad->c2.y);
+	    params[5] = _cairo_fixed_to_16_16 (grad->r2);
 	    attr->filter = GLITZ_FILTER_RADIAL_GRADIENT;
 	}
 
@@ -867,7 +867,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t	              *pattern,
 
 	attr->params	    = params;
 	attr->n_params	    = n_params;
-	attr->base.matrix   = pattern->matrix;
+	attr->base.matrix   = pattern->matrix; /* CHECK */
 	attr->base.x_offset = 0;
 	attr->base.y_offset = 0;
     } break;
@@ -1124,6 +1124,24 @@ _cairo_glitz_surface_fill_rectangles (void		      *abstract_dst,
 {
     cairo_glitz_surface_t *dst = abstract_dst;
     cairo_glitz_surface_t *src;
+    cairo_status_t                   status = CAIRO_STATUS_SUCCESS;
+    glitz_rectangle_t		     stack_rects[CAIRO_STACK_ARRAY_LENGTH (glitz_rectangle_t)];
+    glitz_rectangle_t		     *glitz_rects = stack_rects;
+    int                              i;
+
+    /* Convert rects to glitz rects */
+    if (n_rects > ARRAY_LENGTH (stack_rects)) {
+	glitz_rects = _cairo_malloc_ab (n_rects, sizeof (glitz_rectangle_t));
+	if (glitz_rects == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    }
+
+    for (i = 0; i < n_rects; i++) {
+	glitz_rects[i].x = rects[i].x;
+	glitz_rects[i].y = rects[i].y;
+	glitz_rects[i].width = rects[i].width;
+	glitz_rects[i].height = rects[i].height;
+    }
 
     switch (op) {
     case CAIRO_OPERATOR_SOURCE: {
@@ -1135,16 +1153,17 @@ _cairo_glitz_surface_fill_rectangles (void		      *abstract_dst,
 	glitz_color.alpha = color->alpha_short;
 
 	glitz_set_rectangles (dst->surface, &glitz_color,
-			      (glitz_rectangle_t *) rects, n_rects);
+			      glitz_rects, n_rects);
     } break;
     case CAIRO_OPERATOR_CLEAR: {
 	static const glitz_color_t glitz_color = { 0, 0, 0, 0 };
 
 	glitz_set_rectangles (dst->surface, &glitz_color,
-			      (glitz_rectangle_t *) rects, n_rects);
+			      glitz_rects, n_rects);
     } break;
     case CAIRO_OPERATOR_SATURATE:
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+        status = CAIRO_INT_STATUS_UNSUPPORTED;
+        goto finish;
     case CAIRO_OPERATOR_OVER:
     case CAIRO_OPERATOR_IN:
     case CAIRO_OPERATOR_OUT:
@@ -1157,8 +1176,10 @@ _cairo_glitz_surface_fill_rectangles (void		      *abstract_dst,
     case CAIRO_OPERATOR_XOR:
     case CAIRO_OPERATOR_ADD:
     default:
-	if (_glitz_ensure_target (dst->surface))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	if (_glitz_ensure_target (dst->surface)) {
+            status = CAIRO_INT_STATUS_UNSUPPORTED;
+            goto finish;
+        }
 
 	src = (cairo_glitz_surface_t *)
 	    _cairo_surface_create_similar_solid (&dst->base,
@@ -1166,8 +1187,10 @@ _cairo_glitz_surface_fill_rectangles (void		      *abstract_dst,
 						 1, 1,
 						 (cairo_color_t *) color,
 						 NULL);
-	if (src->base.status)
-	    return src->base.status;
+	if (src->base.status) {
+            status = src->base.status;
+            goto finish;
+        }
 
 	glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
 
@@ -1188,10 +1211,16 @@ _cairo_glitz_surface_fill_rectangles (void		      *abstract_dst,
 	break;
     }
 
-    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED) {
+        status = CAIRO_INT_STATUS_UNSUPPORTED;
+        goto finish;
+    }
 
-    return CAIRO_STATUS_SUCCESS;
+finish:
+    if (glitz_rects != stack_rects)
+	free (glitz_rects);
+
+    return status;
 }
 
 static cairo_int_status_t
@@ -1216,8 +1245,11 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
     cairo_glitz_surface_t	     *mask = NULL;
     glitz_buffer_t		     *buffer = NULL;
     void			     *data = NULL;
-    cairo_int_status_t		     status;
+    cairo_int_status_t		     status = CAIRO_STATUS_SUCCESS;
     unsigned short		     alpha;
+    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)
@@ -1258,6 +1290,26 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
     if (status)
 	return status;
 
+    /* Convert traps to pixman traps (same as glitz traps) */
+    if (n_traps > ARRAY_LENGTH (stack_traps)) {
+	pixman_traps = _cairo_malloc_ab (n_traps, sizeof (pixman_trapezoid_t));
+	if (pixman_traps == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    }
+
+    for (i = 0; i < n_traps; i++) {
+	pixman_traps[i].top = _cairo_fixed_to_16_16 (traps[i].top);
+	pixman_traps[i].bottom = _cairo_fixed_to_16_16 (traps[i].bottom);
+	pixman_traps[i].left.p1.x = _cairo_fixed_to_16_16 (traps[i].left.p1.x);
+	pixman_traps[i].left.p1.y = _cairo_fixed_to_16_16 (traps[i].left.p1.y);
+	pixman_traps[i].left.p2.x = _cairo_fixed_to_16_16 (traps[i].left.p2.x);
+	pixman_traps[i].left.p2.y = _cairo_fixed_to_16_16 (traps[i].left.p2.y);
+	pixman_traps[i].right.p1.x = _cairo_fixed_to_16_16 (traps[i].right.p1.x);
+	pixman_traps[i].right.p1.y = _cairo_fixed_to_16_16 (traps[i].right.p1.y);
+	pixman_traps[i].right.p2.x = _cairo_fixed_to_16_16 (traps[i].right.p2.x);
+	pixman_traps[i].right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
+    }
+
     if (op == CAIRO_OPERATOR_ADD || n_traps <= 1)
     {
 	static const glitz_color_t	clear_black = { 0, 0, 0, 0 };
@@ -1286,7 +1338,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 	    if (src_pattern == &tmp_src_pattern.base)
 		_cairo_pattern_fini (&tmp_src_pattern.base);
 
-	    return mask->base.status;
+	    status = mask->base.status;
+            goto finish;
 	}
 
 	color.red = color.green = color.blue = color.alpha = 0xffff;
@@ -1314,7 +1367,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 							  &attributes);
 		    if (src_pattern == &tmp_src_pattern.base)
 			_cairo_pattern_fini (&tmp_src_pattern.base);
-		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+		    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+                    goto finish;
 		}
 		data = p;
 
@@ -1328,7 +1382,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 							  &attributes);
 		    if (src_pattern == &tmp_src_pattern.base)
 			_cairo_pattern_fini (&tmp_src_pattern.base);
-		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+		    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+                    goto finish;
 		}
 	    }
 
@@ -1336,7 +1391,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 		glitz_add_trapezoids (buffer,
 				      offset, size - offset,
 				      format.vertex.type, mask->surface,
-				      (glitz_trapezoid_t *) traps, n_traps,
+				      (glitz_trapezoid_t *) pixman_traps, n_traps,
 				      &n_trap_added);
 
 	    n_traps -= n_trap_added;
@@ -1364,7 +1419,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
 	    if (src_pattern == &tmp_src_pattern.base)
 		_cairo_pattern_fini (&tmp_src_pattern.base);
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+            goto finish;
 	}
 
 	/* using negative stride */
@@ -1379,11 +1435,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 	{
 	    cairo_surface_destroy (&src->base);
 	    free (data);
-	    return image->base.status;
+	    status = image->base.status;
+            goto finish;
 	}
 
 	pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
-                               n_traps, (pixman_trapezoid_t *) traps);
+                               n_traps, pixman_traps);
 
 	mask = (cairo_glitz_surface_t *)
 	    _cairo_surface_create_similar_scratch (&dst->base,
@@ -1394,7 +1451,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
 	    free (data);
 	    cairo_surface_destroy (&image->base);
-	    return mask->base.status;
+	    status = mask->base.status;
+            goto finish;
 	}
 
 	status = _cairo_glitz_surface_set_image (mask, image,
@@ -1402,8 +1460,9 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 
 	cairo_surface_destroy(&image->base);
 
-	if (status)
-	    return status;
+	if (status) {
+	    goto finish;
+        }
     }
 
     _cairo_glitz_surface_set_attributes (src, &attributes);
@@ -1437,10 +1496,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
     if (mask)
 	cairo_surface_destroy (&mask->base);
 
-    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED) {
+      status = CAIRO_INT_STATUS_UNSUPPORTED;
+      goto finish;
+    }
 
-    return CAIRO_STATUS_SUCCESS;
+ finish:
+    if (pixman_traps != stack_traps)
+	free (pixman_traps);
+
+    return status;
 }
 
 static cairo_int_status_t
@@ -2083,6 +2148,7 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
     glitz_surface_translate_point (font_private->surface, &p1, &p1);
     glitz_surface_translate_point (font_private->surface, &p2, &p2);
 
+    /* THESE ARE OK BECAUSE THIS FIXED_TO_FLOAT WORKS ON GLITZ FIXED FORMAT */
     glyph_private->p1.x = FIXED_TO_FLOAT (p1.x);
     glyph_private->p1.y = FIXED_TO_FLOAT (p1.y);
     glyph_private->p2.x = FIXED_TO_FLOAT (p2.x);
-- 
1.5.4.3


--=-+W4jPHGkSJHEXQ/JQYXP--



More information about the cairo mailing list