[cairo-commit] cairo/src cairo-glitz-surface.c,1.47,1.48

David Reveman commit at pdx.freedesktop.org
Mon Jul 4 03:58:46 PDT 2005


Committed by: davidr

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv819/src

Modified Files:
	cairo-glitz-surface.c 
Log Message:
Use frame buffer objects for accelerated offscreen drawing in glitz backend

Index: cairo-glitz-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-glitz-surface.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- cairo-glitz-surface.c	17 Jun 2005 20:25:19 -0000	1.47
+++ cairo-glitz-surface.c	4 Jul 2005 10:58:44 -0000	1.48
@@ -440,73 +440,18 @@
     return CAIRO_OPERATOR_XOR;
 }
 
+#define CAIRO_GLITZ_FEATURE_OK(surface, name)				  \
+    (glitz_drawable_get_features (glitz_surface_get_drawable (surface)) & \
+     (GLITZ_FEATURE_ ## name ## _MASK))
+
 static glitz_status_t
 _glitz_ensure_target (glitz_surface_t *surface)
 {
-    glitz_drawable_t *drawable;
-
-    drawable = glitz_surface_get_attached_drawable (surface);
-    if (!drawable) {
-	glitz_drawable_format_t *dformat;
-	glitz_drawable_format_t templ;
-	glitz_format_t *format;
-	glitz_drawable_t *pbuffer;
-	unsigned long mask;
-	int i;
-	
-	format = glitz_surface_get_format (surface);
-	if (format->type != GLITZ_FORMAT_TYPE_COLOR)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
-	drawable = glitz_surface_get_drawable (surface);
-	dformat = glitz_drawable_get_format (drawable);
-
-	templ.types.pbuffer = 1;
-	mask = GLITZ_FORMAT_PBUFFER_MASK;
-
-	templ.samples = dformat->samples;
-	mask |= GLITZ_FORMAT_SAMPLES_MASK;
-
-	i = 0;
-	do {
-	    dformat = glitz_find_similar_drawable_format (drawable,
-							  mask, &templ, i++);
-
-	    if (dformat) {
-		int sufficient = 1;
-		
-		if (format->color.red_size) {
-		    if (dformat->color.red_size < format->color.red_size)
-			sufficient = 0;
-		}
-		if (format->color.alpha_size) {
-		    if (dformat->color.alpha_size < format->color.alpha_size)
-			sufficient = 0;
-		}
-
-		if (sufficient)
-		    break;
-	    }
-	} while (dformat);
-	
-	if (!dformat)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
-	pbuffer =
-	    glitz_create_pbuffer_drawable (drawable, dformat,
-					   glitz_surface_get_width (surface),
-					   glitz_surface_get_height (surface));
-	if (!pbuffer)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
-	glitz_surface_attach (surface, pbuffer,
-			      GLITZ_DRAWABLE_BUFFER_FRONT_COLOR,
-			      0, 0);
-
-	glitz_drawable_destroy (pbuffer);
-    }
+    if (glitz_surface_get_attached_drawable (surface) ||
+	CAIRO_GLITZ_FEATURE_OK (surface, FRAMEBUFFER_OBJECT))
+	return CAIRO_STATUS_SUCCESS;
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_UNSUPPORTED;
 }
 
 typedef struct _cairo_glitz_surface_attributes {
@@ -536,13 +481,26 @@
     switch (pattern->type) {
     case CAIRO_PATTERN_LINEAR:
     case CAIRO_PATTERN_RADIAL: {
-	cairo_gradient_pattern_t *gradient =
+	cairo_gradient_pattern_t    *gradient =
 	    (cairo_gradient_pattern_t *) pattern;
-	glitz_drawable_t	 *drawable;
-	glitz_fixed16_16_t	 *params;
-	int			 n_params;
-	int			 i;
-	unsigned short		 alpha;
+	char			    *data;
+	glitz_fixed16_16_t	    *params;
+	int			    n_params;
+	unsigned int		    *pixels;
+	int			    i;
+	unsigned char		    alpha;
+	glitz_buffer_t		    *buffer;
+	static glitz_pixel_format_t format = {
+            {
+                32,
+                0xff000000,
+                0x00ff0000,
+                0x0000ff00,
+                0x000000ff
+            },
+            0, 0, 0,
+            GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
+        };
 	
 	/* XXX: the current color gradient acceleration provided by glitz is
 	 * experimental, it's been proven inappropriate in a number of ways,
@@ -565,22 +523,20 @@
 		break;
 	}
 
-	drawable = glitz_surface_get_drawable (dst->surface);
-	if (!(glitz_drawable_get_features (drawable) &
-	      GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK))
+	if (!CAIRO_GLITZ_FEATURE_OK (dst->surface, FRAGMENT_PROGRAM))
 	    break;
-
+	
 	if (pattern->filter != CAIRO_FILTER_BILINEAR &&
 	    pattern->filter != CAIRO_FILTER_GOOD &&
 	    pattern->filter != CAIRO_FILTER_BEST)
 	    break;
 
-	alpha = (gradient->stops[0].color.alpha) * 0xffff;
+	alpha = gradient->stops[0].color.alpha * 0xff;
 	for (i = 1; i < gradient->n_stops; i++)
 	{
-	    unsigned short a;
+	    unsigned char a;
 	    
-	    a = (gradient->stops[i].color.alpha) * 0xffff;
+	    a = gradient->stops[i].color.alpha * 0xff;
 	    if (a != alpha)
 		break;
 	}
@@ -592,35 +548,51 @@
 
 	n_params = gradient->n_stops * 3 + 4;
 
-	params = malloc (sizeof (glitz_fixed16_16_t) * n_params);
-	if (!params)
+	data = malloc (sizeof (glitz_fixed16_16_t) * n_params +
+		       sizeof (unsigned int) * gradient->n_stops);
+	if (!data)
 	    return CAIRO_STATUS_NO_MEMORY;
 
+	params = (glitz_fixed16_16_t *) data;
+	pixels = (unsigned int *)
+	    (data + sizeof (glitz_fixed16_16_t) * n_params);
+
+	buffer = glitz_buffer_create_for_data (pixels);
+	if (!buffer)
+	{
+	    free (data);
+	    return CAIRO_STATUS_NO_MEMORY;
+	}
+	
 	src = (cairo_glitz_surface_t *)
 	    _cairo_surface_create_similar_scratch (&dst->base,
 						   CAIRO_FORMAT_ARGB32,
 						   gradient->n_stops, 1);
 	if (!src)
 	{
-	    free (params);
+	    glitz_buffer_destroy (buffer);
+	    free (data);
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
 
-	for (i = 0; i < gradient->n_stops; i++) {
-	    glitz_color_t color;
-
-	    color.red   = gradient->stops[i].color.red   * alpha;
-	    color.green = gradient->stops[i].color.green * alpha;
-	    color.blue  = gradient->stops[i].color.blue  * alpha;
-	    color.alpha = alpha;
-
-	    glitz_set_rectangle (src->surface, &color, i, 0, 1, 1);
-
+	for (i = 0; i < gradient->n_stops; i++)
+	{
+	    pixels[i] =
+                (((int) alpha) << 24)                                  |
+                (((int) gradient->stops[i].color.red   * alpha) << 16) |
+                (((int) gradient->stops[i].color.green * alpha) << 8)  |
+                (((int) gradient->stops[i].color.blue  * alpha));
+	    
 	    params[4 + 3 * i] = gradient->stops[i].offset;
 	    params[5 + 3 * i] = i << 16;
 	    params[6 + 3 * i] = 0;
 	}
 
+	glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1,
+			  &format, buffer);
+
+	glitz_buffer_destroy (buffer);
+
 	if (pattern->type == CAIRO_PATTERN_LINEAR)
 	{
 	    cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
@@ -910,10 +882,6 @@
 	glitz_color.blue = color->blue_short;
 	glitz_color.alpha = color->alpha_short;
 
-	if (glitz_surface_get_width (dst->surface) != 1 ||
-	    glitz_surface_get_height (dst->surface) != 1)
-	    _glitz_ensure_target (dst->surface);
-	
 	glitz_set_rectangles (dst->surface, &glitz_color,
 			      (glitz_rectangle_t *) rects, n_rects);
     }
@@ -1452,7 +1420,7 @@
 					     width, height,
 					     kick_out, closure);
 	    if (status == CAIRO_STATUS_SUCCESS)
-		return CAIRO_STATUS_SUCCESS;
+                return CAIRO_STATUS_SUCCESS;
 	}
     } break;
     case CAIRO_GLITZ_AREA_DIVIDED: {




More information about the cairo-commit mailing list