pixman: Branch 'master' - 4 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Wed Jun 20 09:13:10 PDT 2007


 pixman/pixman-image.c   |  102 ++++++++++++++++++++++++
 pixman/pixman-pict.c    |  197 +++++++++++++++++++++++++++++++++++++++++++++---
 pixman/pixman-private.h |    1 
 pixman/pixman-utils.c   |    5 +
 4 files changed, 294 insertions(+), 11 deletions(-)

New commits:
diff-tree 3dbb2a56bd1918595091006c6e0de5260d43af09 (from 658acaad4e73ac705f705f947a42a2cd0979042c)
Author: Alex Larsson <alexl at redhat.com>
Date:   Wed Jun 20 12:01:12 2007 -0400

    Add non-mmx fast paths for In_8x8 and In_nx8x8. Bug 4191, patch by
    Alex Larsson.

diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 8886c0c..dafed13 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -149,6 +149,135 @@ fbCompositeOver_x888x8x8888 (pixman_op_t
     fbFinishAccess (pDst->pDrawable);
 }
 
+static void
+fbCompositeSolidMaskIn_nx8x8 (pixman_op_t      op,
+			      pixman_image_t    *iSrc,
+			      pixman_image_t    *iMask,
+			      pixman_image_t    *iDst,
+			      int16_t      xSrc,
+			      int16_t      ySrc,
+			      int16_t      xMask,
+			      int16_t      yMask,
+			      int16_t      xDst,
+			      int16_t      yDst,
+			      uint16_t     width,
+			      uint16_t     height)
+{
+    uint32_t	src, srca;
+    uint8_t	*dstLine, *dst, dstMask;
+    uint8_t	*maskLine, *mask, m;
+    int	dstStride, maskStride;
+    uint16_t	w;
+    uint16_t    t;
+    
+    fbComposeGetSolid(iSrc, src, iDst->bits.format);
+
+    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (iDst->bits.format));
+    srca = src >> 24;
+    
+    fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
+    fbComposeGetStart (iMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
+
+    if (srca == 0xff) {
+	while (height--)
+	{
+	    dst = dstLine;
+	    dstLine += dstStride;
+	    mask = maskLine;
+	    maskLine += maskStride;
+	    w = width;
+
+	    while (w--)
+	    {
+		m = *mask++;
+		if (m == 0)
+		{
+		    *dst = 0;
+		}
+		else if (m != 0xff)
+		{
+		    *dst = FbIntMult(m, *dst, t);
+		}
+		dst++;
+	    }
+	}
+    }
+    else
+    {
+	while (height--)
+	{
+	    dst = dstLine;
+	    dstLine += dstStride;
+	    mask = maskLine;
+	    maskLine += maskStride;
+	    w = width;
+
+	    while (w--)
+	    {
+		m = *mask++;
+		m = FbIntMult(m, srca, t);
+		if (m == 0)
+		{
+		    *dst = 0;
+		}
+		else if (m != 0xff)
+		{
+		    *dst = FbIntMult(m, *dst, t);
+		}
+		dst++;
+	    }
+	}
+    }
+}
+
+
+static void
+fbCompositeSrcIn_8x8 (pixman_op_t      op,
+		      pixman_image_t  *iSrc,
+		      pixman_image_t  *iMask,
+		      pixman_image_t  *iDst,
+		      int16_t          xSrc,
+		      int16_t          ySrc,
+		      int16_t          xMask,
+		      int16_t          yMask,
+		      int16_t          xDst,
+		      int16_t          yDst,
+		      uint16_t         width,
+		      uint16_t         height)
+{
+    uint8_t	*dstLine, *dst;
+    uint8_t	*srcLine, *src;
+    int	dstStride, srcStride;
+    uint16_t	w;
+    uint8_t	s;
+    uint16_t	t;
+    
+    fbComposeGetStart (iSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
+    fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
+    
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+	
+	while (w--)
+	{
+	    s = *src++;
+	    if (s == 0)
+	    {
+		*dst = 0;
+	    }
+	    else if (s != 0xff)
+	    {
+		*dst = FbIntMult(s, *dst, t);
+	    }
+	    dst++;
+	}
+    }
+}
 
 void
 fbCompositeSolidMask_nx8x8888 (pixman_op_t      op,
@@ -1855,13 +1984,16 @@ pixman_image_composite (pixman_op_t     
 	}
 	break;
     case PIXMAN_OP_IN:
-#ifdef USE_MMX
 	if (pSrc->bits.format == PIXMAN_a8 &&
 	    pDst->bits.format == PIXMAN_a8 &&
 	    !pMask)
-	{
+	{	
+#ifdef USE_MMX
 	    if (pixman_have_mmx())
-		func = fbCompositeIn_8x8mmx;
+		func = fbCompositeIn_8x8mmx;	    
+	    else
+#endif
+		func = fbCompositeIn_8x8;
 	}
 	else if (srcRepeat && pMask && !pMask->common.component_alpha &&
 		 (pSrc->bits.format == PIXMAN_a8r8g8b8 ||
@@ -1869,15 +2001,14 @@ pixman_image_composite (pixman_op_t     
 		 (pMask->bits.format == PIXMAN_a8)        &&
 		 pDst->bits.format == PIXMAN_a8)
 	{
+#ifdef USE_MMX
 	    if (pixman_have_mmx())
-	    {
-		srcRepeat = FALSE;
 		func = fbCompositeIn_nx8x8mmx;
-	    }
-	}
-#else
-	func = NULL;
+	    else
 #endif
+		func = fbCompositeSolidMaskIn_nx8x8;
+	    srcRepeat = FALSE;
+	}
        break;
     default:
 	break;
diff-tree 658acaad4e73ac705f705f947a42a2cd0979042c (from 440ed1da1c7ac600865c615cf257173cac2af214)
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Wed Jun 20 11:36:22 2007 -0400

    Add fbCompositeSrc_8888xx888(); comment out
    fbCompositeOver_x888x8x8888{mmx} since they are not actually faster
    than the generic code.

diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 57bd7d6..8886c0c 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1048,6 +1048,40 @@ fbCompositeSolidFill (pixman_op_t op,
 }
 
 static void
+fbCompositeSrc_8888xx888 (pixman_op_t op,
+			  pixman_image_t * pSrc,
+			  pixman_image_t * pMask,
+			  pixman_image_t * pDst,
+			  int16_t      xSrc,
+			  int16_t      ySrc,
+			  int16_t      xMask,
+			  int16_t      yMask,
+			  int16_t      xDst,
+			  int16_t      yDst,
+			  uint16_t     width,
+			  uint16_t     height)
+{
+    uint32_t	*dst;
+    uint32_t    *src;
+    int		 dstStride, srcStride;
+    uint32_t	 n_bytes = width * sizeof (uint32_t);
+
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, src, 1);
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
+
+    while (height--)
+    {
+	memcpy (dst, src, n_bytes);
+
+	dst += dstStride;
+	src += srcStride;
+    }
+    
+    fbFinishAccess(pSrc->pDrawable);
+    fbFinishAccess(pDst->pDrawable);
+}
+
+static void
 pixman_walk_composite_region (pixman_op_t op,
 			      pixman_image_t * pSrc,
 			      pixman_image_t * pMask,
@@ -1509,6 +1543,10 @@ pixman_image_composite (pixman_op_t     
 		}
 		else
 		{
+#if 0
+		    /* FIXME: This code is commented out since it's apparently not
+		     * actually faster than the generic code.
+		     */
 		    if (pMask->bits.format == PIXMAN_a8)
 		    {
 			if ((pSrc->bits.format == PIXMAN_x8r8g8b8 &&
@@ -1526,6 +1564,7 @@ pixman_image_composite (pixman_op_t     
 				func = fbCompositeOver_x888x8x8888;
 			}
 		    }
+#endif
 		}
 	    }
 	}
@@ -1804,6 +1843,15 @@ pixman_image_composite (pixman_op_t     
 #endif
 			;
 	    }
+	    else if (((pSrc->bits.format == PIXMAN_a8r8g8b8 ||
+		       pSrc->bits.format == PIXMAN_x8r8g8b8) &&
+		      pDst->bits.format == PIXMAN_x8r8g8b8)	||
+		     ((pSrc->bits.format == PIXMAN_a8b8g8r8 ||
+		       pSrc->bits.format == PIXMAN_x8b8g8r8) &&
+		      pDst->bits.format == PIXMAN_x8b8g8r8))
+	    {
+		func = fbCompositeSrc_8888xx888;
+	    }
 	}
 	break;
     case PIXMAN_OP_IN:
diff-tree 440ed1da1c7ac600865c615cf257173cac2af214 (from deb09d769ae4fc55cde595c170f417692284b3e8)
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 19 14:41:04 2007 -0400

    Optimize pixman_fill_rectangles() in a few more cases

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index bd50705..3cc6b8d 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -591,6 +591,47 @@ pixman_image_get_depth (pixman_image_t *
 }
 
 pixman_bool_t
+color_to_pixel (pixman_color_t *color,
+		uint32_t       *pixel,
+		pixman_format_code_t format)
+{
+    uint32_t c = color_to_uint32 (color);
+
+    if (!(format == PIXMAN_a8r8g8b8	||
+	  format == PIXMAN_x8r8g8b8	||
+	  format == PIXMAN_a8b8g8r8	||
+	  format == PIXMAN_x8b8g8r8	||
+	  format == PIXMAN_r5g6b5	||
+	  format == PIXMAN_b5g6r5	||
+	  format == PIXMAN_a8))
+    {
+	return FALSE;
+    }
+    
+    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
+    {
+	c = ((c & 0xff000000) >>  0) |
+	    ((c & 0x00ff0000) >> 16) |
+	    ((c & 0x0000ff00) >>  0) |
+	    ((c & 0x000000ff) << 16);
+    }
+
+    if (format == PIXMAN_a8)
+	c = c >> 24;
+    else if (format == PIXMAN_r5g6b5 ||
+	     format == PIXMAN_b5g6r5)
+	c = cvt8888to0565 (c);
+
+#if 0
+    printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
+    printf ("pixel: %x\n", c);
+#endif
+    
+    *pixel = c;
+    return TRUE;
+}
+
+pixman_bool_t
 pixman_image_fill_rectangles (pixman_op_t		    op,
 			      pixman_image_t		   *dest,
 			      pixman_color_t		   *color,
@@ -619,6 +660,36 @@ pixman_image_fill_rectangles (pixman_op_
 	op = PIXMAN_OP_SRC;
     }
 
+    if (op == PIXMAN_OP_SRC)
+    {
+	uint32_t pixel;
+	
+	if (color_to_pixel (color, &pixel, dest->bits.format))
+	{
+	    for (i = 0; i < n_rects; ++i)
+	    {
+		pixman_region16_t fill_region;
+		int n_boxes, j;
+		pixman_box16_t *boxes;
+		
+		pixman_region_init_rect (&fill_region, rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+		pixman_region_intersect (&fill_region, &fill_region, &dest->common.clip_region);
+
+		boxes = pixman_region_rectangles (&fill_region, &n_boxes);
+		for (j = 0; j < n_boxes; ++j)
+		{
+		    const pixman_box16_t *box = &(boxes[j]);
+		    pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
+				 box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1,
+				 pixel);
+		}
+
+		pixman_region_fini (&fill_region);
+	    }
+	    return TRUE;
+	}
+    }
+    
     solid = pixman_image_create_solid_fill (color);
     if (!solid)
 	return FALSE;
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index b15b818..aadb6e7 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -162,6 +162,11 @@ pixman_fill (uint32_t *bits,
 	     int height,
 	     uint32_t xor)
 {
+#if 0
+    printf ("filling: %d %d %d %d (stride: %d, bpp: %d)   pixel: %x\n",
+	    x, y, width, height, stride, bpp, xor);
+#endif
+    
 #ifdef USE_MMX
     if (!pixman_have_mmx() || !pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
 #endif
diff-tree deb09d769ae4fc55cde595c170f417692284b3e8 (from 6cb74dfe3d395051f9a2e4b850979a018ac340ca)
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 19 12:41:21 2007 -0400

    Add a cache of images to reduce malloc/free time

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 2bc3ef6..bd50705 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -69,10 +69,37 @@ color_to_uint32 (const pixman_color_t *c
 	(color->blue >> 8);
 }
 
+static pixman_image_t *image_cache;
+
+static pixman_image_t *
+new_image (void)
+{
+    pixman_image_t *image;
+
+    if (image_cache)
+    {
+	image = image_cache;
+	image_cache = image->next;
+    }
+    else
+    {
+	image = malloc (sizeof (pixman_image_t));
+    }
+
+    return image;
+}
+
+static void
+delete_image (pixman_image_t *image)
+{
+    image->next = image_cache;
+    image_cache = image;
+}
+
 static pixman_image_t *
 allocate_image (void)
 {
-    pixman_image_t *image = malloc (sizeof (pixman_image_t));
+    pixman_image_t *image = new_image();
     
     if (image)
     {
@@ -145,7 +172,7 @@ pixman_image_unref (pixman_image_t *imag
 	if (image->type == BITS && image->bits.free_me)
 	    free (image->bits.free_me);
 	
-	free (image);
+	delete_image (image);
     }
 }
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9b89dee..d10d7ad 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -260,6 +260,7 @@ union pixman_image
     conical_gradient_t		conical;
     radial_gradient_t		radial;
     solid_fill_t		solid;
+    pixman_image_t             *next;	/* Used in the image cache */
 };
 
 #define LOG2_BITMAP_PAD 5


More information about the xorg-commit mailing list