pixman: Changes to 'upstream-experimental'
TODO | 137 ++-
pixman/Makefile.am | 25
pixman/pixman-compose.c | 1611 +++++++++++++++++++----------------------
pixman/pixman-compute-region.c | 4
pixman/pixman-edge-imp.h | 43 -
pixman/pixman-edge.c | 372 ++-------
pixman/pixman-image.c | 146 +++
pixman/pixman-mmx.c | 244 ++++--
pixman/pixman-mmx.h | 15
pixman/pixman-pict.c | 415 +++++++++-
pixman/pixman-private.h | 263 ++++--
pixman/pixman-region.c | 95 ++
pixman/pixman-timer.c | 59 +
pixman/pixman-utils.c | 314 +++++++
pixman/pixman.h | 5
test/gradient-test.c | 1
16 files changed, 2329 insertions(+), 1420 deletions(-)
New commits:
commit 0c80a0cd84f30616563cef5910df9deb4f8ed687
Author: Alan Coopersmith <alanc@sun.com>
Date: Mon Jul 16 15:06:23 2007 -0400
Build fixes for Solaris.
diff --git a/pixman/pixman-edge.c b/pixman/pixman-edge.c
index 335a25f..191752f 100644
--- a/pixman/pixman-edge.c
+++ b/pixman/pixman-edge.c
@@ -321,13 +321,9 @@ pixman_rasterize_edges (pixman_image_t *image,
pixman_fixed_t b)
{
if (image->common.read_func || image->common.write_func)
- {
- return pixman_rasterize_edges_accessors (image, l, r, t, b);
- }
+ pixman_rasterize_edges_accessors (image, l, r, t, b);
else
- {
- return pixman_rasterize_edges_no_accessors (image, l, r, t, b);
- }
+ pixman_rasterize_edges_no_accessors (image, l, r, t, b);
}
#endif
commit 0f392d81748ab1338d294de96e28c43270f24180
Author: Jinghua Luo <sunmoon1997@gmail.com>
Date: Tue Jul 10 14:47:28 2007 +0800
Fix bug in rasterizeEdges() where the stride should be signed.
diff --git a/pixman/pixman-edge.c b/pixman/pixman-edge.c
index 1b28550..335a25f 100644
--- a/pixman/pixman-edge.c
+++ b/pixman/pixman-edge.c
@@ -128,7 +128,7 @@ fbRasterizeEdges8 (pixman_image_t *image,
int fill_start = -1, fill_end = -1;
int fill_size = 0;
uint32_t *buf = (image)->bits.bits;
- uint32_t stride = (image)->bits.rowstride;
+ int32_t stride = (image)->bits.rowstride;
uint32_t width = (image)->bits.width;
line = buf + pixman_fixed_to_int (y) * stride;
commit bbef73192e558695933d7f05befaa8c18550bb63
Author: Søren Sandmann <sandmann@redhat.com>
Date: Mon Jul 2 12:18:42 2007 -0400
Port Vlad's fixes for integer overflows with malloc().
diff --git a/TODO b/TODO
index 92beb0b..6649c69 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +1,15 @@
+ - Go through things marked FIXME
+
+ - Add calls to prepare and finish access where necessary. grep for
+ ACCESS_MEM, and make sure they are correctly wrapped in prepare
+ and finish.
+
+ - restore READ/WRITE in the fbcompose combiners since they sometimes
+ store directly to destination drawables.
+
- It probably makes sense to move the more strange X region API
into pixman as well, but guarded with PIXMAN_XORG_COMPATIBILITY
- - Go through things marked FIXME
-
- Reinstate the FbBits typedef? At the moment we don't
even have the FbBits type; we just use uint32_t everywhere.
@@ -14,33 +21,78 @@
this, I suggest just using 32-bit datatypes by setting
IC_SHIFT to 5 for all machines.
-- Consider whether calling regions region16 is really such a great idea
+ - Consider whether calling regions region16 is really such a great
+ idea Vlad wants 32 bit regions for Cairo. This will break X server
+ ABI, but should otherwise be mostly harmless, though a
+ pixman_region_get_boxes16() may be useful.
-- Run cairo test suite; fix bugs
- - one bug in source-scale-clip
+ - Make source clipping optional.
+ - done: source clipping happens through an indirection.
+ still needs to make the indirection settable. (And call it
+ from X)
- - Remove the warning suppression in the ACCESS_MEM macro and fix the
- warnings that are real
+ - Consider optimizing the 8/16 bit solid fills in pixman-util.c by
+ storing more than one value at a time.
-- Add calls to prepare and finish access where necessary.
- grep for ACCESS_MEM, and make sure they are correctly wrapped in
- prepare and finish
+ - Add an image cache to prevent excessive malloc/free. Note that pixman
+ needs to be thread safe when used from cairo.
-- Make source clipping optional.
- - done: source clipping happens through an indirection.
- still needs to make the indirection settable.
+ - Review the pixman_format_code_t enum to make sure it will support
+ future formats. Some formats we will probably need:
-- make the wrapper functions global instead of image specific
- - this won't work since pixman is linked to both fb and wfb
+ ARGB/ABGR with 16/32/64 bit integer/floating channels
+ YUV2,
+ YV12
+
+ Also we may need the ability to distinguish between PICT_c8 and
+ PICT_x4c4. (This could be done by interpreting the A channel as
+ the depth for TYPE_COLOR and TYPE_GRAY formats).
+
+ A possibility may be to reserve the two top bits and make them
+ encode "number of places to shift the channel widths given" Since
+ these bits are 00 at the moment everything will continue to work,
+ but these additional widths will be allowed:
+
+ All even widths between 18-32
+ All multiples of four widths between 33 and 64
+ All multiples of eight between 64 and 128
-- restore READ/WRITE in the fbcompose combiners since they sometimes
- store directly to destination drawables.
+ This means things like r21g22b21 won't work - is that worth
+ worrying about? I don't think so. And of course the bpp field
+ can't handle a depth of over 256, so > 64 bit channels arent'
+ really all that useful.
+
+ We could reserve one extra bit to indicate floating point, but
+ we may also just add
+
+ PIXMAN_TYPE_ARGB_FLOAT
+ PIXMAN_TYPE_BGRA_FLOAT
+ PIXMAN_TYPE_A_FLOAT
+
+ image types. With five bits we can support up to 32 different
+ format types, which should be enough for everybody, even if we
+ decide to support all the various video formats here:
+
+ http://www.fourcc.org/yuv.php
+
+ It may make sense to have a PIXMAN_TYPE_YUV, and then use the
+ channel bits to specify the exact subtype.
+
+ What about color spaces such a linear vs. srGB etc.?
-- Consider optimizing the 8/16 bit solid fills in pixman-util.c by
- storing more than one value at a time.
done:
+- Run cairo test suite; fix bugs
+ - one bug in source-scale-clip
+
+ - Remove the warning suppression in the ACCESS_MEM macro and fix the
+ warnings that are real
+ - irrelevant now.
+
+- make the wrapper functions global instead of image specific
+ - this won't work since pixman is linked to both fb and wfb
+
- Add non-mmx solid fill
- Make sure the endian-ness macros are defined correctly.
diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c
index e336e04..e7f80f8 100644
--- a/pixman/pixman-compose.c
+++ b/pixman/pixman-compose.c
@@ -4074,7 +4074,7 @@ static void fbFetchExternalAlpha(bits_image_t * pict, int x, int y, int width, u
return;
}
if (width > SCANLINE_BUFFER_LENGTH)
- alpha_buffer = (uint32_t *) malloc(width*sizeof(uint32_t));
+ alpha_buffer = (uint32_t *) pixman_malloc_ab (width, sizeof(uint32_t));
fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
fbFetchTransformed((bits_image_t *)pict->common.alpha_map, x - pict->common.alpha_origin.x,
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index f22d2c0..ca186a3 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -44,7 +44,7 @@ init_gradient (gradient_t *gradient,
init_source_image (&gradient->common);
- gradient->stops = malloc (n_stops * sizeof (pixman_gradient_stop_t));
+ gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
if (!gradient->stops)
return FALSE;
@@ -443,7 +443,7 @@ pixman_image_set_filter (pixman_image_t *image,
new_params = NULL;
if (params)
{
- new_params = malloc (n_params * sizeof (pixman_fixed_t));
+ new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
if (!new_params)
return FALSE;
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index cad11dd..b8b7b76 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1359,7 +1359,7 @@ pixman_image_composite_rect (pixman_op_t op,
if (width > SCANLINE_BUFFER_LENGTH)
{
- scanline_buffer = (uint32_t *)malloc (width * 3 * sizeof (uint32_t));
+ scanline_buffer = (uint32_t *)pixman_malloc_abc (width, 3, sizeof (uint32_t));
if (!scanline_buffer)
return;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9b89dee..89abf8f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -44,6 +44,9 @@
#define FB_MASK (FB_UNIT - 1)
#define FB_ALLONES ((uint32_t) -1)
+/* Memory allocation helpers */
+void *pixman_malloc_ab (unsigned int n, unsigned int b);
+void *pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
#if DEBUG
diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 08ce2e2..ffd92d6 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -69,7 +69,6 @@ typedef struct pixman_region16_point {
#define PIXREGION_BOX(reg,i) (&PIXREGION_BOXPTR(reg)[i])
#define PIXREGION_TOP(reg) PIXREGION_BOX(reg, (reg)->data->numRects)
#define PIXREGION_END(reg) PIXREGION_BOX(reg, (reg)->data->numRects - 1)
-#define PIXREGION_SZOF(n) (sizeof(pixman_region16_data_t) + ((n) * sizeof(pixman_box16_t)))
#undef assert
@@ -186,7 +185,29 @@ pixman_break (pixman_region16_t *pReg);
((r1)->y1 <= (r2)->y1) && \
((r1)->y2 >= (r2)->y2) )
-#define allocData(n) malloc(PIXREGION_SZOF(n))
+static size_t
+PIXREGION_SZOF(size_t n)
+{
+ size_t size = n * sizeof(pixman_box16_t);
+ if (n > UINT32_MAX / sizeof(pixman_box16_t))
+ return 0;
+
+ if (sizeof(pixman_region16_data_t) > UINT32_MAX - size)
+ return 0;
+
+ return size + sizeof(pixman_region16_data_t);
+}
+
+static void *
+allocData(size_t n)
+{
+ size_t sz = PIXREGION_SZOF(n);
+ if (!sz)
+ return NULL;
+
+ return malloc(sz);
+}
+
#define freeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
#define RECTALLOC_BAIL(pReg,n,bail) \
@@ -219,17 +240,21 @@ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
assert(pReg->data->numRects<=pReg->data->size); \
}
-#define DOWNSIZE(reg,numRects) \
-if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
-{ \
- pixman_region16_data_t * NewData; \
- NewData = (pixman_region16_data_t *)realloc((reg)->data, PIXREGION_SZOF(numRects)); \
- if (NewData) \
- { \
- NewData->size = (numRects); \
- (reg)->data = NewData; \
- } \
-}
+#define DOWNSIZE(reg,numRects) \
+ if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
+ { \
+ pixman_region16_data_t * NewData; \
+ size_t data_size = PIXREGION_SZOF(numRects); \
+ if (!data_size) \
+ NewData = NULL; \
+ else \
+ NewData = (pixman_region16_data_t *)realloc((reg)->data, data_size); \
+ if (NewData) \
+ { \
+ NewData->size = (numRects); \
+ (reg)->data = NewData; \
+ } \
+ }
pixman_bool_t
pixman_region_equal(reg1, reg2)
@@ -365,6 +390,7 @@ pixman_rect_alloc (pixman_region16_t * region, int n)
}
else
{
+ size_t data_size;
if (n == 1)
{
n = region->data->numRects;
@@ -372,7 +398,11 @@ pixman_rect_alloc (pixman_region16_t * region, int n)
n = 250;
}
n += region->data->numRects;
- data = (pixman_region16_data_t *)realloc(region->data, PIXREGION_SZOF(n));
+ data_size = PIXREGION_SZOF(n);
+ if (!data_size)
+ data = NULL;
+ else
+ data = (pixman_region16_data_t *)realloc(region->data, PIXREGION_SZOF(n));
if (!data)
return pixman_break (region);
region->data = data;
@@ -1466,7 +1496,7 @@ pixman_region_validate(pixman_region16_t * badreg,
/* Set up the first region to be the first rectangle in badreg */
/* Note that step 2 code will never overflow the ri[0].reg rects array */
- ri = (RegionInfo *) malloc(4 * sizeof(RegionInfo));
+ ri = (RegionInfo *) pixman_malloc_ab (4, sizeof(RegionInfo));
if (!ri)
return pixman_break (badreg);
sizeRI = 4;
@@ -1528,9 +1558,15 @@ pixman_region_validate(pixman_region16_t * badreg,
/* Uh-oh. No regions were appropriate. Create a new one. */
if (sizeRI == numRI)
{
+ size_t data_size;
+
/* Oops, allocate space for new region information */
sizeRI <<= 1;
- rit = (RegionInfo *) realloc(ri, sizeRI * sizeof(RegionInfo));
+
+ data_size = sizeRI * sizeof(RegionInfo);
+ if (data_size / sizeRI != sizeof(RegionInfo))
+ goto bail;
+ rit = (RegionInfo *) realloc(ri, data_size);
if (!rit)
goto bail;
ri = rit;
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index aadb6e7..cdf115d 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -22,6 +22,7 @@
*/
#include <config.h>
+#include <stdlib.h>
#include "pixman.h"
#include "pixman-private.h"
#include "pixman-mmx.h"
@@ -366,3 +367,26 @@ pixman_line_fixed_edge_init (pixman_edge_t *e,
bot->x + x_off_fixed,
bot->y + y_off_fixed);
}
+
+void *
+pixman_malloc_ab(unsigned int a,
+ unsigned int b)
+{
+ if (a >= INT32_MAX / b)
+ return NULL;
+
+ return malloc (a * b);
+}
+
+void *
+pixman_malloc_abc (unsigned int a,
+ unsigned int b,
+ unsigned int c)
+{
+ if (a >= INT32_MAX / b)
+ return NULL;
+ else if (a * b >= INT32_MAX / c)
+ return NULL;
+ else
+ return malloc (a * b * c);
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index cd64c8d..bd6045f 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -363,7 +363,7 @@ struct pixman_indexed
PIXMAN_FORMAT_B(f))
#define PIXMAN_TYPE_OTHER 0
-#define PIXMAN_TYPE_A 1
+#define PIXMAN_TYPE_A 1
#define PIXMAN_TYPE_ARGB 2
#define PIXMAN_TYPE_ABGR 3
#define PIXMAN_TYPE_COLOR 4
commit 2e61f30e4c8d0e01e175495e13a5f132521ad6f2
Author: Søren Sandmann <sandmann@redhat.com>
Date: Fri Jun 22 13:37:46 2007 -0400
Revert "Add a cache of images to reduce malloc/free time"
Revert the image cache since it isn't thread safe.
This reverts commit deb09d769ae4fc55cde595c170f417692284b3e8.
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 3cc6b8d..f22d2c0 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -69,37 +69,10 @@ color_to_uint32 (const pixman_color_t *color)
(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 = new_image();
+ pixman_image_t *image = malloc (sizeof (pixman_image_t));
if (image)
{
@@ -172,7 +145,7 @@ pixman_image_unref (pixman_image_t *image)
if (image->type == BITS && image->bits.free_me)
free (image->bits.free_me);
- delete_image (image);
+ free (image);
}
}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d10d7ad..9b89dee 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -260,7 +260,6 @@ 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
commit 64e3146c5ddfad415663fa5f87f7b9ff327a8c56
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date: Fri Jun 22 00:58:05 2007 -0400
Don't treat void as a value. Bug 11322, Alan Coopersmith.
diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c
index 24402da..e336e04 100644
--- a/pixman/pixman-compose.c
+++ b/pixman/pixman-compose.c
@@ -4459,11 +4459,11 @@ pixman_composite_rect_general (const FbComposeData *data,
data->dest->common.read_func ||
data->dest->common.write_func)
{
- return pixman_composite_rect_general_accessors (data, scanline_buffer);
+ pixman_composite_rect_general_accessors (data, scanline_buffer);
}
else
{
- return pixman_composite_rect_general_no_accessors (data, scanline_buffer);
+ pixman_composite_rect_general_no_accessors (data, scanline_buffer);
}
}
commit 8216ba1cbd27c5428970b8d393722d0f4343efed
Author: Vladimir Vukicevic <vladimir@pobox.com>
Date: Wed Jun 20 15:13:30 2007 -0400
Add pixman_region_init_rects()
diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 7a0f9da..08ce2e2 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -2468,3 +2468,30 @@ pixman_region_selfcheck (reg)
}
}
+pixman_bool_t
+pixman_region_init_rects (pixman_region16_t *region,
+ pixman_box16_t *boxes, int count)
+{
+ int overlap;
+
+ if (count == 1) {
+ pixman_region_init_rect(region,
+ boxes[0].x1,
+ boxes[0].y1,
+ boxes[0].x2 - boxes[0].x1,
+ boxes[0].y2 - boxes[0].y1);
+ return TRUE;
+ }
+
+ pixman_region_init(region);
+ if (!pixman_rect_alloc(region, count))
+ return FALSE;
+
+ /* Copy in the rects */
+ memcpy (PIXREGION_RECTS(region), boxes, sizeof(pixman_box16_t) * count);
+ region->data->numRects = count;
+
+ /* Validate */
+ region->extents.x1 = region->extents.x2 = 0;
+ return pixman_region_validate (region, &overlap);
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 0014cef..cd64c8d 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -288,7 +288,8 @@ pixman_bool_t pixman_region_equal (pixman_region16_t *region1,
pixman_region16_t *region2);
pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region);
void pixman_region_reset(pixman_region16_t *region, pixman_box16_t *box);
-
+pixman_bool_t pixman_region_init_rects (pixman_region16_t *region,
+ pixman_box16_t *boxes, int count);
/* Copy / Fill */
pixman_bool_t pixman_blt (uint32_t *src_bits,
commit f1194a8bc0599e3ecceb785795ad8283a7c04dc0
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date: Wed Jun 20 12:12:43 2007 -0400
Fix typo
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index dafed13..cad11dd 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1993,7 +1993,7 @@ pixman_image_composite (pixman_op_t op,
func = fbCompositeIn_8x8mmx;
else
#endif
- func = fbCompositeIn_8x8;
+ func = fbCompositeSrcIn_8x8;
}
else if (srcRepeat && pMask && !pMask->common.component_alpha &&
(pSrc->bits.format == PIXMAN_a8r8g8b8 ||
commit 3dbb2a56bd1918595091006c6e0de5260d43af09
Author: Alex Larsson <alexl@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 op,
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 op,
}
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 op,
(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;
commit 658acaad4e73ac705f705f947a42a2cd0979042c
Author: Søren Sandmann Pedersen <sandmann@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 op,
}
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 op,
func = fbCompositeOver_x888x8x8888;
}
}
+#endif
}
}
}
@@ -1804,6 +1843,15 @@ pixman_image_composite (pixman_op_t op,
#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:
commit 440ed1da1c7ac600865c615cf257173cac2af214
Author: Søren Sandmann Pedersen <sandmann@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 *image)
}
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_t 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
commit deb09d769ae4fc55cde595c170f417692284b3e8
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date: Tue Jun 19 12:41:21 2007 -0400
Add a cache of images to reduce malloc/free time
Reply to: