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