[Pixman] [PATCH] test: Fix bug in color_correct() in composite.c

2010-03-07 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This function was using the number of bits in a channel as if it were
a mask, which lead to many spurious errors. With that fixed, we can
turn on testing for all formats where all channels have 5 or more
bits.

Cc: ch...@chris-wilson.co.uk
---
 test/composite.c |   38 +++---
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/test/composite.c b/test/composite.c
index 0624cd3..cea44cb 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -85,7 +85,6 @@ compute_pixman_color (const color_t *color,
 static const format_t formats[] =
 {
 #define P(x) { PIXMAN_##x, #x }
-P(a8),
 
 /* 32bpp formats */
 P(a8r8g8b8),
@@ -94,33 +93,40 @@ static const format_t formats[] =
 P(x8b8g8r8),
 P(b8g8r8a8),
 P(b8g8r8x8),
-
-/* XXX: and here the errors begin! */
-#if 0
 P(x2r10g10b10),
-P(a2r10g10b10),
 P(x2b10g10r10),
-P(a2b10g10r10),
 
 /* 24bpp formats */
 P(r8g8b8),
 P(b8g8r8),
-
-/* 16bpp formats */
 P(r5g6b5),
 P(b5g6r5),
 
-P(a1r5g5b5),
+/* 16bpp formats */
 P(x1r5g5b5),
-P(a1b5g5r5),
 P(x1b5g5r5),
-P(a4r4g4b4),
-P(x4r4g4b4),
+
+/* 8bpp formats */
+P(a8),
+
+#if 0
+/* XXX: and here the errors begin!
+ *
+ * The formats below all have channels with 4 bits or less, and
+ * the eval_diff code doesn't deal correctly with that.
+ */
+P(a2r10g10b10),
+P(a2b10g10r10),
+
+/* 16bpp formats */
+P(a1r5g5b5),
+P(a1b5g5r5),
 P(a4b4g4r4),
 P(x4b4g4r4),
+P(a4r4g4b4),
+P(x4r4g4b4),
 
 /* 8bpp formats */
-P(a8),
 P(r3g3b2),
 P(b2g3r3),
 P(a2r2g2b2),
@@ -482,8 +488,9 @@ static void
 color_correct (pixman_format_code_t format,
   color_t *color)
 {
-#define round_pix(pix, mask) \
-((int)((pix) * (mask) + .5) / (double) (mask))
+#define MASK(x) ((1 << (x)) - 1)
+#define round_pix(pix, m)  \
+((int)((pix) * (MASK(m)) + .5) / (double) (MASK(m)))
 
 if (PIXMAN_FORMAT_R (format) == 0)
 {
@@ -504,6 +511,7 @@ color_correct (pixman_format_code_t format,
color->a = round_pix (color->a, PIXMAN_FORMAT_A (format));
 
 #undef round_pix
+#undef MASK
 }
 
 static void
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] test: Fix eval_diff() so that it provides useful error values.

2010-03-07 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Previously, this function would evaluate the error under the
assumption that the format was 565 or wider. This patch changes it to
take the actual format into account.

With that fixed, we can turn on testing for the rest of the formats.

Cc: ch...@chris-wilson.co.uk
---
 test/composite.c |   46 +++---
 1 files changed, 15 insertions(+), 31 deletions(-)

diff --git a/test/composite.c b/test/composite.c
index cea44cb..632e14b 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -86,7 +86,7 @@ static const format_t formats[] =
 {
 #define P(x) { PIXMAN_##x, #x }
 
-/* 32bpp formats */
+/* 32 bpp formats */
 P(a8r8g8b8),
 P(x8r8g8b8),
 P(a8b8g8r8),
@@ -95,30 +95,18 @@ static const format_t formats[] =
 P(b8g8r8x8),
 P(x2r10g10b10),
 P(x2b10g10r10),
+P(a2r10g10b10),
+P(a2b10g10r10),
 
-/* 24bpp formats */
+/* 24 bpp formats */
 P(r8g8b8),
 P(b8g8r8),
 P(r5g6b5),
 P(b5g6r5),
 
-/* 16bpp formats */
+/* 16 bpp formats */
 P(x1r5g5b5),
 P(x1b5g5r5),
-
-/* 8bpp formats */
-P(a8),
-
-#if 0
-/* XXX: and here the errors begin!
- *
- * The formats below all have channels with 4 bits or less, and
- * the eval_diff code doesn't deal correctly with that.
- */
-P(a2r10g10b10),
-P(a2b10g10r10),
-
-/* 16bpp formats */
 P(a1r5g5b5),
 P(a1b5g5r5),
 P(a4b4g4r4),
@@ -126,24 +114,23 @@ static const format_t formats[] =
 P(a4r4g4b4),
 P(x4r4g4b4),
 
-/* 8bpp formats */
+/* 8 bpp formats */
+P(a8),
 P(r3g3b2),
 P(b2g3r3),
 P(a2r2g2b2),
 P(a2b2g2r2),
-
 P(x4a4),
 
-/* 4bpp formats */
+/* 4 bpp formats */
 P(a4),
 P(r1g2b1),
 P(b1g2r1),
 P(a1r1g1b1),
 P(a1b1g1r1),
 
-/* 1bpp formats */
+/* 1 bpp formats */
 P(a1)
-#endif
 #undef P
 };
 
@@ -602,18 +589,15 @@ get_pixel (pixman_image_t *image,
 }
 
 static double
-eval_diff (color_t *expected, color_t *test)
+eval_diff (color_t *expected, color_t *test, pixman_format_code_t format)
 {
 double rscale, gscale, bscale, ascale;
 double rdiff, gdiff, bdiff, adiff;
 
-/* XXX: Need to be provided mask shifts so we can produce useful error
- * values.
- */
-rscale = 1.0 * (1 << 5);
-gscale = 1.0 * (1 << 6);
-bscale = 1.0 * (1 << 5);
-ascale = 1.0 * 32;
+rscale = 1.0 * ((1 << PIXMAN_FORMAT_R (format)) - 1);
+gscale = 1.0 * ((1 << PIXMAN_FORMAT_G (format)) - 1);
+bscale = 1.0 * ((1 << PIXMAN_FORMAT_B (format)) - 1);
+ascale = 1.0 * ((1 << PIXMAN_FORMAT_A (format)) - 1);
 
 rdiff = fabs (test->r - expected->r) * rscale;
 bdiff = fabs (test->g - expected->g) * gscale;
@@ -707,7 +691,7 @@ composite_test (image_t *dst,
  &expected, component_alpha);
 color_correct (dst->format->format, &expected);
 
-diff = eval_diff (&expected, &result);
+diff = eval_diff (&expected, &result, dst->format->format);
 if (diff > 3.0)
 {
char buf[40];
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] test: Change composite so that it tests randomly generated images

2010-03-07 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Previously this test would try to exhaustively test all combinations
of formats and operators, which meant that it would take years to run.

Instead, generate random images and test those. The random seed is
based on time(), so we will get different tests every time it is run.
Whenever the test fails, it will print what the value of lcg_seed was
when the test began.

This patch also adds a table of random seeds that have failed at some
point. These seeds are run first before the random testing begins.
Whenever this tests fails, you are supposed to add the seed that
failed to the table, so that we can track that the bug doesn't get
reintroduced.

Cc: ch...@chris-wilson.co.uk
---
 test/Makefile.am |4 +-
 test/composite.c |  183 --
 2 files changed, 99 insertions(+), 88 deletions(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 841ff8d..322f3e3 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -15,7 +15,6 @@ TESTPROGRAMS =\
 
 a1_trap_test_LDADD = $(TEST_LDADD)
 fetch_test_LDADD = $(TEST_LDADD)
-composite_LDADD = $(TEST_LDADD)
 trap_crasher_LDADD = $(TEST_LDADD)
 oob_test_LDADD = $(TEST_LDADD)
 window_test_LDADD = $(TEST_LDADD)
@@ -32,6 +31,9 @@ scaling_test_SOURCES = scaling-test.c utils.c utils.h
 alphamap_LDADD = $(TEST_LDADD)
 alphamap_SOURCES = alphamap.c utils.c utils.h
 
+composite_LDADD = $(TEST_LDADD)
+composite_SOURCES = composite.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/composite.c b/test/composite.c
index 632e14b..0610805 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2005 Eric Anholt
  * Copyright © 2009 Chris Wilson
+ * Copyright © 2010 Soeren Sandmann
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -20,15 +21,14 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
-
+#define PIXMAN_USE_INTERNAL_API
 #include 
 #include 
 #include  /* abort() */
 #include 
 #include 
-
-#define FALSE 0
-#define TRUE !FALSE
+#include 
+#include "utils.h"
 
 #define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
 #define min(a,b) ((a) <= (b) ? (a) : (b))
@@ -692,6 +692,11 @@ composite_test (image_t *dst,
 color_correct (dst->format->format, &expected);
 
 diff = eval_diff (&expected, &result, dst->format->format);
+
+/* FIXME: We should find out what deviation is acceptable. 3.0
+ * is clearly absurd for 2 bit formats for example. On the other
+ * hand currently 1.0 does not work.
+ */
 if (diff > 3.0)
 {
char buf[40];
@@ -709,7 +714,7 @@ composite_test (image_t *dst,
result.r, result.g, result.b, result.a,
*(unsigned long *) pixman_image_get_data (dst->image),
expected.r, expected.g, expected.b, expected.a);
-   
+
if (mask != NULL)
{
printf ("src color: %.2f %.2f %.2f %.2f\n"
@@ -792,102 +797,106 @@ image_fini (image_t *info)
 pixman_image_unref (info->image);
 }
 
-int
-main (void)
+static int
+random_color (void)
+{
+return lcg_rand_n (ARRAY_LENGTH (colors));
+}
+
+static int
+random_format (void)
+{
+return lcg_rand_n (ARRAY_LENGTH (formats));
+}
+
+static pixman_bool_t
+run_test (void)
 {
-pixman_bool_t ok, group_ok = TRUE, ca;
-int i, d, m, s;
-int tests_passed = 0, tests_total = 0;
+uint32_t seed = lcg_seed;
+image_t src, mask, dst;
 int sizes[] = { 1, 1 | REPEAT, 10 };
-int num_tests;
+int n_sizes = ARRAY_LENGTH (sizes);
+const operator_t *op;
+int ca;
+int ok;
+
+image_init (&dst, random_color(), random_format(), 1);
+image_init (&src, random_color(), random_format(), lcg_rand_n (n_sizes));
+image_init (&mask, random_color(), random_format(), lcg_rand_n (n_sizes));
 
-for (i = 0; i < ARRAY_LENGTH (colors); i++)
+op = &(operators [lcg_rand_n (ARRAY_LENGTH (operators))]);
+
+ca = lcg_rand_n (3);
+
+switch (ca)
 {
-   colors[i].r *= colors[i].a;
-   colors[i].g *= colors[i].a;
-   colors[i].b *= colors[i].a;
+case 0:
+   ok = composite_test (&dst, op, &src, NULL, FALSE);
+   break;
+case 1:
+   ok = composite_test (&dst, op, &src, &mask, FALSE);
+   break;
+case 2:
+   ok = composite_test (&dst, op, &src, &mask,
+mask.size? TRUE : FALSE);
+   break;
+default:
+   ok = FALSE;
+   break;
 }
 
-num_tests = ARRAY_LENGTH (colors) * ARRAY_LENGTH (formats);
+image_fini (&src);
+image_fini (&mask);
+image_fini (&dst);
 
-for (d = 0; d < num_tests; d++)
+if (!ok)
 {
-   image_

[Pixman] [PATCH] pixman.h: Only define stdint types when PIXMAN_DONT_DEFINE_STDINT is undefined

2010-03-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

In SPICE, with Microsoft Visual C++, pixman.h is included after
another file that defines these types, which causes warnings and
errors.

This patch allows such code to just define PIXMAN_DONT_DEFINE_STDINT
to use its own version of those types.

Cc: al...@redhat.com
---
 pixman/pixman.h |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman.h b/pixman/pixman.h
index 69af0f9..ce1cca0 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -84,6 +84,9 @@ PIXMAN_BEGIN_DECLS
 /*
  * Standard integers
  */
+
+#if !defined (PIXMAN_DONT_DEFINE_STDINT)
+
 #if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined 
(_sgi) || defined (__sun) || defined (sun) || defined (__digital__) || defined 
(__HP_cc)
 #  include 
 #elif defined (_MSC_VER)
@@ -101,6 +104,8 @@ typedef unsigned __int64 uint64_t;
 #  include 
 #endif
 
+#endif
+
 /*
  * Boolean
  */
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] When storing 4 bit pixels, make sure only the low 4 bits are stored.

2010-03-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

In some cases we end up trying to use the STORE_4 macro with an 8 bit
values, which resulted in other pixels getting overwritten. Fix this
by always masking away the high 4 bits.
---
 pixman/pixman-access.c |   22 ++
 test/blitters-test.c   |2 +-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 389cf2a..fa0a267 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -2445,9 +2445,12 @@ store_scanline_x4a4 (bits_image_t *  image,
 do \
 {  \
int bo = 4 * (o);   \
-   STORE_8 (img, l, bo, (bo & 4 ?  \
- (FETCH_8 (img, l, bo) & 0xf0) | (v) : \
- (FETCH_8 (img, l, bo) & 0x0f) | ((v) << 4))); \
+   int v4 = (v) & 0x0f;\
+   \
+   STORE_8 (img, l, bo, (  \
+bo & 4 ?   \
+(FETCH_8 (img, l, bo) & 0xf0) | (v4) : \
+(FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4)));   \
 } while (0)
 #else
 
@@ -2455,9 +2458,12 @@ store_scanline_x4a4 (bits_image_t *  image,
 do \
 {  \
int bo = 4 * (o);   \
-   STORE_8 (img, l, bo, (bo & 4 ?  \
- (FETCH_8 (img, l, bo) & 0x0f) | ((v) << 4) : \
- (FETCH_8 (img, l, bo) & 0xf0) | (v)));\
+   int v4 = (v) & 0x0f;\
+   \
+   STORE_8 (img, l, bo, (  \
+bo & 4 ?   \
+(FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) :\
+(FETCH_8 (img, l, bo) & 0xf0) | (v4)));\
 } while (0)
 #endif
 
@@ -2484,11 +2490,11 @@ store_scanline_r1g2b1 (bits_image_t *  image,
 {
 uint32_t *bits = image->bits + image->rowstride * y;
 int i;
-
+
 for (i = 0; i < width; ++i)
 {
uint32_t pixel;
-   
+
SPLIT (values[i]);
pixel = (((r >> 4) & 0x8) |
 ((g >> 5) & 0x6) |
diff --git a/test/blitters-test.c b/test/blitters-test.c
index c11917d..5e33031 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -482,7 +482,7 @@ main (int argc, char *argv[])
/* Predefined value for running with all the fastpath functions
   disabled. It needs to be updated every time when changes are
   introduced to this program or behavior of pixman changes! */
-   if (crc == 0xEF7A1179)
+   if (crc == 0xA058F792)
{
printf ("blitters test passed\n");
}
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 0/2] Thread local support on OS X

2010-03-16 Thread Søren Sandmann
So apparently OS X does not support __thread which means current
pixman does not compile there. See this:

   http://tinderbox.x.org/builds/2010-03-16-0022/logs/pixman/#build

The following patches add some macros that expand to various types of
thread local support. On Linux, Unix, and Windows they continue to
expand to __thread and __declspec(thread), but on OS X they expand to
a set of functions that use pthread_once() and
pthread_get/setspecific() for thread local data.

I'm not particularly happy with this, but the only alternative seems
to be to just disable the fast path cache there. If anyone has better
ideas, I'm interested.

I have tested that the pthread_get/setspecific() code works on Linux,
but I don't have any way to test it on OS X. I'd appreciate if someone
can test it there. 

Of course, comments on the code are welcome too.


Thanks,
Soren

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 1/2] Add checks for various types of thread local storage.

2010-03-16 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

OS X does not support __thread, so we have to check for it before
using it.  It does however support pthread_get/setspecific(), so if we
don't have __thread, check if those are available.
---
 configure.ac   |   80 
 pixman/Makefile.am |2 +-
 2 files changed, 81 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index fed97b1..0bf5658 100644
--- a/configure.ac
+++ b/configure.ac
@@ -523,6 +523,86 @@ if test x$have_posix_memalign = xyes; then
AC_DEFINE(HAVE_POSIX_MEMALIGN, 1, [Whether we have posix_memalign()])
 fi
 
+dnl =
+dnl Thread local storage
+
+support_for__thread=no
+
+AC_MSG_CHECKING(for __thread)
+AC_COMPILE_IFELSE([
+__thread int x ;
+int main () { return 0; }
+], support_for__thread=yes)
+
+if test $support_for__thread = yes; then 
+   AC_DEFINE([TOOLCHAIN_SUPPORTS__THREAD],[],[Whether the tool chain supports 
__thread])
+fi
+
+AC_MSG_RESULT($support_for__thread)
+
+dnl posix tls
+
+if test $support_for__thread = no; then
+
+support_for_pthread_setspecific=no
+   
+AC_MSG_CHECKING(for pthread_setspecific)
+
+save_LDFLAGS=$LDFLAGS
+
+LDFLAGS="-pthread"
+
+AC_LINK_IFELSE([
+#include 
+
+#include 
+#include 
+
+static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+static pthread_key_t key;
+
+static void
+make_key (void)
+{
+pthread_key_create (&key, NULL);
+}
+
+int
+main ()
+{
+void *value = NULL;
+
+if (pthread_once (&once_control, make_key) != 0)
+{
+   value = NULL;
+}
+else
+{
+   value = pthread_getspecific (key);
+   if (!value)
+   {
+   value = malloc (100);
+   pthread_setspecific (key, value);
+   }
+}
+}
+], support_for_pthread_setspecific=yes);
+
+LDFLAGS=$save_LDFLAGS
+
+if test $support_for_pthread_setspecific = yes; then
+   PTHREAD_LDFLAGS="-pthread"
+   AC_DEFINE([HAVE_PTHREAD_SETSPECIFIC], [], [Whether pthread_setspecific() is 
supported])
+fi
+
+AC_MSG_RESULT($support_for_pthread_setspecific);
+
+fi
+
+AC_SUBST(TOOLCHAIN_SUPPORTS__THREAD)
+AC_SUBST(HAVE_PTHREAD_SETSPECIFIC)
+AC_SUBST(PTHREAD_LDFLAGS)
+
 AC_OUTPUT([pixman-1.pc
pixman-1-uninstalled.pc
Makefile
diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 8ac6827..5a0e7a9 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -1,5 +1,5 @@
 lib_LTLIBRARIES = libpixman-1.la
-libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined
+libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined 
@PTHREAD_LDFLAGS@ 
 libpixman_1_la_LIBADD = @DEP_LIBS@ -lm
 libpixman_1_la_SOURCES =   \
pixman.h\
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 2/2] Add PIXMAN_DEFINE_THREAD_LOCAL() and PIXMAN_GET_THREAD_LOCAL() macros

2010-03-16 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

These macros hide the various types of thread local support. On Linux
and Unix, they expand to just __thread. On Microsoft Visual C++, they
expand to __declspec(thread).

On OS X and other systems that don't have __thread, they expand to a
complicated concoction that uses pthread_once() and
pthread_get/set_specific() to get thread local variables.
---
 configure.ac |2 +-
 pixman/pixman-compiler.h |   63 +
 pixman/pixman.c  |   37 ---
 3 files changed, 80 insertions(+), 22 deletions(-)

diff --git a/configure.ac b/configure.ac
index 0bf5658..d790bf3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -532,7 +532,7 @@ AC_MSG_CHECKING(for __thread)
 AC_COMPILE_IFELSE([
 __thread int x ;
 int main () { return 0; }
-], support_for__thread=yes)
+], support_for__thread=no)
 
 if test $support_for__thread = yes; then 
AC_DEFINE([TOOLCHAIN_SUPPORTS__THREAD],[],[Whether the tool chain supports 
__thread])
diff --git a/pixman/pixman-compiler.h b/pixman/pixman-compiler.h
index 5aeef86..a4e3f88 100644
--- a/pixman/pixman-compiler.h
+++ b/pixman/pixman-compiler.h
@@ -70,11 +70,62 @@
 #endif
 
 /* TLS */
-#if (defined (__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR >= 3) || __GNUC__ > 
3)) || defined(__SUNPRO_C)
-#define THREAD_LOCAL __thread
-#elif defined (_MSC_VER)
-#define THREAD_LOCAL __declspec(thread)
+#if defined(TOOLCHAIN_SUPPORTS__THREAD)
+
+#   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)  \
+static __thread type name
+#   define PIXMAN_GET_THREAD_LOCAL(name)   \
+(&name)
+
+#elif defined(_MSC_VER)
+
+#   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)  \
+static __declspec(thread) type name
+#   define PIXMAN_GET_THREAD_LOCAL(name)   \
+(&name)
+
+#elif defined(HAVE_PTHREAD_SETSPECIFIC)
+
+#include 
+
+#  define PIXMAN_DEFINE_THREAD_LOCAL(type, name)   \
+static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
+static pthread_key_t tls_ ## name ## _key; \
+   \
+static void
\
+tls_ ## name ## _make_key (void)   \
+{  \
+   pthread_key_create (&tls_ ## name ## _key, NULL);   \
+}  \
+   \
+static type *  \
+tls_ ## name ## _alloc (key)   \
+{  \
+   type *value = malloc (sizeof (type));   \
+   if (value)  \
+   pthread_setspecific (key, value);   \
+   return value;   \
+}  \
+   \
+static force_inline type * \
+tls_ ## name ## _get (key) \
+{  \
+   type *value = NULL; \
+   if (pthread_once (&tls_ ## name ## _once_control,   \
+ tls_ ## name ## _make_key) == 0)  \
+   {   \
+   value = pthread_getspecific (tls_ ## name ## _key); \
+   if (!value) \
+   value = tls_ ## name ## _alloc (key);   \
+   }   \
+   return value;   \
+}
+
+#   define PIXMAN_GET_THREAD_LOCAL(name)   \
+tls_ ## name ## _get (tls_ ## name ## _key)
+
 #else
-#warning "unknown compiler"
-#define THREAD_LOCAL __thread
+
+#error "Unknown thread local support for this system"
+
 #endif
diff --git a/pixman/pixman.c b/pixman/pixman.c
index c71617e..68483a0 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -499,6 +499,15 @@ image_covers (pixman_image_t *image,
 return TRUE;
 }
 
+#define N_CACHED_FAST_PATHS 8
+
+typedef struct
+{
+pixman_fast_path_t cache [N_CACHED_FAST_PATHS];
+} cache_t;
+
+PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cac

[Pixman] [ANNOUNCE] pixman stable release 0.18.0 now available

2010-04-01 Thread Søren Sandmann

A new major stable release 0.18.0 of the pixman library is now available.


New features:
-
- Support for creating regions from images [Alexander Larsson]
- Improved support for images larger than 16 bits [Benjamin Otte]


Performance improvements:
-

Performance was a major theme of this release. Optimizations include:

- Faster rescaling with nearest filter [Alexander Larsson, Siarhei
Siamashka, Søren Sandmann Pedersen]
- Faster rescaling with bilinear filter [André Tupinambá]
- Many new fast paths for ARM NEON [Siarhei Siamashka]
- Faster unantialised text rendering [Siarhei Siamashka]
- Reduced overhead in fast path lookup [Søren]

Results from a number of benchmarks in the cairo performance test
suite on x86 and ARM. A number such as 1.84x means that on that particular
benchmark pixman 0.18.0 runs 1.84 times faster than pixman 0.16.6.

x86
evolution .. image ███▋ 1.06x
image16 ███▍ 1.13x
xlib ██▌ 1.04x
firefox-planet-gnome ... image ███▌ 1.45x
image16 ██▌ 1.20x
xlib ██▎ 1.29x
firefox-talos-gfx .. image ▊ 1.84x
image16 ███▋ 2.00x
xlib ▎ 1.35x
firefox-talos-svg .. image ▍ 1.07x
image16 ██▋ 1.04x
xlib ███▊ 1.06x
gnome-system-monitor ... image ███▌ 2.00x
image16 ███▌ 2.00x
xlib ▋ 1.01x
gnome-terminal-vim . image █▎ 1.09x
image16 █▊ 1.28x
xlib ███▋ 1.23x
poppler  image  
2.73x

image16  2.73x
xlib ▉ 2.09x
gvim ... image █ 1.02x
image16 ▊ 0.99x
xlib ██▍ 1.04x
swfdec-giant-steps . image ██▉ 1.05x
image16 ██▌ 1.12x
xlib ▎ 1.00x
swfdec-youtube . image ▌ 1.48x
image16 ██▉ 1.12x
xlib ███▋ 1.45x

ARM
evolution .. image ██▎ 1.04x
image16 ██▎ 1.04x
xlib ▒▒▒▏ 0.95x
firefox-planet-gnome ... image █▋ 1.27x
image16 ██▎ 1.04x
xlib ██▋ 1.30x
firefox-talos-gfx .. image █▋ 1.39x
image16 ███▌ 1.13x
xlib ███ 1.12x
firefox-talos-svg .. image █▋ 1.18x
image16 ▌ 1.16x
xlib ███▉ 1.14x
gnome-system-monitor ... image ███▏ 1.75x
image16 ██▋ 1.73x
xlib ▊ 1.08x
gnome-terminal-vim . image ██▎ 1.11x
image16 ▎ 1.07x
xlib ▍ 1.07x
poppler  image ███▌ 1.60x
image16 ███▋ 1.60x
xlib ███▎ 1.32x
gvim ... image ▎ 1.00x
image16 ▒▋ 0.97x
xlib ▊ 1.01x
swfdec-giant-steps . image █▌ 1.18x
image16 ▋ 1.25x
xlib ▋ 1.16x
swfdec-youtube . image ██▌ 1.56x
image16 ███▍ 1.22x
xlib ██▉ 1.57x


Thanks to everybody who contributed to 0.18.0, including:

Alan Coopersmith, Alexander Larsson, Andrea Canciani,
André Tupinambá, Benjamin Otte, Chris Wilson, Egor Starkov,
Gaetan Nadon, Gerdus van Zyl, Guillem Jover, Jeremy Huddleston,
Jon TURNEY, Loïc Minier, M Joonas Pihlaja, Makoto Kato,
Marvin Schmidt, Pierre-Loup A. Griffais, Siarhei Siamashka,
Søren Sandmann Pedersen


Søren



tar.gz:
http://cairographics.org/releases/pixman-0.18.0.tar.gz
http://xorg.freedesktop.org/archive/individual/lib/pixman-0.18.0.tar.gz

tar.bz2:
http://xorg.freedesktop.org/archive/individual/lib/pixman-0.18.0.tar.bz2

Hashes:
MD5: a4fb870fc325be258089f1683642e976 pixman-0.18.0.tar.gz
MD5: a1b5a0a145cab653f5c1e8cf2f98f945 pixman-0.18.0.tar.bz2
SHA1: 26d204499bd78d82801db50f620bba29c2686cfc pixman-0.18.0.tar.gz
SHA1: 0ff0944b3335f156a94949842b429229e5ae1db4 pixman-0.18.0.tar.bz2

GPG signature:
http://cairographics.org/releases/pixman-0.18.0.tar.gz.sha1.asc
(signed by Søren Sandmann Pedersen )

Git:
git://git.freedesktop.org/git/pixman
tag: pixman-0.18.0

Log:
Alan Coopersmith (3):
Update Sun license notices to current X.Org standard form
Make .s target asm flag selection more portable
Add Sun cc to thread-local support checks in pixman-compiler.h

Alexander Larsson (11):
Add extern "C" guards for c++
Add pixman_image_get_destroy_data()
Move SCREEN_SHIFT_LEFT/RIGHT to pixman-private.h
Add pixman_region{32}_init_from_image
Test pixman_region32_init_from_image in region-test
Add CONVERT_0565_TO_ macro
Add CONVERT__TO_ and CONVERT_0565_TO_0565 macros
Add FAST_PATH_NO_NONE_REPEAT flag
Add FAST_PATH_SAMPLES_COVER_CLIP and FAST_PATH_16BIT_SAFE
Add specialized fast nearest scalers
Use the right format for the OVER__565 fast path

Andrea Canciani (1):
Fix composite on big-endian systems.

André Tupinambá (2):
Speed up bilinear interpolation.
Add fast path scaled, bilinear fetcher.

Benjamin Otte (11):
Fix compile warnings
Add default cases for all switch statements
--enable-maintainer-mode is

[Pixman] [ANNOUNCE] pixman release 0.18.0 now available [fixed formatting]

2010-04-01 Thread Søren Sandmann

[Apologies for the previous misformatted announce email. Hopefully
 this one will get through correctly].

A new major stable release 0.18.0 of the pixman library is now available.

New features:
-
- Support for creating regions from images [Alexander Larsson]
- Improved support for images larger than 16 bits [Benjamin Otte]


Performance improvements:
-

Performance was a major theme of this release. Optimizations include:

- Faster rescaling with nearest filter [Alexander Larsson, Siarhei
  Siamashka, Søren Sandmann Pedersen]
- Faster rescaling with bilinear filter [André Tupinambá]
- Many new fast paths for ARM NEON [Siarhei Siamashka]
- Faster unantialised text rendering [Siarhei Siamashka]
- Reduced overhead in fast path lookup [Søren]

Results from a number of benchmarks in the cairo performance test
suite on x86 and ARM. A number such as 1.84x means that on that particular
benchmark pixman 0.18.0 runs 1.84 times faster than pixman 0.16.6.

 x86
 evolution .. image ███▋ 1.06x
image16 ███▍ 1.13x
   xlib ██▌ 1.04x
 firefox-planet-gnome ... image ███▌ 1.45x
image16 ██▌ 1.20x
   xlib ██▎ 1.29x
 firefox-talos-gfx .. image ▊ 1.84x
image16 ███▋ 2.00x
   xlib ▎ 1.35x
 firefox-talos-svg .. image ▍ 1.07x
image16 ██▋ 1.04x
   xlib ███▊ 1.06x
 gnome-system-monitor ... image ███▌ 2.00x
image16 ███▌ 2.00x
   xlib ▋ 1.01x
 gnome-terminal-vim . image █▎ 1.09x
image16 █▊ 1.28x
   xlib ███▋ 1.23x
 poppler  image  2.73x
image16  2.73x
   xlib ▉ 2.09x
 gvim ... image █ 1.02x
image16 ▊ 0.99x
   xlib ██▍ 1.04x
 swfdec-giant-steps . image ██▉ 1.05x
image16 ██▌ 1.12x
   xlib ▎ 1.00x
 swfdec-youtube . image ▌ 1.48x
image16 ██▉ 1.12x
   xlib ███▋ 1.45x

 ARM
 evolution .. image ██▎ 1.04x
image16 ██▎ 1.04x
   xlib ▒▒▒▏ 0.95x
 firefox-planet-gnome ... image █▋ 1.27x
image16 ██▎ 1.04x
   xlib ██▋ 1.30x
 firefox-talos-gfx .. image █▋ 1.39x
image16 ███▌ 1.13x
   xlib ███ 1.12x
 firefox-talos-svg .. image █▋ 1.18x
image16 ▌ 1.16x
   xlib ███▉ 1.14x
 gnome-system-monitor ... image ███▏ 1.75x
image16 ██▋ 1.73x
   xlib ▊ 1.08x
 gnome-terminal-vim . image ██▎ 1.11x
image16 ▎ 1.07x
   xlib ▍ 1.07x
 poppler  image ███▌ 1.60x
image16 ███▋ 1.60x
   xlib ███▎ 1.32x
 gvim ... image ▎ 1.00x
image16 ▒▋ 0.97x
   xlib ▊ 1.01x
 swfdec-giant-steps . image █▌ 1.18x
image16 ▋ 1.25x
   xlib ▋ 1.16x
 swfdec-youtube . image ██▌ 1.56x
image16 ███▍ 1.22x
   xlib ██▉ 1.57x


Thanks to everybody who contributed to 0.18.0, including:

Alan Coopersmith, Alexander Larsson, Andrea Canciani,
André Tupinambá, Benjamin Otte, Chris Wilson, Egor Starkov,
Gaetan Nadon, Gerdus van Zyl, Guillem Jover, Jeremy Huddleston,
Jon TURNEY, Loïc Minier, M Joonas Pihlaja, Makoto Kato,
Marvin Schmidt, Pierre-Loup A. Griffais, Siarhei Siamashka,
Søren Sandmann Pedersen


Søren


tar.gz:
http://cairographics.org/releases/pixman-0.18.0.tar.gz
http://xorg.freedesktop.org/archive/individual/lib/pixman-0.18.0.tar.gz

tar.bz2:
http://xorg.freedesktop.org/archive/individual/lib/pixman-0.18.0.tar.bz2

Hashes:
MD5:  a4fb870fc325be258089f1683642e976  pixman-0.18.0.tar.gz
MD5:  a1b5a0a145cab653f5c1e8cf2f98f945  pixman-0.18.0.tar.bz2
SHA1

[Pixman] [PATCH 1/2] Extend blitters test to first check known failure cases

2010-04-07 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This serves to make sure we don't accidentally reintroduce old bugs.
---
 test/blitters-test.c |   43 +++
 1 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/test/blitters-test.c b/test/blitters-test.c
index 5e33031..25b3c7b 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -437,6 +437,46 @@ initialize_palette (void)
palette.ent[i] = lcg_rand() & 0xff;
 }
 
+typedef struct
+{
+uint32_t nth;
+uint32_t crc;
+} testcase_t;
+
+static testcase_t known_failures[] =
+{
+{ 592654, 0x06BF6ADE },
+};
+
+static int
+run_known_failures (void)
+{
+int i;
+
+for (i = 0; i < sizeof (known_failures) / sizeof (known_failures[0]); ++i)
+{
+   testcase_t *testcase = &(known_failures[i]);
+   uint32_t crc;
+   
+   crc = test_composite (0, testcase->nth, 0);
+
+   if (crc != testcase->crc)
+   {
+   crc = test_composite (0, testcase->nth, 1);
+   
+   printf ("Test case %d failed\n"
+   "CRC:  %08x\n"
+   "Expected: %08x\n",
+   testcase->nth,
+   crc,
+   testcase->crc);
+   return 1;
+   }
+}
+
+return 0;
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -446,6 +486,9 @@ main (int argc, char *argv[])
 
 initialize_palette();
 
+if (run_known_failures ())
+   return 1;
+
 if (argc >= 3)
 {
n1 = atoi (argv[1]);
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 2/2] [mmx] Fix mask creation bugs

2010-04-07 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This line:

mask = mask | mask >> 8 | mask >> 16 | mask >> 24;

only works when mask has 0s in the lower 24 bits, so add

 mask &= 0xff00;

before.

Reported by Todd Rinaldo on the #cairo IRC channel.
---
 pixman/pixman-mmx.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index e084e7f..d51b40c 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -1385,6 +1385,7 @@ mmx_composite_over__n_ (pixman_implementation_t 
*imp,
 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, 
src_line, 1);
 
 mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);
+mask &= 0xff00;
 mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
 vmask = load (mask);
 srca = MC (4x00ff);
@@ -1470,6 +1471,7 @@ mmx_composite_over_x888_n_ (pixman_implementation_t 
*imp,
 PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, 
src_line, 1);
 mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);
 
+mask &= 0xff00;
 mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
 vmask = load (mask);
 srca = MC (4x00ff);
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Add pixman_image_get_format() accessor

2010-04-21 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

---
 pixman/pixman-image.c |9 +
 pixman/pixman.h   |1 +
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 9b44aa9..9604bfe 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -739,6 +739,15 @@ pixman_image_get_depth (pixman_image_t *image)
 return 0;
 }
 
+PIXMAN_EXPORT pixman_format_code_t
+pixman_image_get_format (pixman_image_t *image)
+{
+if (image->type == BITS)
+   return image->bits.format;
+
+return 0;
+}
+
 uint32_t
 _pixman_image_get_solid (pixman_image_t * image,
  pixman_format_code_t format)
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 964d04a..7b95fed 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -778,6 +778,7 @@ int pixman_image_get_width   
(pixman_image_t   *image);
 int pixman_image_get_height  (pixman_image_t   
*image);
 intpixman_image_get_stride  (pixman_image_t
   *image); /* in bytes */
 intpixman_image_get_depth   (pixman_image_t
   *image);
+pixman_format_code_t pixman_image_get_format(pixman_image_t
   *image);
 pixman_bool_t  pixman_image_fill_rectangles (pixman_op_t   
op,
  pixman_image_t
   *image,
  pixman_color_t
   *color,
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] Misc patches

2010-04-24 Thread Søren Sandmann
This is a series of asssorted patches that I've had lying around for a
while.

Here's what's in it:

- Use memcpy() for SRC compositing in various cases. There was already
  a memcpy() based fast path, but it was only used for
  SRC__x888. There is no reason not to used for all copying
  between identical formats.

- Add pixman_region{,32}_intersect_rect(). We already have a
  _union_rect(), and intersecting with a rectangle is pretty common.

- SSE2 fast paths:

  - OVER xx. I have seen this on some benchmark, but I
can't remember which one. If anyone knows, please let me know.

  - OVER_REVERSE n_. Poppler uses this, presumably to composite a
white background behind an image. This fast path is a small
speed-up on the poppler cairo trace.

  - Support for 8bpp in pixman_fill_sse2(). Previously this would fall
back to MMX for no good reason.

- A bug fix: Currently we consider indexed formats opaque which is
  wrong because their palettes could contain non-opaque colors. Adding
  the over_reverse fast path triggered this because the opaqueness
  caused an ATOP_REVERSE to be strength-reduced to OVER_REVERSE.

- A patch from Benjamin to detect and use bswap_32() if it is
  available. When compiling for 486 or later, this macro expands to
  the bswap instruction.


Søren 


___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 1/7] Rename fast_composite_src_8888_x888 to fast_composite_src_memcpy()

2010-04-24 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Then generalize it and use it for SRC copying between various
identical formats.
---
 pixman/pixman-fast-path.c |   60 
 1 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index bf5b298..c4dd3a6 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1315,27 +1315,31 @@ fast_composite_solid_fill (pixman_implementation_t *imp,
 }
 
 static void
-fast_composite_src__x888 (pixman_implementation_t *imp,
-  pixman_op_t  op,
-  pixman_image_t * src_image,
-  pixman_image_t * mask_image,
-  pixman_image_t * dst_image,
-  int32_t  src_x,
-  int32_t  src_y,
-  int32_t  mask_x,
-  int32_t  mask_y,
-  int32_t  dest_x,
-  int32_t  dest_y,
-  int32_t  width,
-  int32_t  height)
+fast_composite_src_memcpy (pixman_implementation_t *imp,
+  pixman_op_t  op,
+  pixman_image_t * src_image,
+  pixman_image_t * mask_image,
+  pixman_image_t * dst_image,
+  int32_t  src_x,
+  int32_t  src_y,
+  int32_t  mask_x,
+  int32_t  mask_y,
+  int32_t  dest_x,
+  int32_t  dest_y,
+  int32_t  width,
+  int32_t  height)
 {
-uint32_t*dst;
-uint32_t*src;
+int bpp = PIXMAN_FORMAT_BPP (dst_image->bits.format) / 8;
+uint32_t n_bytes = width * bpp;
 int dst_stride, src_stride;
-uint32_t n_bytes = width * sizeof (uint32_t);
+uint8_t*dst;
+uint8_t*src;
+
+src_stride = src_image->bits.rowstride * 4;
+dst_stride = dst_image->bits.rowstride * 4;
 
-PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src, 
1);
-PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, 
dst, 1);
+src = (uint8_t *)src_image->bits.bits + src_y * src_stride + src_x * bpp;
+dst = (uint8_t *)dst_image->bits.bits + dest_y * dst_stride + dest_x * bpp;
 
 while (height--)
 {
@@ -1792,10 +1796,22 @@ static const pixman_fast_path_t c_fast_paths[] =
 PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, 
fast_composite_solid_fill),
 PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill),
 PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill),
-PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, 
fast_composite_src__x888),
-PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, 
fast_composite_src__x888),
-PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, 
fast_composite_src__x888),
-PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, 
fast_composite_src__x888),
+PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, b8g8r8a8, null, b8g8r8x8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, b8g8r8a8, null, b8g8r8a8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, b8g8r8x8, null, b8g8r8x8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, b8g8r8, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, 
fast_composite_src_memcpy),
+PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, fast_composite_src_memcpy),
 PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, 
fast_composit

[Pixman] [PATCH 2/7] Add pixman_region{,32}_intersect_rect()

2010-04-24 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

---
 pixman/pixman-region.c |   18 ++
 pixman/pixman.h|   13 -
 2 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index a6a4005..3ea88a0 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -1329,6 +1329,24 @@ pixman_region_union_o (region_type_t *region,
 return TRUE;
 }
 
+PIXMAN_EXPORT pixman_bool_t
+PREFIX(_intersect_rect) (region_type_t *dest,
+region_type_t *source,
+int x, int y,
+unsigned int width,
+unsigned int height)
+{
+region_type_t region;
+
+region.data = NULL;
+region.extents.x1 = x;
+region.extents.y1 = y;
+region.extents.x2 = x + width;
+region.extents.y2 = y + height;
+
+return PREFIX(_intersect) (dest, source, ®ion);
+}
+
 /* Convenience function for performing union of region with a
  * single rectangle
  */
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 7b95fed..8df5813 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -420,7 +420,6 @@ voidpixman_region_init_from_image
(pixman_region16_t *reg
 voidpixman_region_fini   (pixman_region16_t 
*region);
 
 
-
 /* manipulation */
 voidpixman_region_translate  (pixman_region16_t 
*region,
  intx,
@@ -439,6 +438,12 @@ pixman_bool_t   pixman_region_union_rect 
(pixman_region16_t *des
  inty,
  unsigned int   
width,
  unsigned int   
height);
+pixman_bool_t  pixman_region_intersect_rect (pixman_region16_t 
*dest,
+ pixman_region16_t 
*source,
+ intx,
+ inty,
+ unsigned int   
width,
+ unsigned int   
height);
 pixman_bool_t   pixman_region_subtract   (pixman_region16_t 
*reg_d,
  pixman_region16_t 
*reg_m,
  pixman_region16_t 
*reg_s);
@@ -521,6 +526,12 @@ pixman_bool_t   pixman_region32_intersect  
(pixman_region32_t *n
 pixman_bool_t   pixman_region32_union  (pixman_region32_t 
*new_reg,
pixman_region32_t 
*reg1,
pixman_region32_t 
*reg2);
+pixman_bool_t  pixman_region32_intersect_rect (pixman_region32_t 
*dest,
+   pixman_region32_t 
*source,
+   int
x,
+   int
y,
+   unsigned int   
width,
+   unsigned int   
height);
 pixman_bool_t   pixman_region32_union_rect (pixman_region32_t 
*dest,
pixman_region32_t 
*source,
int
x,
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 3/7] Add an over_8888_8888_8888 sse2 fast path.

2010-04-24 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

---
 pixman/pixman-sse2.c |  168 ++
 1 files changed, 168 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 946e7ba..09da14d 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -5765,6 +5765,173 @@ sse2_composite_over__8_ 
(pixman_implementation_t *imp,
 _mm_empty ();
 }
 
+static void
+sse2_composite_over___ (pixman_implementation_t *imp,
+   pixman_op_t  op,
+   pixman_image_t * src_image,
+   pixman_image_t * mask_image,
+   pixman_image_t * dst_image,
+   int32_t  src_x,
+   int32_t  src_y,
+   int32_t  mask_x,
+   int32_t  mask_y,
+   int32_t  dest_x,
+   int32_t  dest_y,
+   int32_t  width,
+   int32_t  height)
+{
+uint32_t*src, *src_line, s;
+uint32_t*dst, *dst_line, d;
+uint32_t*mask, *mask_line;
+uint32_tm;
+int src_stride, mask_stride, dst_stride;
+int32_t w;
+
+__m128i xmm_src, xmm_src_lo, xmm_src_hi, xmm_srca_lo, xmm_srca_hi;
+__m128i xmm_dst, xmm_dst_lo, xmm_dst_hi;
+__m128i xmm_mask, xmm_mask_lo, xmm_mask_hi;
+
+PIXMAN_IMAGE_GET_LINE (
+   dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+PIXMAN_IMAGE_GET_LINE (
+   mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
+PIXMAN_IMAGE_GET_LINE (
+   src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
+
+while (height--)
+{
+src = src_line;
+src_line += src_stride;
+dst = dst_line;
+dst_line += dst_stride;
+mask = mask_line;
+mask_line += mask_stride;
+
+w = width;
+
+/* call prefetch hint to optimize cache load*/
+cache_prefetch ((__m128i *)src);
+cache_prefetch ((__m128i *)dst);
+cache_prefetch ((__m128i *)mask);
+
+while (w && (unsigned long)dst & 15)
+{
+   uint32_t sa;
+
+s = *src++;
+m = (*mask++) >> 24;
+d = *dst;
+
+   sa = s >> 24;
+
+   if (m)
+   {
+   if (sa == 0xff && m == 0xff)
+   {
+   *dst = s;
+   }
+   else
+   {
+   __m64 ms, md, ma, msa;
+
+   ma = expand_alpha_rev_1x64 (load_32_1x64 (m));
+   ms = unpack_32_1x64 (s);
+   md = unpack_32_1x64 (d);
+
+   msa = expand_alpha_rev_1x64 (load_32_1x64 (sa));
+
+   *dst = pack_1x64_32 (in_over_1x64 (&ms, &msa, &ma, &md));
+   }
+   }
+
+   dst++;
+w--;
+}
+
+/* call prefetch hint to optimize cache load*/
+cache_prefetch ((__m128i *)src);
+cache_prefetch ((__m128i *)dst);
+cache_prefetch ((__m128i *)mask);
+
+while (w >= 4)
+{
+/* fill cache line with next memory */
+cache_prefetch_next ((__m128i *)src);
+cache_prefetch_next ((__m128i *)dst);
+cache_prefetch_next ((__m128i *)mask);
+
+   xmm_mask = load_128_unaligned ((__m128i*)mask);
+
+   if (!is_transparent (xmm_mask))
+   {
+   xmm_src = load_128_unaligned ((__m128i*)src);
+
+   if (is_opaque (xmm_mask) && is_opaque (xmm_src))
+   {
+   save_128_aligned ((__m128i *)dst, xmm_src);
+   }
+   else
+   {
+   xmm_dst = load_128_aligned ((__m128i *)dst);
+
+   unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi);
+   unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi);
+   unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi);
+
+   expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, &xmm_srca_lo, 
&xmm_srca_hi);
+   expand_alpha_2x128 (xmm_mask_lo, xmm_mask_hi, &xmm_mask_lo, 
&xmm_mask_hi);
+
+   in_over_2x128 (&xmm_src_lo, &xmm_src_hi, &xmm_srca_lo, 
&xmm_srca_hi,
+  &xmm_mask_lo, &xmm_mask_hi, &xmm_dst_lo, 
&xmm_dst_hi);
+
+   save_128_aligned ((__m128i*)dst, pack_2x128_128 
(xmm_dst_lo, xmm_dst_hi));
+   }
+ 

[Pixman] [PATCH 4/7] Don't consider indexed formats opaque.

2010-04-24 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The indexed formats have 0 bits of alpha, but can't be considered
opaque because there may be non-opaque colors in the palette.
---
 pixman/pixman-image.c |6 --
 test/blitters-test.c  |2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 9604bfe..6b0dc6d 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -394,8 +394,10 @@ compute_image_info (pixman_image_t *image)
}
}
 
-   if (image->common.repeat != PIXMAN_REPEAT_NONE &&
-   !PIXMAN_FORMAT_A (image->bits.format))
+   if (image->common.repeat != PIXMAN_REPEAT_NONE  
&&
+   !PIXMAN_FORMAT_A (image->bits.format)   
&&
+   PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY 
&&
+   PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
{
flags |= FAST_PATH_IS_OPAQUE;
}
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 5e33031..18f871e 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -482,7 +482,7 @@ main (int argc, char *argv[])
/* Predefined value for running with all the fastpath functions
   disabled. It needs to be updated every time when changes are
   introduced to this program or behavior of pixman changes! */
-   if (crc == 0xA058F792)
+   if (crc == 0x8F9F7DC1)
{
printf ("blitters test passed\n");
}
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 5/7] sse2: Add sse2_composite_over_reverse_n_8888

2010-04-24 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This is a small speed-up for the poppler benchmark:

Before:
[ # ]  backend test   min(s) median(s) stddev. count
[  0]image  poppler4.4434.474   0.31%6/6

After:
[ # ]  backend test   min(s) median(s) stddev. count
[  0]image  poppler4.2244.248   0.42%6/6
---
 pixman/pixman-sse2.c |  104 ++
 1 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 09da14d..3f474d7 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -5766,6 +5766,106 @@ sse2_composite_over__8_ 
(pixman_implementation_t *imp,
 }
 
 static void
+sse2_composite_over_reverse_n_ (pixman_implementation_t *imp,
+   pixman_op_t  op,
+   pixman_image_t * src_image,
+   pixman_image_t * mask_image,
+   pixman_image_t * dst_image,
+   int32_t  src_x,
+   int32_t  src_y,
+   int32_t  mask_x,
+   int32_t  mask_y,
+   int32_t  dest_x,
+   int32_t  dest_y,
+   int32_t  width,
+   int32_t  height)
+{
+uint32_t src;
+uint32_t*dst_line, *dst;
+__m128i xmm_src;
+__m128i xmm_dst, xmm_dst_lo, xmm_dst_hi;
+__m128i xmm_dsta_hi, xmm_dsta_lo;
+int dst_stride;
+int32_t w;
+
+src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+
+if (src == 0)
+   return;
+
+PIXMAN_IMAGE_GET_LINE (
+   dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+
+xmm_src = expand_pixel_32_1x128 (src);
+
+while (height--)
+{
+   dst = dst_line;
+
+   /* call prefetch hint to optimize cache load*/
+   cache_prefetch ((__m128i*)dst);
+
+   dst_line += dst_stride;
+   w = width;
+
+   while (w && (unsigned long)dst & 15)
+   {
+   __m64 vd;
+
+   vd = unpack_32_1x64 (*dst);
+
+   *dst = pack_1x64_32 (over_1x64 (vd, expand_alpha_1x64 (vd),
+   _mm_movepi64_pi64 (xmm_src)));
+   w--;
+   dst++;
+   }
+
+   cache_prefetch ((__m128i*)dst);
+
+   while (w >= 4)
+   {
+   __m128i tmp_lo, tmp_hi;
+
+   /* fill cache line with next memory */
+   cache_prefetch_next ((__m128i*)(dst + 4));
+
+   xmm_dst = load_128_aligned ((__m128i*)dst);
+
+   unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi);
+   expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, &xmm_dsta_lo, 
&xmm_dsta_hi);
+
+   tmp_lo = xmm_src;
+   tmp_hi = xmm_src;
+
+   over_2x128 (&xmm_dst_lo, &xmm_dst_hi,
+   &xmm_dsta_lo, &xmm_dsta_hi,
+   &tmp_lo, &tmp_hi);
+
+   save_128_aligned (
+   (__m128i*)dst, pack_2x128_128 (tmp_lo, tmp_hi));
+
+   w -= 4;
+   dst += 4;
+   }
+
+   while (w)
+   {
+   __m64 vd;
+
+   vd = unpack_32_1x64 (*dst);
+
+   *dst = pack_1x64_32 (over_1x64 (vd, expand_alpha_1x64 (vd),
+   _mm_movepi64_pi64 (xmm_src)));
+   w--;
+   dst++;
+   }
+
+}
+
+_mm_empty ();
+}
+
+static void
 sse2_composite_over___ (pixman_implementation_t *imp,
pixman_op_t  op,
pixman_image_t * src_image,
@@ -5982,6 +6082,10 @@ static const pixman_fast_path_t sse2_fast_paths[] =
 PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, x8r8g8b8, 
sse2_composite_copy_area),
 PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, x8b8g8r8, 
sse2_composite_copy_area),
 
+/* PIXMAN_OP_OVER_REVERSE */
+PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, 
sse2_composite_over_reverse_n_),
+PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, 
sse2_composite_over_reverse_n_),
+
 /* PIXMAN_OP_ADD */
 PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, 
sse2_composite_add_n___ca),
 PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, sse2_composite_add_8000_8000),
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 6/7] Add support for 8bpp to pixman_fill_sse2()

2010-04-24 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

---
 pixman/pixman-sse2.c |   39 ++-
 1 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 3f474d7..d5349d7 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -3981,24 +3981,40 @@ pixman_fill_sse2 (uint32_t *bits,
 
 __m128i xmm_def;
 
-if (bpp != 16 && bpp != 32)
-   return FALSE;
+if (bpp == 8)
+{
+   uint8_t b;
+   uint16_t w;
+
+   stride = stride * (int) sizeof (uint32_t) / 1;
+   byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x);
+   byte_width = width;
+   stride *= 1;
 
-if (bpp == 16)
+   b = data & 0xff;
+   w = (b << 8) | b;
+   data = (w << 16) | w;
+}
+else if (bpp == 16)
 {
stride = stride * (int) sizeof (uint32_t) / 2;
byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
byte_width = 2 * width;
stride *= 2;
+
 data = (data & 0x) * 0x00010001;
 }
-else
+else if (bpp == 32)
 {
stride = stride * (int) sizeof (uint32_t) / 4;
byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
byte_width = 4 * width;
stride *= 4;
 }
+else
+{
+   return FALSE;
+}
 
 cache_prefetch ((__m128i*)byte_line);
 xmm_def = create_mask_2x32_128 (data, data);
@@ -4010,9 +4026,15 @@ pixman_fill_sse2 (uint32_t *bits,
byte_line += stride;
w = byte_width;
 
-
cache_prefetch_next ((__m128i*)d);
 
+   while (w >= 1 && ((unsigned long)d & 1))
+   {
+   *(uint8_t *)d = data;
+   w -= 1;
+   d += 1;
+   }
+
while (w >= 2 && ((unsigned long)d & 3))
{
*(uint16_t *)d = data;
@@ -4095,6 +4117,13 @@ pixman_fill_sse2 (uint32_t *bits,
w -= 2;
d += 2;
}
+
+   if (w >= 1)
+   {
+   *(uint8_t *)d = data;
+   w -= 1;
+   d += 1;
+   }
 }
 
 _mm_empty ();
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 7/7] Add bswap() macros and use them

2010-04-24 Thread Søren Sandmann
From: Benjamin Otte 

Code taken from Cairo.
---
 configure.ac|1 +
 pixman/pixman-access.c  |   35 +--
 pixman/pixman-private.h |   18 ++
 3 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/configure.ac b/configure.ac
index aabe721..7aed963 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,6 +74,7 @@ AC_PROG_CC
 AM_PROG_AS
 AC_PROG_LIBTOOL
 AC_CHECK_FUNCS([getisax])
+AC_CHECK_HEADERS(byteswap.h)
 AC_C_BIGENDIAN
 AC_C_INLINE
 
diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index fa0a267..5e203f6 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -184,11 +184,8 @@ fetch_scanline_b8g8r8a8 (pixman_image_t *image,
 while (pixel < end)
 {
uint32_t p = READ (image, pixel++);
-
-   *buffer++ = (((p & 0xff00) >> 24)   |
-((p & 0x00ff) >> 8)|
-((p & 0xff00) << 8)|
-((p & 0x00ff) << 24));
+   
+   *buffer++ = bswap_32 (p);
 }
 }
 
@@ -209,10 +206,7 @@ fetch_scanline_b8g8r8x8 (pixman_image_t *image,
 {
uint32_t p = READ (image, pixel++);

-   *buffer++ = (0xff00 |
-((p & 0xff00) >> 24)   |
-((p & 0x00ff) >> 8)|
-((p & 0xff00) << 8));
+   *buffer++ = 0xff00 | bswap_32 (p);
 }
 }
 
@@ -1285,10 +1279,7 @@ fetch_pixel_b8g8r8a8 (bits_image_t *image,
 uint32_t *bits = image->bits + line * image->rowstride;
 uint32_t pixel = READ (image, (uint32_t *)bits + offset);
 
-return ((pixel & 0xff00) >> 24 |
-   (pixel & 0x00ff) >> 8 |
-   (pixel & 0xff00) << 8 |
-   (pixel & 0x00ff) << 24);
+return bswap_32 (pixel);
 }
 
 static uint32_t
@@ -1299,10 +1290,7 @@ fetch_pixel_b8g8r8x8 (bits_image_t *image,
 uint32_t *bits = image->bits + line * image->rowstride;
 uint32_t pixel = READ (image, (uint32_t *)bits + offset);
 
-return ((0xff00) |
-   (pixel & 0xff00) >> 24 |
-   (pixel & 0x00ff) >> 8 |
-   (pixel & 0xff00) << 8);
+return 0xff00 | bswap_32 (pixel);
 }
 
 static uint32_t
@@ -1997,11 +1985,8 @@ store_scanline_b8g8r8a8 (bits_image_t *  image,
 
 for (i = 0; i < width; ++i)
 {
-   WRITE (image, pixel++,
-  ((values[i] >> 24) & 0x00ff) |
-  ((values[i] >>  8) & 0xff00) |
-  ((values[i] <<  8) & 0x00ff) |
-  ((values[i] << 24) & 0xff00));
+uint32_t p = bswap_32 (values[i]);
+   WRITE (image, pixel++, p);
 }
 }
 
@@ -2018,10 +2003,8 @@ store_scanline_b8g8r8x8 (bits_image_t *  image,
 
 for (i = 0; i < width; ++i)
 {
-   WRITE (image, pixel++,
-  ((values[i] >>  8) & 0xff00) |
-  ((values[i] <<  8) & 0x00ff) |
-  ((values[i] << 24) & 0xff00));
+uint32_t p = bswap_32 (values[i]);
+   WRITE (image, pixel++, p);
 }
 }
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d5767af..c4f5064 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -686,6 +686,24 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
 #  define MAX(a, b) ((a > b) ? a : b)
 #endif
 
+/* Byte swapping */
+#if HAVE_BYTESWAP_H
+# include 
+#endif
+#ifndef bswap_16
+# define bswap_16(p) \
+   (uint16_t)(p)) & 0x00ff) << 8) | \
+ (((uint16_t)(p))   >> 8));
+#endif
+#ifndef bswap_32
+# define bswap_32(p) \
+ (uint32_t)(p)) & 0x00ff) << 24) | \
+ uint32_t)(p)) & 0xff00) << 8)  | \
+ uint32_t)(p)) & 0x00ff) >> 8)  | \
+ uint32_t)(p)))  >> 24));
+#endif
+
+
 /* Integer division that rounds towards -infinity */
 #define DIV(a, b) \
 a) < 0) == ((b) < 0)) ? (a) / (b) :\
-- 
1.7.0.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] MinGW thread local storage

2010-05-03 Thread Søren Sandmann

Hi,

The patches below are supposed to fix the thread local storage issue
on MinGW 32. Apparently, __thread is "supported" in the latest GCC,
but doesn't actually work. The first patch here simply disables
__thread if MinGW32 is detected.

The second patch is based on Tor's code from here:

http://lists.freedesktop.org/archives/pixman/2010-April/000160.html

Sven Goericke tested a tarball with these patches applied, so it
apparently works, but more testing from people using MinGW32 would be
appreciated.

Also, I would still like to know if which pixman identifiers the
 file is clashing with; maybe we can just rename those.



Soren
___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Don't use __thread on MinGW.

2010-05-03 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

It is apparently broken. See this:

http://mingw-users.1079350.n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-thread-specifier-not-working-td3440749.html

We'll need to support thread local storage on MinGW32 some other way.

Cc: t...@iki.fi
---
 configure.ac |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/configure.ac b/configure.ac
index aabe721..c9d0c66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -524,6 +524,9 @@ support_for__thread=no
 
 AC_MSG_CHECKING(for __thread)
 AC_COMPILE_IFELSE([
+#ifdef __MINGW32__
+#error MinGW has broken __thread support
+#endif
 __thread int x ;
 int main () { return 0; }
 ], support_for__thread=yes)
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Add macros for thread local storage on MinGW 32

2010-05-03 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

These macros are identical to the ones that Tor Lillqvist posted here:

http://lists.freedesktop.org/archives/pixman/2010-April/000160.html

with one exception: the variable is allocated with calloc() and not
malloc().

Cc: t...@iki.fi
---
 pixman/pixman-compiler.h |   65 ++
 1 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-compiler.h b/pixman/pixman-compiler.h
index 531c8c9..1a1350d 100644
--- a/pixman/pixman-compiler.h
+++ b/pixman/pixman-compiler.h
@@ -77,6 +77,71 @@
 #   define PIXMAN_GET_THREAD_LOCAL(name)   \
 (&name)
 
+#elif defined(__MINGW32__) && !defined(__WIN64)
+
+/* We can't include  as it causes carious clashes with
+ * identifiers in pixman, sigh. So just declare the functions we need
+ * here.
+ */
+extern __stdcall long InterlockedCompareExchange(long volatile *, long, long);
+#define InterlockedCompareExchangePointer(d,e,c)   \
+(void *)InterlockedCompareExchange((long volatile 
*)(d),(long)(e),(long)(c))
+extern __stdcall int TlsAlloc (void);
+extern __stdcall void *TlsGetValue (unsigned);
+extern __stdcall int TlsSetValue (unsigned, void *);
+extern __stdcall void *CreateMutexA(void *, int, char *);
+extern __stdcall int CloseHandle(void *);
+extern __stdcall unsigned WaitForSingleObject (void *, unsigned);
+extern __stdcall int ReleaseMutex (void *);
+
+#   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)  \
+static volatile int tls_ ## name ## _initialized = 0;  \
+static void *tls_ ## name ## _mutex = NULL;
\
+static unsigned tls_ ## name ## _index;\
+   \
+static type *  \
+tls_ ## name ## _alloc (void)  \
+{  \
+type *value = calloc (1, sizeof (type));   \
+if (value) \
+TlsSetValue (tls_ ## name ## _index, value);   \
+return value;  \
+}  \
+   \
+static force_inline type * \
+tls_ ## name ## _get (void)
\
+{  \
+   type *value;\
+   if (!tls_ ## name ## _initialized)  \
+   {   \
+   if (!tls_ ## name ## _mutex)\
+   {   \
+   void *mutex = CreateMutexA (NULL, 0, NULL); \
+   if (InterlockedCompareExchangePointer ( \
+   &tls_ ## name ## _mutex, mutex, NULL) != NULL)  \
+   {   \
+   CloseHandle (mutex);\
+   }   \
+   }   \
+   WaitForSingleObject (tls_ ## name ## _mutex, 0x);   \
+   if (!tls_ ## name ## _initialized)  \
+   {   \
+   tls_ ## name ## _index = TlsAlloc ();   \
+   tls_ ## name ## _initialized = 1;   \
+   }   \
+   ReleaseMutex (tls_ ## name ## _mutex);  \
+   }   \
+   if (tls_ ## name ## _index == 0x)   \
+   return NULL;\
+   value = TlsGetValue (tls_ ## name ## _index);   \
+   if (!value) \
+   value = tls_ ## name ## _alloc ();  \
+   return value;   \
+}
+
+#   define PIXMAN_GET_THREAD_LOCAL(name)   \
+tls_ ## name ## _get ()
+
 #elif defined(_MSC_VER)
 
 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)  \
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists

[Pixman] [PATCH] Eliminate mask_bits from all the scanline fetchers.

2010-05-31 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Back in the day, the mask_bits argument was used to distinguish
between masks used for component alpha (where it was 0x) and
masks for unified alpha (where it was 0xff00). In this way, the
fetchers could check if just the alpha channel was 0 and in that case
avoid fetching the source.

However, we haven't actually used it like that for a long time; it is
currently always either 0x or 0 (if the mask is NULL). It also
doesn't seem worthwhile resurrecting it because for premultiplied
buffers, if alpha is 0, then so are the color channels
normally.

This patch eliminates the mask_bits and changes the fetchers to just
assume it is 0x if mask is non-NULL.
---
 pixman/pixman-access.c   |  122 +-
 pixman/pixman-bits-image.c   |   33 --
 pixman/pixman-conical-gradient.c |7 +-
 pixman/pixman-general.c  |   11 ++--
 pixman/pixman-image.c|   18 ++
 pixman/pixman-linear-gradient.c  |   13 ++--
 pixman/pixman-private.h  |   12 +---
 pixman/pixman-radial-gradient.c  |7 +-
 pixman/pixman-solid-fill.c   |6 +-
 9 files changed, 85 insertions(+), 144 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index fa0a267..809cc38 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -94,8 +94,7 @@ fetch_scanline_a8r8g8b8 (pixman_image_t *image,
  int y,
  int width,
  uint32_t *  buffer,
- const uint32_t *mask,
- uint32_tmask_bits)
+ const uint32_t *mask)
 {
 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
 
@@ -110,8 +109,7 @@ fetch_scanline_x8r8g8b8 (pixman_image_t *image,
  int y,
  int width,
  uint32_t *  buffer,
- const uint32_t *mask,
- uint32_tmask_bits)
+ const uint32_t *mask)
 {
 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
 const uint32_t *pixel = (const uint32_t *)bits + x;
@@ -127,8 +125,7 @@ fetch_scanline_a8b8g8r8 (pixman_image_t *image,
  int y,
  int width,
  uint32_t *  buffer,
- const uint32_t *mask,
- uint32_tmask_bits)
+ const uint32_t *mask)
 {
 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
 const uint32_t *pixel = (uint32_t *)bits + x;
@@ -150,8 +147,7 @@ fetch_scanline_x8b8g8r8 (pixman_image_t *image,
  int y,
  int width,
  uint32_t *  buffer,
- const uint32_t *mask,
- uint32_tmask_bits)
+ const uint32_t *mask)
 {
 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
 const uint32_t *pixel = (uint32_t *)bits + x;
@@ -174,8 +170,7 @@ fetch_scanline_b8g8r8a8 (pixman_image_t *image,
  int y,
  int width,
  uint32_t *  buffer,
- const uint32_t *mask,
- uint32_tmask_bits)
+ const uint32_t *mask)
 {
 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
 const uint32_t *pixel = (uint32_t *)bits + x;
@@ -198,8 +193,7 @@ fetch_scanline_b8g8r8x8 (pixman_image_t *image,
  int y,
  int width,
  uint32_t *  buffer,
- const uint32_t *mask,
- uint32_tmask_bits)
+ const uint32_t *mask)
 {
 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
 const uint32_t *pixel = (uint32_t *)bits + x;
@@ -223,8 +217,7 @@ fetch_scanline_a2r10g10b10 (pixman_image_t *image,
 int y,
 int width,
 uint32_t *  b,
-const uint32_t *mask,
-uint32_tmask_bits)
+const uint32_t *mask)
 {
 const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
 const uint32_t *pixel = bits + x;
@@ -259,8 +252,7 @@ fetch_scanline_x2r10g10b10 (pixman_image_t *image,
 int y,
 int w

[Pixman] [PATCH] Make the combiner macros less likely to cause name collisions.

2010-07-06 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Protect the arguments to the combiner macros with parentheses, and
prefix their temporary variables with underscores to avoid name space
collisions with the surrounding code.
---
 pixman/pixman-combine.h.template |  152 +++---
 1 files changed, 76 insertions(+), 76 deletions(-)

diff --git a/pixman/pixman-combine.h.template b/pixman/pixman-combine.h.template
index 2f6392f..012ada7 100644
--- a/pixman/pixman-combine.h.template
+++ b/pixman/pixman-combine.h.template
@@ -31,7 +31,7 @@
 (((comp2_t) (a) * MASK) / (b))
 
 #define ADD_UNc(x, y, t)\
-((t) = x + y,   \
+((t) = (x) + (y),   \
  (comp4_t) (comp1_t) ((t) | (0 - ((t) >> G_SHIFT
 
 #define DIV_ONE_UNc(x) \
@@ -84,15 +84,15 @@
 #define UNcx4_MUL_UNc(x, a)\
 do \
 {  \
-   comp4_t r1, r2, t;  \
+   comp4_t __r1, __r2, __t;\
\
-   r1 = (x);   \
-   UNc_rb_MUL_UNc (r1, a, t);  \
+   __r1 = (x); \
+   UNc_rb_MUL_UNc (__r1, (a), __t);\
\
-   r2 = (x) >> G_SHIFT;\
-   UNc_rb_MUL_UNc (r2, a, t);  \
+   __r2 = (x) >> G_SHIFT;  \
+   UNc_rb_MUL_UNc (__r2, (a), __t);\
\
-   x = r1 | (r2 << G_SHIFT);   \
+   (x) = __r1 | (__r2 << G_SHIFT); \
 } while (0)
 
 /*
@@ -101,19 +101,19 @@
 #define UNcx4_MUL_UNc_ADD_UNcx4(x, a, y)   \
 do \
 {  \
-   comp4_t r1, r2, r3, t;  \
+   comp4_t __r1, __r2, __r3, __t;  \
\
-   r1 = (x);   \
-   r2 = (y) & RB_MASK; \
-   UNc_rb_MUL_UNc (r1, a, t);  \
-   UNc_rb_ADD_UNc_rb (r1, r2, t);  \
+   __r1 = (x); \
+   __r2 = (y) & RB_MASK;   \
+   UNc_rb_MUL_UNc (__r1, (a), __t);\
+   UNc_rb_ADD_UNc_rb (__r1, __r2, __t);\
\
-   r2 = (x) >> G_SHIFT;\
-   r3 = ((y) >> G_SHIFT) & RB_MASK;\
-   UNc_rb_MUL_UNc (r2, a, t);  \
-   UNc_rb_ADD_UNc_rb (r2, r3, t);  \
+   __r2 = (x) >> G_SHIFT;  \
+   __r3 = ((y) >> G_SHIFT) & RB_MASK;  \
+   UNc_rb_MUL_UNc (__r2, (a), __t);\
+   UNc_rb_ADD_UNc_rb (__r2, __r3, __t);\
\
-   x = r1 | (r2 << G_SHIFT);   \
+   (x) = __r1 | (__r2 << G_SHIFT); \
 } while (0)
 
 /*
@@ -122,21 +122,21 @@
 #define UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc(x, a, y, b)\
 do \
 {  \
-   comp4_t r1, r2, r3, t;  \
+   comp4_t __r1, __r2, __r3, __t;  \
\
-   r1 = x; \
-   r2 = y; \
-   UNc_rb_MUL_UNc (

[Pixman] [PATCH] test: Make sure the palettes for indexed format roundtrip properly

2010-07-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The palettes for indexed formats must satisfy the condition that if
some index maps to a color C, then the 15 bit version of that color
must map back to the index. This ensures that the destination operator
is always a no-op, which seems like a reasonable assumption to make.
---
 test/blitters-test.c |   74 ++---
 1 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/test/blitters-test.c b/test/blitters-test.c
index 2673968..5becada 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -11,7 +11,8 @@
 #include 
 #include "utils.h"
 
-static pixman_indexed_t palette;
+static pixman_indexed_t rgb_palette[9];
+static pixman_indexed_t y_palette[9];
 
 static void *
 aligned_malloc (size_t align, size_t size)
@@ -66,10 +67,13 @@ create_random_image (pixman_format_code_t *allowed_formats,
 
 img = pixman_image_create_bits (fmt, width, height, buf, stride);
 
-if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR  ||
-   PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY)
+if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR)
 {
-   pixman_image_set_indexed (img, &palette);
+   pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)]));
+}
+else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY)
+{
+   pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)]));
 }
 
 image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt));
@@ -409,23 +413,71 @@ test_composite (int testnum, int verbose)
 return crc32;
 }
 
+#define CONVERT_15(c, is_rgb)  \
+(is_rgb?   \
+ c) >> 3) & 0x001f) |  \
+  (((c) >> 6) & 0x03e0) |  \
+  (((c) >> 9) & 0x7c00)) : \
+ (c) >> 16) & 0xff) * 153 +\
+   (((c) >>  8) & 0xff) * 301 +\
+   (((c)  ) & 0xff) * 58) >> 2))
+
 static void
-initialize_palette (void)
+initialize_palette (pixman_indexed_t *palette, uint32_t mask, int is_rgb)
 {
 int i;
 
-for (i = 0; i < PIXMAN_MAX_INDEXED; ++i)
-   palette.rgba[i] = lcg_rand ();
-
 for (i = 0; i < 32768; ++i)
-   palette.ent[i] = lcg_rand() & 0xff;
+   palette->ent[i] = lcg_rand() & mask;
+
+for (i = 0; i < mask + 1; ++i)
+{
+   uint32_t rgba24;
+   pixman_bool_t retry;
+   uint32_t i15;
+
+   /* We filled the rgb->index map with random numbers, but we
+* do need the ability to round trip, that is if some indexed
+* color expands to an argb24, then the 15 bit version of that
+* color must map back to the index. Anything else, we don't
+* care about too much.
+*/
+   do
+   {
+   uint32_t old_idx;
+   
+   rgba24 = lcg_rand();
+   i15 = CONVERT_15 (rgba24, is_rgb);
+
+   old_idx = palette->ent[i15];
+   if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
+   retry = 1;
+   else
+   retry = 0;
+   } while (retry);
+   
+   palette->rgba[i] = rgba24;
+   palette->ent[i15] = i;
+}
+
+for (i = 0; i < mask + 1; ++i)
+{
+   assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
+}
 }
 
 int
 main (int argc, const char *argv[])
 {
-initialize_palette();
+int i;
+
+for (i = 1; i <= 8; i++)
+{
+   initialize_palette (&(rgb_palette[i]), (1 << i) - 1, TRUE);
+   initialize_palette (&(y_palette[i]), (1 << i) - 1, FALSE);
+}
 
-return fuzzer_test_main("blitters", 200, 0xD09B1C03,
+return fuzzer_test_main("blitters", 200,
+   0xD0B050B1,
test_composite, argc, argv);
 }
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] When converting indexed formats to 64 bits, don't correct for channel widths

2010-07-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Indexed formats are mapped to a8r8g8b8 with full precision, so when
expanding we shouldn't correct for the width of the channels
---
 pixman/pixman-access.c |   31 +--
 test/blitters-test.c   |2 +-
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 9708b10..80fa9e8 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -2683,12 +2683,26 @@ fetch_scanline_generic_64 (pixman_image_t *image,
uint32_t *  buffer,
const uint32_t *mask)
 {
+pixman_format_code_t format;
+
 /* Fetch the pixels into the first half of buffer and then expand them in
  * place.
  */
 image->bits.fetch_scanline_raw_32 (image, x, y, width, buffer, NULL);
+
+format = image->bits.format;
+if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR   ||
+   PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
+{
+   /* Indexed formats are mapped to a8r8g8b8 with full
+* precision, so when expanding we shouldn't correct
+* for the width of the channels
+*/
+   
+   format = PIXMAN_a8r8g8b8;
+}
 
-pixman_expand ((uint64_t *)buffer, buffer, image->bits.format, width);
+pixman_expand ((uint64_t *)buffer, buffer, format, width);
 }
 
 /* Despite the type, this function expects a uint64_t *buffer */
@@ -2699,8 +2713,21 @@ fetch_pixel_generic_64 (bits_image_t *image,
 {
 uint32_t pixel32 = image->fetch_pixel_raw_32 (image, offset, line);
 uint64_t result;
+pixman_format_code_t format;
+
+format = image->format;
+if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR   ||
+   PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
+{
+   /* Indexed formats are mapped to a8r8g8b8 with full
+* precision, so when expanding we shouldn't correct
+* for the width of the channels
+*/
+   
+   format = PIXMAN_a8r8g8b8;
+}
 
-pixman_expand ((uint64_t *)&result, &pixel32, image->format, 1);
+pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
 
 return result;
 }
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 5becada..2c6334a 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -478,6 +478,6 @@ main (int argc, const char *argv[])
 }
 
 return fuzzer_test_main("blitters", 200,
-   0xD0B050B1,
+   0xD5833506,
test_composite, argc, argv);
 }
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Make the repeat mode explicit in the FAST_NEAREST macro.

2010-07-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Before, it was 0 or 1 meaning 'no repeat' and 'normal repeat'
respectively. Now we explicitly pass in either NONE or NORMAL.
---
 pixman/pixman-fast-path.c |   43 ++-
 1 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index c4dd3a6..7b8c9bc 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1399,7 +1399,7 @@ repeat (pixman_repeat_t repeat, int *c, int size)
 #define GET_0565_ALPHA(s) 0xff
 
 #define FAST_NEAREST(scale_func_name, SRC_FORMAT, DST_FORMAT,  
\
-src_type_t, dst_type_t, OP, do_repeat) 
\
+src_type_t, dst_type_t, OP, repeat_mode)   
\
 static void
\
 fast_composite_scaled_nearest_ ## scale_func_name ## _ ## OP 
(pixman_implementation_t *imp,\
  pixman_op_t   
   op,  \
@@ -1435,6 +1435,12 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ 
## OP (pixman_implementat
 if (PIXMAN_OP_ ## OP != PIXMAN_OP_SRC && PIXMAN_OP_ ## OP != 
PIXMAN_OP_OVER)   \
abort();
\

\
+if (PIXMAN_REPEAT_ ## repeat_mode != PIXMAN_REPEAT_NORMAL  &&  
\
+   PIXMAN_REPEAT_ ## repeat_mode != PIXMAN_REPEAT_NONE)
\
+{  
\
+   abort();
\
+}  
\
+   
\
 PIXMAN_IMAGE_GET_LINE (dst_image, dst_x, dst_y, dst_type_t, dst_stride, 
dst_line, 1);  \
 /* pass in 0 instead of src_x and src_y because src_x and src_y need to be 
\
  * transformed from destination space to source space */   
\
@@ -1458,7 +1464,7 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ ## 
OP (pixman_implementat
 vx = v.vector[0];  
\
 vy = v.vector[1];  
\

\
-if (do_repeat) 
\
+if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) 
\
 {  
\
/* Clamp repeating positions inside the actual samples */   
\
max_vx = src_image->bits.width << 16;   
\
@@ -1477,7 +1483,7 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ ## 
OP (pixman_implementat

\
y = vy >> 16;   
\
vy += unit_y;   
\
-   if (do_repeat)  
\
+   if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL)  
\
repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy); 
\

\
src = src_first_line + src_stride * y;  
\
@@ -1488,7 +1494,7 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ ## 
OP (pixman_implementat
{   
\
x1 = vx >> 16;  
\
vx += unit_x;   
\
-   if (do_repeat)  
\
+   if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL)  
\
{   
\

[Pixman] [PATCH] In the FAST_NEAREST macro call the function 8888_8888 and not x888_x888

2010-07-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The x888 suggests that they have something to do with the x8r8g8b8
formats, but that's not the case; they are assuming a8r8g8b8
formats. (Although in some cases they also work for x8r8g8b8 type
formats).
---
 pixman/pixman-fast-path.c |   36 ++--
 1 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 7b8c9bc..2e9d39a 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1590,12 +1590,12 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ 
## OP (pixman_implementat
 }  
\
 }
 
-FAST_NEAREST(x888_x888_none, , , uint32_t, uint32_t, SRC, NONE);
-FAST_NEAREST(x888_x888_normal, , , uint32_t, uint32_t, SRC, NORMAL);
-FAST_NEAREST(x888_x888_none, , , uint32_t, uint32_t, OVER, NONE);
-FAST_NEAREST(x888_x888_normal, , , uint32_t, uint32_t, OVER, NORMAL);
-FAST_NEAREST(x888_565_none, , 0565, uint32_t, uint16_t, SRC, NONE);
-FAST_NEAREST(x888_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL);
+FAST_NEAREST(__none, , , uint32_t, uint32_t, SRC, NONE);
+FAST_NEAREST(__normal, , , uint32_t, uint32_t, SRC, NORMAL);
+FAST_NEAREST(__none, , , uint32_t, uint32_t, OVER, NONE);
+FAST_NEAREST(__normal, , , uint32_t, uint32_t, OVER, NORMAL);
+FAST_NEAREST(_565_none, , 0565, uint32_t, uint16_t, SRC, NONE);
+FAST_NEAREST(_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL);
 FAST_NEAREST(565_565_none, 0565, 0565, uint16_t, uint16_t, SRC, NONE);
 FAST_NEAREST(565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL);
 FAST_NEAREST(_565_none, , 0565, uint32_t, uint16_t, OVER, NONE);
@@ -1855,23 +1855,23 @@ static const pixman_fast_path_t c_fast_paths[] =
PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \
 }
-SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, x888_x888),
-SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, x888_x888),
-SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, x888_x888),
-SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, x888_x888),
+SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, _),
+SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, _),
+SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, _),
+SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, _),
 
-SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, x888_x888),
-SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, x888_x888),
+SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, _),
+SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, _),
 
-SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, x888_565),
-SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, x888_565),
+SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, _565),
+SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, _565),
 
 SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, 565_565),
 
-SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, x888_x888),
-SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, x888_x888),
-SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, x888_x888),
-SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, x888_x888),
+SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, _),
+SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, _),
+SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, _),
+SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, _),
 
 SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, _565),
 
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] fast-path: Some formatting fixes

2010-07-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Add spaces before parentheses; fix indentation in the macro.
---
 pixman/pixman-fast-path.c |   26 +-
 1 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 2e9d39a..c65dfb1 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1547,8 +1547,8 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ ## 
OP (pixman_implementat
}   
\
else /* PIXMAN_OP_SRC */
\
{   
\
-   *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); 
\
-   *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s2); 
\
+   *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); 
\
+   *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s2); 
\
}   
\
}   
\

\
@@ -1584,22 +1584,22 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ 
## OP (pixman_implementat
}   
\
else /* PIXMAN_OP_SRC */
\
{   
\
-   *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); 
\
+   *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); 
\
}   
\
}   
\
 }  
\
 }
 
-FAST_NEAREST(__none, , , uint32_t, uint32_t, SRC, NONE);
-FAST_NEAREST(__normal, , , uint32_t, uint32_t, SRC, NORMAL);
-FAST_NEAREST(__none, , , uint32_t, uint32_t, OVER, NONE);
-FAST_NEAREST(__normal, , , uint32_t, uint32_t, OVER, NORMAL);
-FAST_NEAREST(_565_none, , 0565, uint32_t, uint16_t, SRC, NONE);
-FAST_NEAREST(_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL);
-FAST_NEAREST(565_565_none, 0565, 0565, uint16_t, uint16_t, SRC, NONE);
-FAST_NEAREST(565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL);
-FAST_NEAREST(_565_none, , 0565, uint32_t, uint16_t, OVER, NONE);
-FAST_NEAREST(_565_normal, , 0565, uint32_t, uint16_t, OVER, NORMAL);
+FAST_NEAREST (__none, , , uint32_t, uint32_t, SRC, NONE);
+FAST_NEAREST (__normal, , , uint32_t, uint32_t, SRC, NORMAL);
+FAST_NEAREST (__none, , , uint32_t, uint32_t, OVER, NONE);
+FAST_NEAREST (__normal, , , uint32_t, uint32_t, OVER, NORMAL);
+FAST_NEAREST (_565_none, , 0565, uint32_t, uint16_t, SRC, NONE);
+FAST_NEAREST (_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL);
+FAST_NEAREST (565_565_none, 0565, 0565, uint16_t, uint16_t, SRC, NONE);
+FAST_NEAREST (565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL);
+FAST_NEAREST (_565_none, , 0565, uint32_t, uint16_t, OVER, NONE);
+FAST_NEAREST (_565_normal, , 0565, uint32_t, uint16_t, OVER, NORMAL);
 
 static force_inline uint32_t
 fetch_nearest (pixman_repeat_t src_repeat,
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Check for read accessors before taking the bilinear fast path

2010-07-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The bilinear fast path accesses pixels directly, so if the image has a
read accessor, then it can't be used.
---
 pixman/pixman-bits-image.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index ff59a8f..95710b4 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -909,6 +909,7 @@ bits_image_property_changed (pixman_image_t *image)
 bits->common.transform->matrix[2][2] == pixman_fixed_1 &&
 bits->common.transform->matrix[0][0] > 0   &&
 bits->common.transform->matrix[1][0] == 0  &&
+!bits->read_func   &&
 (bits->common.filter == PIXMAN_FILTER_BILINEAR ||
  bits->common.filter == PIXMAN_FILTER_GOOD ||
  bits->common.filter == PIXMAN_FILTER_BEST)&&
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] [fast] Add fast_composite_src_x888_8888()

2010-07-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This shows up on when Firefox displays http://dougx.net/plunder/plunder.html
---
 pixman/pixman-fast-path.c |   38 ++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index c65dfb1..6ed1580 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -724,6 +724,42 @@ fast_composite_over__ (pixman_implementation_t 
*imp,
 }
 }
 
+static void
+fast_composite_src_x888_ (pixman_implementation_t *imp,
+ pixman_op_t  op,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t  src_x,
+ int32_t  src_y,
+ int32_t  mask_x,
+ int32_t  mask_y,
+ int32_t  dest_x,
+ int32_t  dest_y,
+ int32_t  width,
+ int32_t  height)
+{
+uint32_t*dst_line, *dst;
+uint32_t*src_line, *src;
+int dst_stride, src_stride;
+int32_t w;
+
+PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, 
dst_line, 1);
+PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, 
src_line, 1);
+
+while (height--)
+{
+   dst = dst_line;
+   dst_line += dst_stride;
+   src = src_line;
+   src_line += src_stride;
+   w = width;
+
+   while (w--)
+   *dst++ = (*src++) | 0xff00;
+}
+}
+
 #if 0
 static void
 fast_composite_over__0888 (pixman_implementation_t *imp,
@@ -1805,6 +1841,8 @@ static const pixman_fast_path_t c_fast_paths[] =
 PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, 
fast_composite_solid_fill),
 PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill),
 PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill),
+PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, 
fast_composite_src_x888_),
+PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, 
fast_composite_src_x888_),
 PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, 
fast_composite_src_memcpy),
 PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, 
fast_composite_src_memcpy),
 PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, 
fast_composite_src_memcpy),
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] [sse2] Add sse2_composite_src_x888_8888()

2010-07-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This operation shows up when Firefox displays
http://dougx.net/plunder/plunder.html
---
 pixman/pixman-sse2.c |   84 ++
 1 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index d5349d7..2c9f5eb 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -3517,6 +3517,88 @@ sse2_composite_over__n_ (pixman_implementation_t 
*imp,
 _mm_empty ();
 }
 
+/*-
+ * composite_over__n_
+ */
+
+static void
+sse2_composite_src_x888_ (pixman_implementation_t *imp,
+ pixman_op_t  op,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t  src_x,
+ int32_t  src_y,
+ int32_t  mask_x,
+ int32_t  mask_y,
+ int32_t  dest_x,
+ int32_t  dest_y,
+ int32_t  width,
+ int32_t  height)
+{
+uint32_t*dst_line, *dst;
+uint32_t*src_line, *src;
+int32_t w;
+int dst_stride, src_stride;
+
+
+PIXMAN_IMAGE_GET_LINE (
+   dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+PIXMAN_IMAGE_GET_LINE (
+   src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
+
+while (height--)
+{
+   dst = dst_line;
+   dst_line += dst_stride;
+   src = src_line;
+   src_line += src_stride;
+   w = width;
+
+   /* call prefetch hint to optimize cache load*/
+   cache_prefetch ((__m128i*)src);
+
+   while (w && (unsigned long)dst & 15)
+   {
+   *dst++ = *src++ | 0xff00;
+   w--;
+   }
+
+   /* call prefetch hint to optimize cache load*/
+   cache_prefetch ((__m128i*)src);
+
+   while (w >= 16)
+   {
+   __m128i xmm_src1, xmm_src2, xmm_src3, xmm_src4;
+   
+   /* fill cache line with next memory */
+   cache_prefetch_next ((__m128i*)src);
+
+   xmm_src1 = load_128_unaligned ((__m128i*)src + 0);
+   xmm_src2 = load_128_unaligned ((__m128i*)src + 1);
+   xmm_src3 = load_128_unaligned ((__m128i*)src + 2);
+   xmm_src4 = load_128_unaligned ((__m128i*)src + 3);
+   
+   save_128_aligned ((__m128i*)dst + 0, _mm_or_si128 (xmm_src1, 
mask_ff00));
+   save_128_aligned ((__m128i*)dst + 1, _mm_or_si128 (xmm_src2, 
mask_ff00));
+   save_128_aligned ((__m128i*)dst + 2, _mm_or_si128 (xmm_src3, 
mask_ff00));
+   save_128_aligned ((__m128i*)dst + 3, _mm_or_si128 (xmm_src4, 
mask_ff00));
+   
+   dst += 16;
+   src += 16;
+   w -= 16;
+   }
+
+   while (w)
+   {
+   *dst++ = *src++ | 0xff00;
+   w--;
+   }
+}
+
+_mm_empty ();
+}
+
 /* -
  * composite_over_x888_n_
  */
@@ -6127,6 +6209,8 @@ static const pixman_fast_path_t sse2_fast_paths[] =
 PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, 
sse2_composite_src_n_8_),
 PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, 
sse2_composite_src_n_8_),
 PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, 
sse2_composite_src_n_8_),
+PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, 
sse2_composite_src_x888_),
+PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, 
sse2_composite_src_x888_),
 PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, 
sse2_composite_copy_area),
 PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, 
sse2_composite_copy_area),
 PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, 
sse2_composite_copy_area),
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] [sse2] Add sse2_composite_add_n_8()

2010-07-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This shows up when epiphany displays the "ImageTest" on
glimr.rubyforge.org/cake/canvas.html
---
 pixman/pixman-sse2.c |   98 ++
 1 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 822fffe..3dd7967 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -5386,6 +5386,103 @@ sse2_composite_add_n_8_8 (pixman_implementation_t *imp,
 _mm_empty ();
 }
 
+/* -
+ * composite_add_n_8_8
+ */
+
+static void
+sse2_composite_add_n_8 (pixman_implementation_t *imp,
+   pixman_op_t  op,
+   pixman_image_t * src_image,
+   pixman_image_t * mask_image,
+   pixman_image_t * dst_image,
+   int32_t  src_x,
+   int32_t  src_y,
+   int32_t  mask_x,
+   int32_t  mask_y,
+   int32_t  dest_x,
+   int32_t  dest_y,
+   int32_t  width,
+   int32_t  height)
+{
+uint8_t *dst_line, *dst;
+int dst_stride;
+int32_t w;
+uint32_t src;
+
+__m128i xmm_src;
+
+PIXMAN_IMAGE_GET_LINE (
+   dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
+
+src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+
+src >>= 24;
+
+if (src == 0x00)
+   return;
+
+if (src == 0xff)
+{
+   pixman_fill (dst_image->bits.bits, dst_image->bits.rowstride,
+8, dest_x, dest_y, width, height, 0xff);
+
+   return;
+}
+
+src = (src << 24) | (src << 16) | (src << 8) | src;
+xmm_src = _mm_set_epi32 (src, src, src, src);
+
+while (height--)
+{
+   dst = dst_line;
+   dst_line += dst_stride;
+   w = width;
+
+   /* call prefetch hint to optimize cache load*/
+   cache_prefetch ((__m128i*)dst);
+
+   while (w && ((unsigned long)dst & 15))
+   {
+   *dst = (uint8_t)_mm_cvtsi64_si32 (
+   _mm_adds_pu8 (
+   _mm_movepi64_pi64 (xmm_src),
+   _mm_cvtsi32_si64 (*dst)));
+
+   w--;
+   dst++;
+   }
+
+   /* call prefetch hint to optimize cache load*/
+   cache_prefetch ((__m128i*)dst);
+
+   while (w >= 16)
+   {
+   /* fill cache line with next memory */
+   cache_prefetch_next ((__m128i*)dst);
+
+   save_128_aligned (
+   (__m128i*)dst, _mm_adds_epu8 (xmm_src, load_128_aligned  
((__m128i*)dst)));
+
+   dst += 16;
+   w -= 16;
+   }
+
+   while (w)
+   {
+   *dst = (uint8_t)_mm_cvtsi64_si32 (
+   _mm_adds_pu8 (
+   _mm_movepi64_pi64 (xmm_src),
+   _mm_cvtsi32_si64 (*dst)));
+
+   w--;
+   dst++;
+   }
+}
+
+_mm_empty ();
+}
+
 /* --
  * composite_add_8000_8000
  */
@@ -6309,6 +6406,7 @@ static const pixman_fast_path_t sse2_fast_paths[] =
 PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, 
sse2_composite_add__),
 PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, 
sse2_composite_add__),
 PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, sse2_composite_add_n_8_8),
+PIXMAN_STD_FAST_PATH (ADD, solid, null, a8, sse2_composite_add_n_8),
 
 /* PIXMAN_OP_SRC */
 PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, 
sse2_composite_src_n_8_),
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] [sse2] Add sse2_composite_in_n_8()

2010-07-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This shows up when epiphany displays the "ImageTest" on
glimr.rubyforge.org/cake/canvas.html
---
 pixman/pixman-sse2.c |  109 +-
 1 files changed, 108 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 2c9f5eb..822fffe 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -5066,6 +5066,112 @@ sse2_composite_in_n_8_8 (pixman_implementation_t *imp,
 _mm_empty ();
 }
 
+/* ---
+ * composite_in_n_8
+ */
+
+static void
+sse2_composite_in_n_8 (pixman_implementation_t *imp,
+  pixman_op_t  op,
+  pixman_image_t * src_image,
+  pixman_image_t * mask_image,
+  pixman_image_t * dst_image,
+  int32_t  src_x,
+  int32_t  src_y,
+  int32_t  mask_x,
+  int32_t  mask_y,
+  int32_t  dest_x,
+  int32_t  dest_y,
+  int32_t  width,
+  int32_t  height)
+{
+uint8_t *dst_line, *dst;
+int dst_stride;
+uint32_t d;
+uint32_t src;
+int32_t w;
+
+__m128i xmm_alpha;
+__m128i xmm_dst, xmm_dst_lo, xmm_dst_hi;
+
+PIXMAN_IMAGE_GET_LINE (
+   dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
+
+src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+
+xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src));
+
+src = src >> 24;
+
+if (src == 0xff)
+   return;
+
+if (src == 0x00)
+{
+   pixman_fill (dst_image->bits.bits, dst_image->bits.rowstride,
+8, dest_x, dest_y, width, height, src);
+
+   return;
+}
+
+while (height--)
+{
+   dst = dst_line;
+   dst_line += dst_stride;
+   w = width;
+
+   /* call prefetch hint to optimize cache load*/
+   cache_prefetch ((__m128i*)dst);
+
+   while (w && ((unsigned long)dst & 15))
+   {
+   d = (uint32_t) *dst;
+
+   *dst++ = (uint8_t) pack_1x64_32 (
+   pix_multiply_1x64 (
+   _mm_movepi64_pi64 (xmm_alpha),
+   unpack_32_1x64 (d)));
+   w--;
+   }
+
+   /* call prefetch hint to optimize cache load*/
+   cache_prefetch ((__m128i*)dst);
+
+   while (w >= 16)
+   {
+   /* fill cache line with next memory */
+   cache_prefetch_next ((__m128i*)dst);
+
+   xmm_dst = load_128_aligned ((__m128i*)dst);
+
+   unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi);
+   
+   pix_multiply_2x128 (&xmm_alpha, &xmm_alpha,
+   &xmm_dst_lo, &xmm_dst_hi,
+   &xmm_dst_lo, &xmm_dst_hi);
+
+   save_128_aligned (
+   (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi));
+
+   dst += 16;
+   w -= 16;
+   }
+
+   while (w)
+   {
+   d = (uint32_t) *dst;
+
+   *dst++ = (uint8_t) pack_1x64_32 (
+   pix_multiply_1x64 (
+   _mm_movepi64_pi64 (xmm_alpha),
+   unpack_32_1x64 (d)));
+   w--;
+   }
+}
+
+_mm_empty ();
+}
+
 /* ---
  * composite_in_8_8
  */
@@ -6192,7 +6298,7 @@ static const pixman_fast_path_t sse2_fast_paths[] =
 PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, b5g6r5, 
sse2_composite_over_pixbuf_0565),
 PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, x8r8g8b8, 
sse2_composite_copy_area),
 PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, x8b8g8r8, 
sse2_composite_copy_area),
-
+
 /* PIXMAN_OP_OVER_REVERSE */
 PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, 
sse2_composite_over_reverse_n_),
 PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, 
sse2_composite_over_reverse_n_),
@@ -6223,6 +6329,7 @@ static const pixman_fast_path_t sse2_fast_paths[] =
 /* PIXMAN_OP_IN */
 PIXMAN_STD_FAST_PATH (IN, a8, null, a8, sse2_composite_in_8_8),
 PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, sse2_composite_in_n_8_8),
+PIXMAN_STD_FAST_PATH (IN, solid, null, a8, sse2_composite_in_n_8),
 
 { PIXMAN_OP_NONE },
 };
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] bits: Fix potential divide-by-zero in projective code

2010-07-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

If the homogeneous coordinate is 0, just set the coordinates to 0.
---
 pixman/pixman-bits-image.c |   16 
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 95710b4..36ea0af 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -695,12 +695,20 @@ bits_image_fetch_transformed (pixman_image_t * image,
 {
for (i = 0; i < width; ++i)
{
-   pixman_fixed_t x0, y0;
-
if (!mask || mask[i])
{
-   x0 = ((pixman_fixed_48_16_t)x << 16) / w;
-   y0 = ((pixman_fixed_48_16_t)y << 16) / w;
+   pixman_fixed_t x0, y0;
+
+   if (w != 0)
+   {
+   x0 = ((pixman_fixed_48_16_t)x << 16) / w;
+   y0 = ((pixman_fixed_48_16_t)y << 16) / w;
+   }
+   else
+   {
+   x0 = 0;
+   y0 = 0;
+   }
 
buffer[i] =
bits_image_fetch_pixel_filtered (&image->bits, x0, y0);
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] If we bail out of do_composite, make sure to undo any workarounds.

2010-07-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The workaround for an old X bug has to be undone if we bail from
do_composite, so we can't just return.
---
 pixman/pixman.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index 80a766a..2d06ce2 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -742,7 +742,7 @@ do_composite (pixman_op_t  op,
®ion, src, mask, dest,
src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
 {
-   return;
+   goto out;
 }
 
 extents = pixman_region32_extents (®ion);
@@ -759,7 +759,7 @@ do_composite (pixman_op_t  op,
  */
 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
 if (op == PIXMAN_OP_DST)
-   return;
+   goto out;
 
 lookup_composite_function (op,
   src_format, src_flags,
@@ -776,6 +776,7 @@ do_composite (pixman_op_t  op,
  (mask_flags & FAST_PATH_SIMPLE_REPEAT),
  ®ion, func);
 
+out:
 if (need_workaround)
 {
unapply_workaround (src, src_bits, src_dx, src_dy);
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [bits] Some cleanups of fetchers, plus flags for bits-image

2010-07-29 Thread Søren Sandmann
The following patches contain some cleanups of the way the scanline
fetching works for bits images. By removing the support for alpha map
recursion, there is no longer any need to distinguish between 'raw'
and non-raw scanline fetchers.

Instead there is only one type of scanline fetcher, and only two
function pointers in the image struct: one for 32 bit fetching and one
for 64 bits.

This then allows the various types of fetchers to be stored in an
array indexed by flags, similar to how the fast paths are stored.

Soren

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 1/7] Eliminate recursion from alpha map code

2010-07-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Alpha maps with alpha maps are no longer supported. It's not a useful
feature and it could could lead to infinite recursion.
---
 pixman/pixman-bits-image.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 36ea0af..81722c2 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -51,7 +51,7 @@ bits_image_store_scanline_32 (bits_image_t *  image,
x -= image->common.alpha_origin_x;
y -= image->common.alpha_origin_y;
 
-   bits_image_store_scanline_32 (image->common.alpha_map, x, y, width, 
buffer);
+   image->common.alpha_map->store_scanline_raw_32 
(image->common.alpha_map, x, y, width, buffer);
 }
 }
 
@@ -69,7 +69,7 @@ bits_image_store_scanline_64 (bits_image_t *  image,
x -= image->common.alpha_origin_x;
y -= image->common.alpha_origin_y;
 
-   bits_image_store_scanline_64 (image->common.alpha_map, x, y, width, 
buffer);
+   image->common.alpha_map->store_scanline_raw_64 
(image->common.alpha_map, x, y, width, buffer);
 }
 }
 
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 2/7] Eliminate get_pixel_32() and get_pixel_64() from bits_image.

2010-07-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

These functions can simply be passed as arguments to the various pixel
fetchers. We don't need to store them. Since they are known at compile
time and the pixel fetchers are force_inline, this is not a
performance issue.

Also temporarily make all pixel access go through the alpha path.
---
 pixman/pixman-bits-image.c |   78 +--
 pixman/pixman-private.h|4 --
 2 files changed, 45 insertions(+), 37 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 81722c2..0372217 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -96,38 +96,47 @@ _pixman_image_store_scanline_64 (bits_image_t *  image,
 /* Fetch functions */
 
 static uint32_t
-bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
+fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t 
check_bounds)
 {
 uint32_t pixel;
-uint32_t pixel_a;
+
+if (check_bounds &&
+   (x < 0 || x >= image->width || y < 0 || y >= image->height))
+{
+   return 0;
+}
 
 pixel = image->fetch_pixel_raw_32 (image, x, y);
 
-assert (image->common.alpha_map);
+if (image->common.alpha_map)
+{
+   uint32_t pixel_a;
 
-x -= image->common.alpha_origin_x;
-y -= image->common.alpha_origin_y;
+   x -= image->common.alpha_origin_x;
+   y -= image->common.alpha_origin_y;
 
-if (x < 0 || x >= image->common.alpha_map->width ||
-   y < 0 || y >= image->common.alpha_map->height)
-{
-   pixel_a = 0;
-}
-else
-{
-   pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
-   image->common.alpha_map, x, y);
-   pixel_a = ALPHA_8 (pixel_a);
-}
+   if (x < 0 || x >= image->common.alpha_map->width ||
+   y < 0 || y >= image->common.alpha_map->height)
+   {
+   pixel_a = 0;
+   }
+   else
+   {
+   pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
+   image->common.alpha_map, x, y);
 
-pixel &= 0x00ff;
-pixel |= (pixel_a << 24);
+   pixel_a = ALPHA_8 (pixel_a);
+   }
+
+   pixel &= 0x00ff;
+   pixel |= (pixel_a << 24);
+}
 
 return pixel;
 }
 
 static force_inline uint32_t
-get_pixel (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
+fetch_pixel_no_alpha (bits_image_t *image, int x, int y, pixman_bool_t 
check_bounds)
 {
 if (check_bounds &&
(x < 0 || x >= image->width || y < 0 || y >= image->height))
@@ -135,9 +144,12 @@ get_pixel (bits_image_t *image, int x, int y, 
pixman_bool_t check_bounds)
return 0;
 }
 
-return image->fetch_pixel_32 (image, x, y);
+return image->fetch_pixel_raw_32 (image, x, y);
 }
 
+typedef uint32_t (* get_pixel_t) (bits_image_t *image,
+ int x, int y, pixman_bool_t check_bounds);
+
 static force_inline void
 repeat (pixman_repeat_t repeat, int size, int *coord)
 {
@@ -169,7 +181,8 @@ repeat (pixman_repeat_t repeat, int size, int *coord)
 static force_inline uint32_t
 bits_image_fetch_pixel_nearest (bits_image_t   *image,
pixman_fixed_t  x,
-   pixman_fixed_t  y)
+   pixman_fixed_t  y,
+   get_pixel_t get_pixel)
 {
 int x0 = pixman_fixed_to_int (x - pixman_fixed_e);
 int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
@@ -281,7 +294,8 @@ bilinear_interpolation (uint32_t tl, uint32_t tr,
 static force_inline uint32_t
 bits_image_fetch_pixel_bilinear (bits_image_t   *image,
 pixman_fixed_t  x,
-pixman_fixed_t  y)
+pixman_fixed_t  y,
+get_pixel_t get_pixel)
 {
 pixman_repeat_t repeat_mode = image->common.repeat;
 int width = image->width;
@@ -538,7 +552,8 @@ bits_image_fetch_bilinear_no_repeat_ (pixman_image_t * 
ima,
 static force_inline uint32_t
 bits_image_fetch_pixel_convolution (bits_image_t   *image,
pixman_fixed_t  x,
-   pixman_fixed_t  y)
+   pixman_fixed_t  y,
+   get_pixel_t get_pixel)
 {
 pixman_fixed_t *params = image->common.filter_params;
 int x_off = (params[0] - pixman_fixed_1) >> 1;
@@ -611,23 +626,24 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
 static force_inline uint32_t
 bits_image_fetch_pixel_filtered (bits_image_t *image,
 pixman_fixed_t x,
-pixman_fixed_t y)
+pixman_fixed_t

[Pixman] [PATCH 3/7] Split bits_image_fetch_transformed() into two functions.

2010-07-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

One function deals with the common affine, no-alpha-map case. The
other deals with perspective transformations and alpha maps.
---
 pixman/pixman-bits-image.c |  222 +---
 1 files changed, 128 insertions(+), 94 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 0372217..09b69df 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -95,48 +95,9 @@ _pixman_image_store_scanline_64 (bits_image_t *  image,
 
 /* Fetch functions */
 
-static uint32_t
-fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t 
check_bounds)
-{
-uint32_t pixel;
-
-if (check_bounds &&
-   (x < 0 || x >= image->width || y < 0 || y >= image->height))
-{
-   return 0;
-}
-
-pixel = image->fetch_pixel_raw_32 (image, x, y);
-
-if (image->common.alpha_map)
-{
-   uint32_t pixel_a;
-
-   x -= image->common.alpha_origin_x;
-   y -= image->common.alpha_origin_y;
-
-   if (x < 0 || x >= image->common.alpha_map->width ||
-   y < 0 || y >= image->common.alpha_map->height)
-   {
-   pixel_a = 0;
-   }
-   else
-   {
-   pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
-   image->common.alpha_map, x, y);
-
-   pixel_a = ALPHA_8 (pixel_a);
-   }
-
-   pixel &= 0x00ff;
-   pixel |= (pixel_a << 24);
-}
-
-return pixel;
-}
-
 static force_inline uint32_t
-fetch_pixel_no_alpha (bits_image_t *image, int x, int y, pixman_bool_t 
check_bounds)
+fetch_pixel_no_alpha (bits_image_t *image,
+ int x, int y, pixman_bool_t check_bounds)
 {
 if (check_bounds &&
(x < 0 || x >= image->width || y < 0 || y >= image->height))
@@ -654,12 +615,101 @@ bits_image_fetch_pixel_filtered (bits_image_t *image,
 }
 
 static void
-bits_image_fetch_transformed (pixman_image_t * image,
-  int  offset,
-  int  line,
-  int  width,
-  uint32_t *   buffer,
-  const uint32_t * mask)
+bits_image_fetch_affine_no_alpha (pixman_image_t * image,
+ int  offset,
+ int  line,
+ int  width,
+ uint32_t *   buffer,
+ const uint32_t * mask)
+{
+pixman_fixed_t x, y;
+pixman_fixed_t ux, uy;
+pixman_vector_t v;
+int i;
+
+/* reference point is the center of the pixel */
+v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
+v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
+v.vector[2] = pixman_fixed_1;
+
+if (image->common.transform)
+{
+   if (!pixman_transform_point_3d (image->common.transform, &v))
+   return;
+
+   ux = image->common.transform->matrix[0][0];
+   uy = image->common.transform->matrix[1][0];
+}
+else
+{
+   ux = pixman_fixed_1;
+   uy = 0;
+}
+
+x = v.vector[0];
+y = v.vector[1];
+
+for (i = 0; i < width; ++i)
+{
+   if (!mask || mask[i])
+   {
+   buffer[i] = bits_image_fetch_pixel_filtered (
+   &image->bits, x, y, fetch_pixel_no_alpha);
+   }
+   
+   x += ux;
+   y += uy;
+}
+}
+
+/* General fetcher */
+static force_inline uint32_t
+fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t 
check_bounds)
+{
+uint32_t pixel;
+
+if (check_bounds &&
+   (x < 0 || x >= image->width || y < 0 || y >= image->height))
+{
+   return 0;
+}
+
+pixel = image->fetch_pixel_raw_32 (image, x, y);
+
+if (image->common.alpha_map)
+{
+   uint32_t pixel_a;
+
+   x -= image->common.alpha_origin_x;
+   y -= image->common.alpha_origin_y;
+
+   if (x < 0 || x >= image->common.alpha_map->width ||
+   y < 0 || y >= image->common.alpha_map->height)
+   {
+   pixel_a = 0;
+   }
+   else
+   {
+   pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
+   image->common.alpha_map, x, y);
+
+   pixel_a = ALPHA_8 (pixel_a);
+   }
+
+   pixel &= 0x00ff;
+   pixel |= (pixel_a << 24);
+}
+
+return pixel;
+}
+
+static void
+bits_image_fetch_general (pixman_image_t * image,
+ int  offset,
+ int  line,
+ int  width,
+ uint32_t *   buffer,
+  

[Pixman] [PATCH 4/7] Eliminate the store_scanline_{32, 64} function pointers.

2010-07-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Now that we can't recurse on alpha maps, they are not needed anymore.
---
 pixman/pixman-bits-image.c |   54 +---
 pixman/pixman-private.h|4 ---
 2 files changed, 16 insertions(+), 42 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 09b69df..f8ddcbc 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -36,13 +36,12 @@
 #include "pixman-combine32.h"
 
 /* Store functions */
-
-static void
-bits_image_store_scanline_32 (bits_image_t *  image,
-  int x,
-  int y,
-  int width,
-  const uint32_t *buffer)
+void
+_pixman_image_store_scanline_32 (bits_image_t *  image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *buffer)
 {
 image->store_scanline_raw_32 (image, x, y, width, buffer);
 
@@ -51,16 +50,17 @@ bits_image_store_scanline_32 (bits_image_t *  image,
x -= image->common.alpha_origin_x;
y -= image->common.alpha_origin_y;
 
-   image->common.alpha_map->store_scanline_raw_32 
(image->common.alpha_map, x, y, width, buffer);
+   image->common.alpha_map->store_scanline_raw_32 (
+   image->common.alpha_map, x, y, width, buffer);
 }
 }
 
-static void
-bits_image_store_scanline_64 (bits_image_t *  image,
-  int x,
-  int y,
-  int width,
-  const uint32_t *buffer)
+void
+_pixman_image_store_scanline_64 (bits_image_t *  image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *buffer)
 {
 image->store_scanline_raw_64 (image, x, y, width, buffer);
 
@@ -69,30 +69,11 @@ bits_image_store_scanline_64 (bits_image_t *  image,
x -= image->common.alpha_origin_x;
y -= image->common.alpha_origin_y;
 
-   image->common.alpha_map->store_scanline_raw_64 
(image->common.alpha_map, x, y, width, buffer);
+   image->common.alpha_map->store_scanline_raw_64 (
+   image->common.alpha_map, x, y, width, buffer);
 }
 }
 
-void
-_pixman_image_store_scanline_32 (bits_image_t *  image,
- int x,
- int y,
- int width,
- const uint32_t *buffer)
-{
-image->store_scanline_32 (image, x, y, width, buffer);
-}
-
-void
-_pixman_image_store_scanline_64 (bits_image_t *  image,
- int x,
- int y,
- int width,
- const uint32_t *buffer)
-{
-image->store_scanline_64 (image, x, y, width, buffer);
-}
-
 /* Fetch functions */
 
 static force_inline uint32_t
@@ -983,9 +964,6 @@ bits_image_property_changed (pixman_image_t *image)
image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
image->common.get_scanline_32 = bits_image_fetch_general;
 }
-
-bits->store_scanline_64 = bits_image_store_scanline_64;
-bits->store_scanline_32 = bits_image_store_scanline_32;
 }
 
 static uint32_t *
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 06f6d11..15a5bc2 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -187,10 +187,6 @@ struct bits_image
 store_scanline_t   store_scanline_raw_32;
 store_scanline_t   store_scanline_raw_64;
 
-/* Store a scanline, taking alpha maps into account */
-store_scanline_t   store_scanline_32;
-store_scanline_t   store_scanline_64;
-
 /* Used for indirect access to the bits */
 pixman_read_memory_func_t  read_func;
 pixman_write_memory_func_t write_func;
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 5/7] Remove "_raw_" from all the accessors.

2010-07-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

There are no non-raw accessors anymore.
---
 pixman/pixman-access.c |   40 
 pixman/pixman-bits-image.c |   28 ++--
 pixman/pixman-private.h|   19 +++
 3 files changed, 41 insertions(+), 46 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 80fa9e8..a786947 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -2667,7 +2667,7 @@ store_scanline_generic_64 (bits_image_t *  image,
  */
 pixman_contract (argb8_pixels, (uint64_t *)values, width);
 
-image->store_scanline_raw_32 (image, x, y, width, argb8_pixels);
+image->store_scanline_32 (image, x, y, width, argb8_pixels);
 
 free (argb8_pixels);
 }
@@ -2688,7 +2688,7 @@ fetch_scanline_generic_64 (pixman_image_t *image,
 /* Fetch the pixels into the first half of buffer and then expand them in
  * place.
  */
-image->bits.fetch_scanline_raw_32 (image, x, y, width, buffer, NULL);
+image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
 
 format = image->bits.format;
 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR   ||
@@ -2711,7 +2711,7 @@ fetch_pixel_generic_64 (bits_image_t *image,
int   offset,
int   line)
 {
-uint32_t pixel32 = image->fetch_pixel_raw_32 (image, offset, line);
+uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
 uint64_t result;
 pixman_format_code_t format;
 
@@ -2743,7 +2743,7 @@ fetch_pixel_generic_lossy_32 (bits_image_t *image,
  int   offset,
  int   line)
 {
-uint64_t pixel64 = image->fetch_pixel_raw_64 (image, offset, line);
+uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line);
 uint32_t result;
 
 pixman_contract (&result, &pixel64, 1);
@@ -2754,12 +2754,12 @@ fetch_pixel_generic_lossy_32 (bits_image_t *image,
 typedef struct
 {
 pixman_format_code_t   format;
-fetch_scanline_t   fetch_scanline_raw_32;
-fetch_scanline_t   fetch_scanline_raw_64;
-fetch_pixel_32_t   fetch_pixel_raw_32;
-fetch_pixel_64_t   fetch_pixel_raw_64;
-store_scanline_t   store_scanline_raw_32;
-store_scanline_t   store_scanline_raw_64;
+fetch_scanline_t   fetch_scanline_32;
+fetch_scanline_t   fetch_scanline_64;
+fetch_pixel_32_t   fetch_pixel_32;
+fetch_pixel_64_t   fetch_pixel_64;
+store_scanline_t   store_scanline_32;
+store_scanline_t   store_scanline_64;
 } format_info_t;
 
 #define FORMAT_INFO(format)\
@@ -2885,12 +2885,12 @@ setup_accessors (bits_image_t *image)
 {
if (info->format == image->format)
{
-   image->fetch_scanline_raw_32 = info->fetch_scanline_raw_32;
-   image->fetch_scanline_raw_64 = info->fetch_scanline_raw_64;
-   image->fetch_pixel_raw_32 = info->fetch_pixel_raw_32;
-   image->fetch_pixel_raw_64 = info->fetch_pixel_raw_64;
-   image->store_scanline_raw_32 = info->store_scanline_raw_32;
-   image->store_scanline_raw_64 = info->store_scanline_raw_64;
+   image->fetch_scanline_32 = info->fetch_scanline_32;
+   image->fetch_scanline_64 = info->fetch_scanline_64;
+   image->fetch_pixel_32 = info->fetch_pixel_32;
+   image->fetch_pixel_64 = info->fetch_pixel_64;
+   image->store_scanline_32 = info->store_scanline_32;
+   image->store_scanline_64 = info->store_scanline_64;

return;
}
@@ -2901,13 +2901,13 @@ setup_accessors (bits_image_t *image)
 
 #ifndef PIXMAN_FB_ACCESSORS
 void
-_pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image);
+_pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
 
 void
-_pixman_bits_image_setup_raw_accessors (bits_image_t *image)
+_pixman_bits_image_setup_accessors (bits_image_t *image)
 {
 if (image->read_func || image->write_func)
-   _pixman_bits_image_setup_raw_accessors_accessors (image);
+   _pixman_bits_image_setup_accessors_accessors (image);
 else
setup_accessors (image);
 }
@@ -2915,7 +2915,7 @@ _pixman_bits_image_setup_raw_accessors (bits_image_t 
*image)
 #else
 
 void
-_pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image)
+_pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
 {
 setup_accessors (image);
 }
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index f8ddcbc..d27256d 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -43,14 +43,14 @@ _pixman_image_store_scanline_32 (bits_imag

[Pixman] [PATCH 6/7] Add some new FAST_PATH flags

2010-07-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The flags are:

 *  AFFINE_TRANSFORM, for affine transforms

 *  Y_UNIT_ZERO, for when the 10 entry in the transformation is zero

 *  FILTER_BILINEAR, for when the image has a bilinear filter

 *  NO_NORMAL_REPEAT, for when the repeat mode is not NORMAL

 *  HAS_TRANSFORM, for when the transform is not NULL

Also add some new FAST_PATH_REPEAT_* macros. These are just shorthands
for the image not having any of the other repeat modes. For example
REPEAT_NORMAL is (NO_NONE | NO_PAD | NO_REFLECT).
---
 pixman/pixman-bits-image.c |1 -
 pixman/pixman-fast-path.c  |9 +++--
 pixman/pixman-image.c  |   36 +++-
 pixman/pixman-private.h|   25 +
 4 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index d27256d..7129e86 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -954,7 +954,6 @@ bits_image_property_changed (pixman_image_t *image)
 bits->common.transform->matrix[2][0] == 0  &&
 bits->common.transform->matrix[2][1] == 0  &&
 bits->common.transform->matrix[2][2] == pixman_fixed_1)
-
 {
image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
image->common.get_scanline_32 = bits_image_fetch_affine_no_alpha;
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 9cc8529..f03752f 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1866,15 +1866,12 @@ static const pixman_fast_path_t c_fast_paths[] =
  FAST_PATH_NO_ACCESSORS|   \
  FAST_PATH_NO_WIDE_FORMAT)
 
-#define HAS_NORMAL_REPEAT_FLAGS
\
-(FAST_PATH_NO_REFLECT_REPEAT | \
- FAST_PATH_NO_PAD_REPEAT | \
- FAST_PATH_NO_NONE_REPEAT)
-
 #define SIMPLE_NEAREST_FAST_PATH(op,s,d,func)  \
 {   PIXMAN_OP_ ## op,  \
PIXMAN_ ## s,   \
-   SCALED_NEAREST_FLAGS | HAS_NORMAL_REPEAT_FLAGS | 
FAST_PATH_X_UNIT_POSITIVE, \
+   (SCALED_NEAREST_FLAGS   |   \
+FAST_PATH_NORMAL_REPEAT|   \
+FAST_PATH_X_UNIT_POSITIVE),\
PIXMAN_null, 0, \
PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op,   \
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 5c6d415..269c3c1 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -297,21 +297,33 @@ compute_image_info (pixman_image_t *image)
 /* Transform */
 if (!image->common.transform)
 {
-   flags |= (FAST_PATH_ID_TRANSFORM | FAST_PATH_X_UNIT_POSITIVE);
+   flags |= (FAST_PATH_ID_TRANSFORM|
+ FAST_PATH_X_UNIT_POSITIVE |
+ FAST_PATH_Y_UNIT_ZERO |
+ FAST_PATH_AFFINE_TRANSFORM);
 }
 else
 {
-   if (image->common.transform->matrix[0][1] == 0 &&
-   image->common.transform->matrix[1][0] == 0 &&
-   image->common.transform->matrix[2][0] == 0 &&
-   image->common.transform->matrix[2][1] == 0 &&
+   flags |= FAST_PATH_HAS_TRANSFORM;
+
+   if (image->common.transform->matrix[2][0] == 0  &&
+   image->common.transform->matrix[2][1] == 0  &&
image->common.transform->matrix[2][2] == pixman_fixed_1)
{
-   flags |= FAST_PATH_SCALE_TRANSFORM;
+   flags |= FAST_PATH_AFFINE_TRANSFORM;
+
+   if (image->common.transform->matrix[0][1] == 0 &&
+   image->common.transform->matrix[1][0] == 0)
+   {
+   flags |= FAST_PATH_SCALE_TRANSFORM;
+   }
}
 
if (image->common.transform->matrix[0][0] > 0)
flags |= FAST_PATH_X_UNIT_POSITIVE;
+
+   if (image->common.transform->matrix[1][0] == 0)
+   flags |= FAST_PATH_Y_UNIT_ZERO;
 }
 
 /* Alpha map */
@@ -326,6 +338,12 @@ compute_image_info (pixman_image_t *image)
flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
break;
 
+case PIXMAN_FILTER_BILINEAR:
+case PIXMAN_FILTER_GOOD:
+case PIXMAN_FILTER_BEST:
+   flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
+   break;
+
 case PIXMAN_FILTER_CONVOLUTION:
break;
 
@@ -338,15 +3

[Pixman] [PATCH 7/7] Store the various bits image fetchers in a table with formats and flags.

2010-07-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Similarly to how the fast paths are done, put the various bits_image
fetchers in a table, so that we can quickly find the best one based on
the image's flags and format.
---
 pixman/pixman-bits-image.c |  126 ++-
 1 files changed, 76 insertions(+), 50 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 7129e86..a32ebcc 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -906,62 +906,88 @@ bits_image_fetch_untransformed_64 (pixman_image_t * image,
 }
 }
 
+typedef struct
+{
+pixman_format_code_t   format;
+uint32_t   flags;
+fetch_scanline_t   fetch_32;
+fetch_scanline_t   fetch_64;
+} fetcher_info_t;
+
+static const fetcher_info_t fetcher_info[] =
+{
+{ PIXMAN_solid,
+  FAST_PATH_NO_ALPHA_MAP,
+  bits_image_fetch_solid_32,
+  bits_image_fetch_solid_64
+},
+
+{ PIXMAN_any,
+  (FAST_PATH_NO_ALPHA_MAP  |
+   FAST_PATH_ID_TRANSFORM  |
+   FAST_PATH_NO_CONVOLUTION_FILTER |
+   FAST_PATH_NO_PAD_REPEAT |
+   FAST_PATH_NO_REFLECT_REPEAT),
+  bits_image_fetch_untransformed_32,
+  bits_image_fetch_untransformed_64
+},
+
+#define FAST_BILINEAR_FLAGS\
+(FAST_PATH_NO_ALPHA_MAP|   \
+ FAST_PATH_NO_ACCESSORS|   \
+ FAST_PATH_HAS_TRANSFORM   |   \
+ FAST_PATH_AFFINE_TRANSFORM|   
\
+ FAST_PATH_X_UNIT_POSITIVE |   \
+ FAST_PATH_Y_UNIT_ZERO |   \
+ FAST_PATH_NONE_REPEAT |   \
+ FAST_PATH_BILINEAR_FILTER)
+
+{ PIXMAN_a8r8g8b8,
+  FAST_BILINEAR_FLAGS,
+  bits_image_fetch_bilinear_no_repeat_,
+  _pixman_image_get_scanline_generic_64
+},
+
+{ PIXMAN_x8r8g8b8,
+  FAST_BILINEAR_FLAGS,
+  bits_image_fetch_bilinear_no_repeat_,
+  _pixman_image_get_scanline_generic_64
+},
+
+{ PIXMAN_any,
+  (FAST_PATH_NO_ALPHA_MAP |
+   FAST_PATH_HAS_TRANSFORM |
+   FAST_PATH_AFFINE_TRANSFORM),
+  bits_image_fetch_affine_no_alpha,
+  _pixman_image_get_scanline_generic_64
+},
+
+{ PIXMAN_any, 0, bits_image_fetch_general, 
_pixman_image_get_scanline_generic_64 },
+
+{ PIXMAN_null },
+};
+
 static void
 bits_image_property_changed (pixman_image_t *image)
 {
-bits_image_t *bits = (bits_image_t *)image;
+uint32_t flags = image->common.flags;
+pixman_format_code_t format = image->common.extended_format_code;
+const fetcher_info_t *info;
 
-_pixman_bits_image_setup_accessors (bits);
+_pixman_bits_image_setup_accessors (&image->bits);
 
-if (bits->common.alpha_map)
-{
-   image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
-   image->common.get_scanline_32 = bits_image_fetch_general;
-}
-else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
- bits->width == 1 &&
- bits->height == 1)
-{
-   image->common.get_scanline_64 = bits_image_fetch_solid_64;
-   image->common.get_scanline_32 = bits_image_fetch_solid_32;
-}
-else if (!bits->common.transform &&
- bits->common.filter != PIXMAN_FILTER_CONVOLUTION &&
- (bits->common.repeat == PIXMAN_REPEAT_NONE ||
-  bits->common.repeat == PIXMAN_REPEAT_NORMAL))
-{
-   image->common.get_scanline_64 = bits_image_fetch_untransformed_64;
-   image->common.get_scanline_32 = bits_image_fetch_untransformed_32;
-}
-else if (bits->common.transform&&
-bits->common.transform->matrix[2][0] == 0  &&
-bits->common.transform->matrix[2][1] == 0  &&
-bits->common.transform->matrix[2][2] == pixman_fixed_1 &&
-bits->common.transform->matrix[0][0] > 0   &&
-bits->common.transform->matrix[1][0] == 0  &&
-!bits->read_func   &&
-(bits->common.filter == PIXMAN_FILTER_BILINEAR ||
- bits->common.filter == PIXMAN_FILTER_GOOD ||
- bits->common.filter == PIXMAN_FILTER_BEST)&&
-bits->common.repeat == PIXMAN_REPEAT_NONE  &&
-(bits->format == PIXMAN_a8r8g8b8   ||
- bits->format == PIXMAN_x8

[Pixman] [PATCH] Add support for AltiVec detection for OpenBSD/PowerPC.

2010-07-31 Thread Søren Sandmann
From: Brad Smith 

Bug 29331.
---
 pixman/pixman-cpu.c |   25 -
 1 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index e96b140..1b31885 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -61,6 +61,29 @@ pixman_have_vmx (void)
 return have_vmx;
 }
 
+#elif defined (__OpenBSD__)
+#include 
+#include 
+#include 
+
+static pixman_bool_t
+pixman_have_vmx (void)
+{
+if (!initialized)
+{
+   int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
+   size_t length = sizeof(have_vmx);
+   int error =
+   sysctl (&mib, 2, &have_vmx, &length, NULL, 0);
+
+   if (error)
+   have_vmx = FALSE;
+
+   initialized = TRUE;
+}
+return have_vmx;
+}
+
 #elif defined (__linux__)
 #include 
 #include 
@@ -123,7 +146,7 @@ pixman_have_vmx (void)
 return have_vmx;
 }
 
-#else /* !__APPLE__ && !__linux__ */
+#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
 #include 
 #include 
 
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Use stdint.h on OpenBSD

2010-07-31 Thread Søren Sandmann
From: Brad Smith 

OpenBSD has had stdint.h for a long time now. Bug 29330.
---
 pixman/pixman.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman.h b/pixman/pixman.h
index 9981f0d..c1ecedc 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -87,7 +87,7 @@ PIXMAN_BEGIN_DECLS
 
 #if !defined (PIXMAN_DONT_DEFINE_STDINT)
 
-#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined 
(_sgi) || defined (__sun) || defined (sun) || defined (__digital__) || defined 
(__HP_cc)
+#if defined (_SVR4) || defined (SVR4) || defined (_sgi) || defined (__sun) || 
defined (sun) || defined (__digital__) || defined (__HP_cc)
 #  include 
 /* VS 2010 (_MSC_VER 1600) has stdint.h */
 #elif defined (_MSC_VER) && _MSC_VER < 1600
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Add alpha-loop test program

2010-08-04 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This tests what happens if you attempt to make an image with an alpha
map that has the image as its alpha map. This results in an infinite
loop in _pixman_image_validate(), so the test sets up a SIGALRM to
exit if it runs for more than five seconds.
---
 configure.ac  |   12 +++-
 test/Makefile.am  |4 
 test/alpha-loop.c |   29 +
 test/utils.c  |   33 +
 test/utils.h  |3 +++
 5 files changed, 80 insertions(+), 1 deletions(-)
 create mode 100644 test/alpha-loop.c

diff --git a/configure.ac b/configure.ac
index 98c2783..acec8a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -600,13 +600,23 @@ AC_SUBST(DEP_CFLAGS)
 AC_SUBST(DEP_LIBS)
 
 dnl =
-dnl posix_memalign 
+dnl posix_memalign, sigaction, alarm
 
 AC_CHECK_FUNC(posix_memalign, have_posix_memalign=yes, have_posix_memalign=no)
 if test x$have_posix_memalign = xyes; then
AC_DEFINE(HAVE_POSIX_MEMALIGN, 1, [Whether we have posix_memalign()])
 fi
 
+AC_CHECK_FUNC(sigaction, have_sigaction=yes, have_sigaction=no)
+if test x$have_sigaction = xyes; then
+   AC_DEFINE(HAVE_SIGACTION, 1, [Whether we have sigaction()])
+fi
+
+AC_CHECK_FUNC(alarm, have_alarm=yes, have_alarm=no)
+if test x$have_alarm = xyes; then
+   AC_DEFINE(HAVE_ALARM, 1, [Whether we have alarm()])
+fi
+
 dnl =
 dnl Thread local storage
 
diff --git a/test/Makefile.am b/test/Makefile.am
index 2a7aea2..5273bec 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,6 +13,7 @@ TESTPROGRAMS =\
gradient-crash-test \
trap-crasher\
alphamap\
+   alpha-loop  \
scaling-crash-test  \
blitters-test   \
scaling-test\
@@ -39,6 +40,9 @@ scaling_test_SOURCES = scaling-test.c utils.c utils.h
 alphamap_LDADD = $(TEST_LDADD)
 alphamap_SOURCES = alphamap.c utils.c utils.h
 
+alpha_loop_LDADD = $(TEST_LDADD)
+alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/alpha-loop.c b/test/alpha-loop.c
new file mode 100644
index 000..e4d90a9
--- /dev/null
+++ b/test/alpha-loop.c
@@ -0,0 +1,29 @@
+#include 
+#include 
+#include "utils.h"
+
+#define WIDTH 400
+#define HEIGHT 200
+
+int
+main (int argc, char **argv)
+{
+uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
+uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+
+pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, 
(uint32_t *)alpha, WIDTH);
+pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, 
HEIGHT, dest, WIDTH * 4);
+pixman_image_t *s = pixman_image_create_bits (PIXMAN_a2r10g10b10, WIDTH, 
HEIGHT, src, WIDTH * 4);
+
+fail_after (5, "Infinite loop detected: 5 seconds without progress\n");
+
+pixman_image_set_alpha_map (s, a, 0, 0);
+pixman_image_set_alpha_map (a, s, 0, 0);
+
+pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, 
WIDTH, HEIGHT);
+
+pixman_image_unref (s);
+
+return 0;
+}
diff --git a/test/utils.c b/test/utils.c
index 1ee5c9c..d95cbc2 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -1,4 +1,9 @@
 #include "utils.h"
+#include 
+
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
 
 /* Random number seed
  */
@@ -319,3 +324,31 @@ fuzzer_test_main (const char *test_name,
 
 return 0;
 }
+
+static const char *global_msg;
+
+static void
+on_alarm (int signo)
+{
+printf ("%s\n", global_msg);
+exit (1);
+}
+
+void
+fail_after (int seconds, const char *msg)
+{
+#ifdef HAVE_SIGACTION
+#ifdef HAVE_ALARM
+struct sigaction action;
+
+global_msg = msg;
+
+memset (&action, 0, sizeof (action));
+action.sa_handler = on_alarm;
+
+alarm (seconds);
+
+sigaction (SIGALRM, &action, NULL);
+#endif
+#endif
+}
diff --git a/test/utils.h b/test/utils.h
index 95d809a..bfb76a5 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -62,3 +62,6 @@ fuzzer_test_main (const char *test_name,
  uint32_t(*test_function)(int testnum, int verbose),
  int argc,
  const char *argv[]);
+
+void
+fail_after (int seconds, const char *msg);
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] pixman_image_set_alpha_map(): Disallow alpha map cycles

2010-08-04 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

If someone tries to set an alpha map that itself has an alpha map,
simply return. Also, if someone tries to add an alpha map to an image
that is being _used_ as an alpha map, simply return.

This ensures that an alpha map can never have an alpha map.
---
 pixman/pixman-image.c   |   30 +++---
 pixman/pixman-private.h |1 +
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 269c3c1..0b8bb3c 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -101,6 +101,7 @@ _pixman_image_allocate (void)
 
pixman_region32_init (&common->clip_region);
 
+   common->alpha_count = 0;
common->have_clip_region = FALSE;
common->clip_sources = FALSE;
common->transform = NULL;
@@ -195,9 +196,6 @@ pixman_image_unref (pixman_image_t *image)
if (common->filter_params)
free (common->filter_params);
 
-   if (common->alpha_map)
-   pixman_image_unref ((pixman_image_t *)common->alpha_map);
-
if (image->type == LINEAR ||
image->type == RADIAL ||
image->type == CONICAL)
@@ -668,15 +666,41 @@ pixman_image_set_alpha_map (pixman_image_t *image,
 
 return_if_fail (!alpha_map || alpha_map->type == BITS);
 
+if (alpha_map && common->alpha_count > 0)
+{
+   /* If this image is being used as an alpha map itself,
+* then you can't give it an alpha map of its own.
+*/
+   return;
+}
+
+if (alpha_map && alpha_map->common.alpha_map)
+{
+   /* If the image has an alpha map of its own,
+* then it can't be used as an alpha map itself
+*/
+   return;
+}
+
 if (common->alpha_map != (bits_image_t *)alpha_map)
 {
if (common->alpha_map)
+   {
+   common->alpha_map->common.alpha_count--;
+
pixman_image_unref ((pixman_image_t *)common->alpha_map);
+   }
 
if (alpha_map)
+   {
common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
+
+   common->alpha_map->common.alpha_count++;
+   }
else
+   {
common->alpha_map = NULL;
+   }
 }
 
 common->alpha_origin_x = x;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0629c42..c4e6bb8 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -80,6 +80,7 @@ struct image_common
 image_type_ttype;
 int32_t ref_count;
 pixman_region32_t   clip_region;
+int32_talpha_count;/* How many times this 
image is being used as an alpha map */
 pixman_bool_t   have_clip_region;   /* FALSE if there is no 
clip */
 pixman_bool_t   client_clip;/* Whether the source clip 
was
   set by a client */
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Merge pixman_image_composite32() and do_composite().

2010-08-22 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

There is not much point having a separate function that just validates
the images. Also add a boolean return to lookup_composite_function()
so that we can return if no composite function is found.
---
 pixman/pixman.c |  131 +++---
 1 files changed, 56 insertions(+), 75 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index ddd4935..402c72c 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -501,7 +501,7 @@ typedef struct
 
 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
 
-static force_inline void
+static force_inline pixman_bool_t
 lookup_composite_function (pixman_op_t op,
   pixman_format_code_t src_format,
   uint32_t src_flags,
@@ -577,7 +577,7 @@ lookup_composite_function (pixman_op_t  
op,
++info;
}
 }
-return;
+return FALSE;
 
 update_cache:
 if (i)
@@ -595,6 +595,8 @@ update_cache:
cache->cache[0].fast_path.dest_flags = dest_flags;
cache->cache[0].fast_path.func = *out_func;
 }
+
+return TRUE;
 }
 
 static pixman_bool_t
@@ -803,19 +805,38 @@ analyze_extent (pixman_image_t *image, int x, int y,
 return TRUE;
 }
 
-static void
-do_composite (pixman_op_t op,
- pixman_image_t  *src,
- pixman_image_t  *mask,
- pixman_image_t  *dest,
- int  src_x,
- int  src_y,
- int  mask_x,
- int  mask_y,
- int  dest_x,
- int  dest_y,
- int  width,
- int  height)
+/*
+ * Work around GCC bug causing crashes in Mozilla with SSE2
+ *
+ * When using -msse, gcc generates movdqa instructions assuming that
+ * the stack is 16 byte aligned. Unfortunately some applications, such
+ * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
+ * causes the movdqa instructions to fail.
+ *
+ * The __force_align_arg_pointer__ makes gcc generate a prologue that
+ * realigns the stack pointer to 16 bytes.
+ *
+ * On x86-64 this is not necessary because the standard ABI already
+ * calls for a 16 byte aligned stack.
+ *
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
+ */
+#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && 
!defined(__amd64__)
+__attribute__((__force_align_arg_pointer__))
+#endif
+PIXMAN_EXPORT void
+pixman_image_composite32 (pixman_op_t  op,
+  pixman_image_t * src,
+  pixman_image_t * mask,
+  pixman_image_t * dest,
+  int32_t  src_x,
+  int32_t  src_y,
+  int32_t  mask_x,
+  int32_t  mask_y,
+  int32_t  dest_x,
+  int32_t  dest_y,
+  int32_t  width,
+  int32_t  height)
 {
 pixman_format_code_t src_format, mask_format, dest_format;
 uint32_t src_flags, mask_flags, dest_flags;
@@ -831,6 +852,11 @@ do_composite (pixman_op_t op,
 pixman_implementation_t *imp;
 pixman_composite_func_t func;
 
+_pixman_image_validate (src);
+if (mask)
+   _pixman_image_validate (mask);
+_pixman_image_validate (dest);
+
 src_format = src->common.extended_format_code;
 src_flags = src->common.flags;
 
@@ -907,20 +933,21 @@ do_composite (pixman_op_top,
 if (op == PIXMAN_OP_DST)
goto out;
 
-lookup_composite_function (op,
-  src_format, src_flags,
-  mask_format, mask_flags,
-  dest_format, dest_flags,
-  &imp, &func);
-
-walk_region_internal (imp, op,
- src, mask, dest,
- src_x, src_y, mask_x, mask_y,
- dest_x, dest_y,
- width, height,
- (src_flags & FAST_PATH_SIMPLE_REPEAT),
- (mask_flags & FAST_PATH_SIMPLE_REPEAT),
- ®ion, func);
+if (lookup_composite_function (op,
+  src_format, src_flags,
+  mask_format, mask_flags,
+  dest_format, dest_flags,
+  &imp, &func))
+{
+   walk_region_internal (imp, op,
+ src, mask, dest,
+ src_x, src_y, mask_x, mask_y,
+

[Pixman] [PATCH] Be more paranoid about checking for GTK+

2010-08-23 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

From time to time peole run into issues where the configure script
detects GTK+ when it is either not installed, or not functional due to
a missing pixman. Most recently,

  https://bugs.freedesktop.org/show_bug.cgi?id=29736

This patch makes the configure script more paranoid by

- always using PKG_CHECK_MODULES and not PKG_CHECK_EXISTS, since it
seems PKG_CHECK_EXISTS will sometimes return true even if a dependency
of GTK+, such as pixman-1, is missing.

- explicitly checking that pixman-1 is installed before enabling GTK+.

Cc: my.somewhat.lengthy.loginn...@gmail.com
---
 configure.ac |   14 ++
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index d8a8999..dbff2a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -178,7 +178,6 @@ AC_SUBST(PIXMAN_VERSION_MICRO)
 AC_SUBST(LT_VERSION_INFO)
 
 # Check for dependencies
-#PKG_CHECK_MODULES(DEP, x11)
 
 PIXMAN_CHECK_CFLAG([-Wall])
 PIXMAN_CHECK_CFLAG([-fno-strict-aliasing])
@@ -585,11 +584,18 @@ AC_ARG_ENABLE(gtk,
[enable_gtk=$enableval], [enable_gtk=auto])
 
 PKG_PROG_PKG_CONFIG
+
+if test $enable_gtk = yes ; then
+   AC_CHECK_LIB([pixman-1], [pixman_version_string])
+   PKG_CHECK_MODULES(GTK, [gtk+-2.0 pixman-1])
+fi
+
 if test $enable_gtk = auto ; then
-   PKG_CHECK_EXISTS([gtk+-2.0], [enable_gtk=yes], [enable_gtk=no])
+   AC_CHECK_LIB([pixman-1], [pixman_version_string], [enable_gtk=auto], 
[enable_gtk=no])
 fi
-if test $enable_gtk = yes ; then
-   PKG_CHECK_MODULES(GTK, [gtk+-2.0])
+
+if test $enable_gtk = auto ; then
+   PKG_CHECK_MODULES(GTK, [gtk+-2.0 pixman-1], [enable_gtk=yes], 
[enable_gtk=no])
 fi
 
 AM_CONDITIONAL(HAVE_GTK, [test "x$enable_gtk" = xyes])
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Store a2b2g2r2 pixel through the WRITE macro

2010-08-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Otherwise, accessor functions won't work.
---
 pixman/pixman-access.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 56de711..f1ce0ba 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -2425,11 +2425,11 @@ store_scanline_a2b2g2r2 (bits_image_t *  image,
 {
SPLIT_A (values[i]);

-   *(pixel++) =
-   ((a ) & 0xc0) |
-   ((b >> 2) & 0x30) |
-   ((g >> 4) & 0x0c) |
-   ((r >> 6)   );
+   WRITE (image, pixel++,
+  ((a ) & 0xc0) |
+  ((b >> 2) & 0x30) |
+  ((g >> 4) & 0x0c) |
+  ((r >> 6)   ));
 }
 }
 
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] When pixman_compute_composite_region32() return FALSE, don't fini the region.

2010-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The rule is that the region passed in must be initialized and that the
region returned will still be valid. Ie., the lifecycle is the
responsibility of the caller, regardless of what the function returns.

Previously, composite_region32() would finalize the region and then
return FALSE, and then the caller would finalize the region again,
leading to memory corruption in some cases.
---
 pixman/pixman.c |   14 +-
 1 files changed, 1 insertions(+), 13 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index 402c72c..62b58b8 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -302,17 +302,13 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 if (region->extents.x1 >= region->extents.x2 ||
 region->extents.y1 >= region->extents.y2)
 {
-   pixman_region32_init (region);
return FALSE;
 }
 
 if (dst_image->common.have_clip_region)
 {
if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
-   {
-   pixman_region32_fini (region);
return FALSE;
-   }
 }
 
 if (dst_image->common.alpha_map && 
dst_image->common.alpha_map->common.have_clip_region)
@@ -321,7 +317,6 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 -dst_image->common.alpha_origin_x,
 -dst_image->common.alpha_origin_y))
{
-   pixman_region32_fini (region);
return FALSE;
}
 }
@@ -330,10 +325,7 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 if (src_image->common.have_clip_region)
 {
if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - 
src_y))
-   {
-   pixman_region32_fini (region);
return FALSE;
-   }
 }
 if (src_image->common.alpha_map && 
src_image->common.alpha_map->common.have_clip_region)
 {
@@ -341,7 +333,6 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
dest_x - (src_x - 
src_image->common.alpha_origin_x),
dest_y - (src_y - 
src_image->common.alpha_origin_y)))
{
-   pixman_region32_fini (region);
return FALSE;
}
 }
@@ -349,17 +340,14 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 if (mask_image && mask_image->common.have_clip_region)
 {
if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - 
mask_y))
-   {
-   pixman_region32_fini (region);
return FALSE;
-   }
+
if (mask_image->common.alpha_map && 
mask_image->common.alpha_map->common.have_clip_region)
{
if (!clip_source_image (region, (pixman_image_t 
*)mask_image->common.alpha_map,
dest_x - (mask_x - 
mask_image->common.alpha_origin_x),
dest_y - (mask_y - 
mask_image->common.alpha_origin_y)))
{
-   pixman_region32_fini (region);
return FALSE;
}
}
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Silence some warnings about uninitialized variables

2010-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Neither were real problems, but GCC were complaining about them.
---
 pixman/pixman.c  |3 +++
 test/composite.c |1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index 62b58b8..47ffdd6 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -613,6 +613,9 @@ compute_sample_extents (pixman_transform_t *transform,
 {
int i;
 
+   /* Silence GCC */
+   tx1 = ty1 = tx2 = ty2 = 0;
+
for (i = 0; i < 4; ++i)
{
pixman_fixed_48_16_t tx, ty;
diff --git a/test/composite.c b/test/composite.c
index 0624cd3..b530a20 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -882,6 +882,7 @@ main (void)
 mask.size? TRUE : FALSE);
break;
 default:
+   ok = FALSE; /* Silence GCC */
 break;
}
group_ok = group_ok && ok;
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Add FAST_PATH_NO_ALPHA_MAP to the standard destination flags.

2010-09-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

We can't in general take a fast path if the destination has an alpha
map.
---
 pixman/pixman-private.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index dedea0b..3557fb2 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -613,6 +613,7 @@ _pixman_choose_implementation (void);
  FAST_PATH_COMPONENT_ALPHA)
 #define FAST_PATH_STD_DEST_FLAGS   \
 (FAST_PATH_NO_ACCESSORS|   \
+ FAST_PATH_NO_ALPHA_MAP|   \
  FAST_PATH_NO_WIDE_FORMAT)
 
 #define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, 
func) \
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Do opacity computation with shifts instead of comparing with 0

2010-09-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Also add a COMPILE_TIME_ASSERT() macro and use it to assert that the
shift is correct.
---
 pixman/pixman-private.h |3 +++
 pixman/pixman.c |   14 +-
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 3557fb2..36b9d91 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -744,6 +744,9 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
 
 #undef DEBUG
 
+#define COMPILE_TIME_ASSERT(x) \
+do { typedef int compile_time_assertion [(x)?1:-1]; } while (0)
+
 /* Turn on debugging depending on what type of release this is
  */
 #if (((PIXMAN_VERSION_MICRO % 2) == 0) && ((PIXMAN_VERSION_MINOR % 2) == 1))
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 47ffdd6..cdf4b75 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -139,14 +139,18 @@ optimize_operator (pixman_op_t op,
   uint32_tdst_flags)
 {
 pixman_bool_t is_source_opaque, is_dest_opaque;
-int opaqueness;
 
-is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE) != 0;
-is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE) != 0;
+#define OPAQUE_SHIFT 13
+
+COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
+
+is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
+is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
 
-opaqueness = ((is_dest_opaque << 1) | is_source_opaque);
+is_dest_opaque >>= OPAQUE_SHIFT - 1;
+is_source_opaque >>= OPAQUE_SHIFT;
 
-return operator_table[op].opaque_info[opaqueness];
+return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
 }
 
 static void
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 1/5] Add fence_malloc() and fence_free().

2010-09-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

These variants of malloc() and free() try to surround the allocated
memory with protected pages so that out-of-bounds accessess will cause
a segmentation fault.

If mprotect() and getpagesize() are not available, these functions are
simply equivalent to malloc() and free().
---
 configure.ac |   10 +
 test/utils.c |  105 +-
 test/utils.h |   11 +-
 3 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index dbff2a6..652fec9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -623,6 +623,16 @@ if test x$have_alarm = xyes; then
AC_DEFINE(HAVE_ALARM, 1, [Whether we have alarm()])
 fi
 
+AC_CHECK_FUNC(mprotect, have_mprotect=yes, have_mprotect=no)
+if test x$have_mprotect = xyes; then
+   AC_DEFINE(HAVE_MPROTECT, 1, [Whether we have mprotect()])
+fi
+
+AC_CHECK_FUNC(getpagesize, have_getpagesize=yes, have_=no)
+if test x$have_getpagesize = xyes; then
+   AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()])
+fi
+
 dnl =
 dnl Thread local storage
 
diff --git a/test/utils.c b/test/utils.c
index d95cbc2..0134e04 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -5,6 +5,8 @@
 #include 
 #endif
 
+#include 
+
 /* Random number seed
  */
 
@@ -197,10 +199,111 @@ image_endian_swap (pixman_image_t *img, int bpp)
 }
 }
 
+#define N_LEADING_PROTECTED10
+#define N_TRAILING_PROTECTED   10
+#define INITIAL_PAGE
+
+typedef struct
+{
+void *addr;
+uint32_t len;
+uint8_t *trailing;
+} info_t;
+
+#if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE)
+
+void *
+fence_malloc (uint32_t len)
+{
+unsigned long page_size = getpagesize();
+unsigned long page_mask = page_size - 1;
+uint32_t n_payload_bytes = (len + page_mask) & ~page_mask;
+uint32_t n_bytes =
+   (len +
+page_size * (N_LEADING_PROTECTED + N_TRAILING_PROTECTED + 2) +
+n_payload_bytes) & ~page_mask;
+uint8_t *initial_page;
+uint8_t *leading_protected;
+uint8_t *trailing_protected;
+uint8_t *payload;
+uint8_t *addr;
+
+addr = malloc (n_bytes);
+
+if (!addr)
+{
+   printf ("malloc failed on %u %u\n", len, n_bytes);
+   return NULL;
+}
+
+initial_page = (uint8_t *)(((unsigned long)addr + page_mask) & ~page_mask);
+leading_protected = initial_page + page_size;
+payload = leading_protected + N_LEADING_PROTECTED * page_size;
+trailing_protected = payload + n_payload_bytes;
+
+((info_t *)initial_page)->addr = addr;
+((info_t *)initial_page)->len = len;
+((info_t *)initial_page)->trailing = trailing_protected;
+
+if (mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
+ PROT_NONE) == -1)
+{
+   free (addr);
+   return NULL;
+}
+
+if (mprotect (trailing_protected, N_TRAILING_PROTECTED * page_size,
+ PROT_NONE) == -1)
+{
+   mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
+ PROT_READ | PROT_WRITE);
+
+   free (addr);
+   return NULL;
+}
+
+return payload;
+}
+
+void
+fence_free (void *data)
+{
+uint32_t page_size = getpagesize();
+uint8_t *payload = data;
+uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size;
+uint8_t *initial_page = leading_protected - page_size;
+info_t *info = (info_t *)initial_page;
+uint8_t *trailing_protected = info->trailing;
+
+mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
+ PROT_READ | PROT_WRITE);
+
+mprotect (trailing_protected, N_LEADING_PROTECTED * page_size,
+ PROT_READ | PROT_WRITE);
+
+free (info->addr);
+}
+
+#else
+
+void *
+fence_malloc (uint32_t len)
+{
+return malloc (len);
+}
+
+void
+fence_free (void *data)
+{
+free (data);
+}
+
+#endif
+
 uint8_t *
 make_random_bytes (int n_bytes)
 {
-uint8_t *bytes = malloc (n_bytes);
+uint8_t *bytes = fence_malloc (n_bytes);
 int i;
 
 if (!bytes)
diff --git a/test/utils.h b/test/utils.h
index a39af02..14e3c8b 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -51,7 +51,16 @@ compute_crc32 (uint32_tin_crc32,
 void
 image_endian_swap (pixman_image_t *img, int bpp);
 
-/* Generate n_bytes random bytes in malloced memory */
+/* Allocate memory that is bounded by protected pages,
+ * so that out-of-bounds access will cause segfaults
+ */
+void *
+fence_malloc (uint32_t len);
+
+void
+fence_free (void *data);
+
+/* Generate n_bytes random bytes in fence_malloced memory */
 uint8_t *
 make_random_bytes (int n_bytes);
 
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 2/5] Update and extend the alphamap test

2010-09-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

- Test many more combinations of formats

- Test destination alpha maps

- Test various different alpha origins

Also add a transformation to the destination, but comment it out
because it is actually broken at the moment (and pretty difficult to
fix).
---
 test/Makefile.am |2 +-
 test/alphamap.c  |  243 --
 2 files changed, 218 insertions(+), 27 deletions(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 3d98e17..f3b2b58 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,9 +13,9 @@ TESTPROGRAMS =\
window-test \
gradient-crash-test \
trap-crasher\
-   alphamap\
alpha-loop  \
scaling-crash-test  \
+   alphamap\
blitters-test   \
scaling-test\
composite
diff --git a/test/alphamap.c b/test/alphamap.c
index e6a25ef..09de387 100644
--- a/test/alphamap.c
+++ b/test/alphamap.c
@@ -2,47 +2,238 @@
 #include 
 #include "utils.h"
 
-#define WIDTH 400
-#define HEIGHT 200
+#define WIDTH 100
+#define HEIGHT 100
 
-int
-main (int argc, char **argv)
+static const pixman_format_code_t formats[] =
+{
+PIXMAN_a8r8g8b8,
+PIXMAN_a2r10g10b10,
+PIXMAN_a4r4g4b4,
+PIXMAN_a8
+};
+
+static const pixman_format_code_t alpha_formats[] =
+{
+PIXMAN_null,
+PIXMAN_a8,
+PIXMAN_a2r10g10b10,
+PIXMAN_a4r4g4b4
+};
+
+static const int origins[] =
 {
-uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
-uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
-uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
-int i;
+0, 10, -100
+};
 
-pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, 
(uint32_t *)alpha, WIDTH);
-pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, 
HEIGHT, dest, WIDTH * 4);
+static const char *
+format_name (pixman_format_code_t format)
+{
+if (format == PIXMAN_a8)
+   return "a8";
+else if (format == PIXMAN_a2r10g10b10)
+   return "a2r10g10b10";
+else if (format == PIXMAN_a8r8g8b8)
+   return "a8r8g8b8";
+else if (format == PIXMAN_a4r4g4b4)
+   return "a4r4g4b4";
+else if (format == PIXMAN_null)
+   return "none";
+else
+   assert (0);
 
-for (i = 0; i < 2; ++i)
+return "";
+}
+
+static pixman_image_t *
+make_image (pixman_format_code_t format)
+{
+uint32_t *bits;
+uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
+
+bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
+
+return pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
+}
+
+static pixman_image_t *
+create_image (pixman_format_code_t format, pixman_format_code_t alpha_format,
+ int alpha_origin_x, int alpha_origin_y)
+{
+pixman_image_t *image = make_image (format);
+
+if (alpha_format != PIXMAN_null)
 {
-   pixman_format_code_t sformat = (i == 0)? PIXMAN_a8r8g8b8 : 
PIXMAN_a2r10g10b10;
-   pixman_image_t *s = pixman_image_create_bits (sformat, WIDTH, HEIGHT, 
src, WIDTH * 4);
-   int j, k;
+   pixman_image_t *alpha = make_image (alpha_format);
 
-   pixman_image_set_alpha_map (s, a, 0, 0);
+   pixman_image_set_alpha_map (image, alpha,
+   alpha_origin_x, alpha_origin_y);
+}
 
-   pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, 
WIDTH, HEIGHT);
+return image;
+}
 
-   for (j = 0; j < HEIGHT; ++j)
+static uint8_t
+get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
+{
+uint8_t *bits;
+uint8_t r;
+
+if (image->common.alpha_map)
+{
+   if (x - orig_x >= 0 && x - orig_x < WIDTH &&
+   y - orig_y >= 0 && y - orig_y < HEIGHT)
+   {
+   image = (pixman_image_t *)image->common.alpha_map;
+
+   x -= orig_x;
+   y -= orig_y;
+   }
+   else
{
-   for (k = 0; k < WIDTH; ++k)
+   return 0;
+   }
+}
+
+bits = (uint8_t *)image->bits.bits;
+
+if (image->bits.format == PIXMAN_a8)
+{
+   r = bits[y * WIDTH + x];
+}
+else if (image->bits.format == PIXMAN_a2r10g10b10)
+{
+   r = ((uint32_t *)bits)[y * WIDTH + x] >> 30;
+   r |= r << 2;
+   r |= r << 4;
+}
+else if (image->bits.format == PIXMAN_a8r8g8b8)
+{
+   r = ((uint32_t *)bits)[y * WIDTH + x] >> 24;
+}
+else if (image->bits.format == PIXMAN_a4r4g4b4)
+{
+   r = ((uint16_t *)bits)[y * WIDTH + x] >> 12;
+   r |= r << 4;
+}
+else
+{
+   assert (0);
+}
+
+return r;
+}
+
+#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof (

[Pixman] [PATCH 3/5] Rename FAST_PATH_NO_WIDE_FORMAT to FAST_PATH_NARROW_FORMAT

2010-09-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This avoids a negative in the name. Also, by renaming the "wide"
variable in pixman-general.c to "narrow" and fixing up the logic
correspondingly, the code there reads a lot more straightforwardly.
---
 pixman/pixman-fast-path.c |2 +-
 pixman/pixman-general.c   |   46 ++--
 pixman/pixman-image.c |4 +-
 pixman/pixman-private.h   |6 ++--
 4 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index f03752f..6dee472 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1864,7 +1864,7 @@ static const pixman_fast_path_t c_fast_paths[] =
  FAST_PATH_NO_ALPHA_MAP|   \
  FAST_PATH_NEAREST_FILTER  |   \
  FAST_PATH_NO_ACCESSORS|   \
- FAST_PATH_NO_WIDE_FORMAT)
+ FAST_PATH_NARROW_FORMAT)
 
 #define SIMPLE_NEAREST_FAST_PATH(op,s,d,func)  \
 {   PIXMAN_OP_ ## op,  \
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index fc742c0..fc276bd 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -63,11 +63,11 @@ general_composite_rect  (pixman_implementation_t *imp,
mask && mask->type == BITS ? mask->bits.format : 0;
 const pixman_format_code_t dest_format =
dest->type == BITS ? dest->bits.format : 0;
-const int src_wide = PIXMAN_FORMAT_IS_WIDE (src_format);
-const int mask_wide = mask && PIXMAN_FORMAT_IS_WIDE (mask_format);
-const int dest_wide = PIXMAN_FORMAT_IS_WIDE (dest_format);
-const int wide = src_wide || mask_wide || dest_wide;
-const int Bpp = wide ? 8 : 4;
+const int src_narrow = !PIXMAN_FORMAT_IS_WIDE (src_format);
+const int mask_narrow = !mask || !PIXMAN_FORMAT_IS_WIDE (mask_format);
+const int dest_narrow = !PIXMAN_FORMAT_IS_WIDE (dest_format);
+const int narrow = src_narrow && mask_narrow && dest_narrow;
+const int Bpp = narrow ? 4 : 8;
 uint8_t *scanline_buffer = stack_scanline_buffer;
 uint8_t *src_buffer, *mask_buffer, *dest_buffer;
 fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL;
@@ -106,29 +106,29 @@ general_composite_rect  (pixman_implementation_t *imp,
 
 if (op == PIXMAN_OP_CLEAR)
fetch_src = NULL;
-else if (wide)
-   fetch_src = _pixman_image_get_scanline_64;
-else
+else if (narrow)
fetch_src = _pixman_image_get_scanline_32;
+else
+   fetch_src = _pixman_image_get_scanline_64;
 
 if (!mask || op == PIXMAN_OP_CLEAR)
fetch_mask = NULL;
-else if (wide)
-   fetch_mask = _pixman_image_get_scanline_64;
-else
+else if (narrow)
fetch_mask = _pixman_image_get_scanline_32;
+else
+   fetch_mask = _pixman_image_get_scanline_64;
 
 if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC)
fetch_dest = NULL;
-else if (wide)
-   fetch_dest = _pixman_image_get_scanline_64;
-else
+else if (narrow)
fetch_dest = _pixman_image_get_scanline_32;
-
-if (wide)
-   store = _pixman_image_store_scanline_64;
 else
+   fetch_dest = _pixman_image_get_scanline_64;
+
+if (narrow)
store = _pixman_image_store_scanline_32;
+else
+   store = _pixman_image_store_scanline_64;
 
 /* Skip the store step and composite directly into the
  * destination if the output format of the compose func matches
@@ -148,7 +148,7 @@ general_composite_rect  (pixman_implementation_t *imp,
  op == PIXMAN_OP_OUT_REVERSE   ||
  op == PIXMAN_OP_DST)))
 {
-   if (!wide &&
+   if (narrow &&
!dest->common.alpha_map &&
!dest->bits.write_func)
{
@@ -175,19 +175,19 @@ general_composite_rect  (pixman_implementation_t *imp,
 mask->common.component_alpha&&
 PIXMAN_FORMAT_RGB (mask->bits.format);
 
-if (wide)
+if (narrow)
 {
if (component_alpha)
-   compose = 
(pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
+   compose = _pixman_implementation_combine_32_ca;
else
-   compose = 
(pixman_combine_32_func_t)_pixman_implementation_combine_64;
+   compose = _pixman_implementation_combine_32;
 }
 else
 {
if (component_alpha)
-   compose = _pixman_implementation_combine_32_ca;
+   compose = 
(pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
else
-   compose = _pixman_implementation_combine_32;
+   compose = 
(pixman_combine_32_func_t)_pixman_implementation_combine_64;
 }
 
 if (!compose)
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index cfee865..102df6c 100644
--

[Pixman] [PATCH 4/5] Remove FAST_PATH_NARROW_FORMAT flag if there is a wide alpha map

2010-09-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

If an image has an alpha map that has wide components, then we need to
use 64 bit processing for that image. We detect this situation in
pixman-image.c and remove the FAST_PATH_NARROW_FORMAT flag.

In pixman-general, the wide/narrow decision is now based on the flags
instead of on the formats.
---
 pixman/pixman-general.c |   18 +++---
 pixman/pixman-image.c   |   15 +++
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index fc276bd..4d234a0 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -57,17 +57,6 @@ general_composite_rect  (pixman_implementation_t *imp,
  int32_t  height)
 {
 uint8_t stack_scanline_buffer[SCANLINE_BUFFER_LENGTH * 3];
-const pixman_format_code_t src_format =
-   src->type == BITS ? src->bits.format : 0;
-const pixman_format_code_t mask_format =
-   mask && mask->type == BITS ? mask->bits.format : 0;
-const pixman_format_code_t dest_format =
-   dest->type == BITS ? dest->bits.format : 0;
-const int src_narrow = !PIXMAN_FORMAT_IS_WIDE (src_format);
-const int mask_narrow = !mask || !PIXMAN_FORMAT_IS_WIDE (mask_format);
-const int dest_narrow = !PIXMAN_FORMAT_IS_WIDE (dest_format);
-const int narrow = src_narrow && mask_narrow && dest_narrow;
-const int Bpp = narrow ? 4 : 8;
 uint8_t *scanline_buffer = stack_scanline_buffer;
 uint8_t *src_buffer, *mask_buffer, *dest_buffer;
 fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL;
@@ -77,8 +66,15 @@ general_composite_rect  (pixman_implementation_t *imp,
 pixman_bool_t component_alpha;
 uint32_t *bits;
 int32_t stride;
+int narrow, Bpp;
 int i;
 
+narrow =
+   (src->common.flags & FAST_PATH_NARROW_FORMAT)   &&
+   (!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) &&
+   (dest->common.flags & FAST_PATH_NARROW_FORMAT);
+Bpp = narrow ? 4 : 8;
+
 if (width * Bpp > SCANLINE_BUFFER_LENGTH)
 {
scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 102df6c..029a1df 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -327,10 +327,6 @@ compute_image_info (pixman_image_t *image)
flags |= FAST_PATH_Y_UNIT_ZERO;
 }
 
-/* Alpha map */
-if (!image->common.alpha_map)
-   flags |= FAST_PATH_NO_ALPHA_MAP;
-
 /* Filter */
 switch (image->common.filter)
 {
@@ -454,6 +450,17 @@ compute_image_info (pixman_image_t *image)
break;
 }
 
+/* Alpha map */
+if (!image->common.alpha_map)
+{
+   flags |= FAST_PATH_NO_ALPHA_MAP;
+}
+else
+{
+   if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
+   flags &= ~FAST_PATH_NARROW_FORMAT;
+}
+
 /* Both alpha maps and convolution filters can introduce
  * non-opaqueness in otherwise opaque images. Also
  * an image with component alpha turned on is only opaque
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 5/5] Clip composite region against the destination alpha map extents.

2010-09-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Otherwise we can end up writing outside the alpha map.
---
 pixman/pixman.c |   21 +
 1 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index cdf4b75..285bbfc 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -315,14 +315,27 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
return FALSE;
 }
 
-if (dst_image->common.alpha_map && 
dst_image->common.alpha_map->common.have_clip_region)
+if (dst_image->common.alpha_map)
 {
-   if (!clip_general_image (region, 
&dst_image->common.alpha_map->common.clip_region,
--dst_image->common.alpha_origin_x,
--dst_image->common.alpha_origin_y))
+   if (!pixman_region32_intersect_rect (region, region,
+dst_image->common.alpha_origin_x,
+dst_image->common.alpha_origin_y,
+dst_image->common.alpha_map->width,
+
dst_image->common.alpha_map->height))
{
return FALSE;
}
+   if (!pixman_region32_not_empty (region))
+   return FALSE;
+   if (dst_image->common.alpha_map->common.have_clip_region)
+   {
+   if (!clip_general_image (region, 
&dst_image->common.alpha_map->common.clip_region,
+-dst_image->common.alpha_origin_x,
+-dst_image->common.alpha_origin_y))
+   {
+   return FALSE;
+   }
+   }
 }
 
 /* clip against src */
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 0/5] Fix various alpha map related bugs

2010-09-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Hi,

The following patch series contains some fixes for various alpha-map
related bugs.

The bugs are:

- We don't currently clip the composite region against the extents of
  the alpha map of the destination. This means that if the alpha map
  doesn't cover the entire destination, we will make invalid writes to it.

- If the alpha map is one of the 10bpc formats, then it doesn't have a
  32 bit fetcher installed, which causes crashes. The fix for this is
  to make sure wide alpha maps result in wide processing.

There is also a stylistic change where the NO_WIDE_FORMAT flag is
renamed to FAST_PATH_NARROW_FORMAT to avoid the negative in the name.

Finally, there are some updates to the test suite:

- The alpha map test is much more aggressive. It now demonstrates the
  two bugs above and also tests that destination alpha maps are
  correctly read and written. 

- The alpha map test now also has code to set a transformation on the
  destination, but this is commented out because it causes crashes
  even with the other changes. This problem is somewhat difficult to
  fix because we currently don't have any fetchers that will do
  alphamap processing, but ignore transformations.

- There is a new fence_malloc()/fence_free() pair of utility
  functions. These attempt to allocate the memory surrounded by
  mprotect()ed pages so that invalid reads or writes will cause
  crashes.


Soren



Søren Sandmann Pedersen (5):
  Add fence_malloc() and fence_free().
  Update and extend the alphamap test
  Rename FAST_PATH_NO_WIDE_FORMAT to FAST_PATH_NARROW_FORMAT
  Remove FAST_PATH_NARROW_FORMAT flag if there is a wide alpha map
  Clip composite region against the destination alpha map extents.

 configure.ac  |   10 ++
 pixman/pixman-fast-path.c |2 +-
 pixman/pixman-general.c   |   54 +--
 pixman/pixman-image.c |   19 +++-
 pixman/pixman-private.h   |6 +-
 pixman/pixman.c   |   21 +++-
 test/Makefile.am  |2 +-
 test/alphamap.c   |  243 -
 test/utils.c  |  105 +++-
 test/utils.h  |   11 ++-
 10 files changed, 401 insertions(+), 72 deletions(-)
___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 1/3] Add new FAST_PATH_UNCOMPOSITABLE flag

2010-09-16 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This is set if the image can't be used for compositing, such as when
it's bigger than 0x or has size 0.
---
 pixman/pixman-image.c   |   10 ++
 pixman/pixman-private.h |1 +
 pixman/pixman.c |   10 +++---
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 029a1df..512142d 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -398,6 +398,16 @@ compute_image_info (pixman_image_t *image)
{
code = image->bits.format;
 
+   /* During repeat mode calculations we might convert the
+* width/height of an image to fixed 16.16, so we need
+* them to be smaller than 16 bits.
+*/
+   if (image->bits.width == 0  || image->bits.height == 0 ||
+   image->bits.width >= 0x || image->bits.height >= 0x)
+   {
+   flags |= FAST_PATH_UNCOMPOSITABLE;
+   }
+   
if (!image->common.transform &&
image->common.repeat == PIXMAN_REPEAT_NORMAL)
{
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d85868f..b05a68d 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -572,6 +572,7 @@ _pixman_choose_implementation (void);
 #define FAST_PATH_NO_NORMAL_REPEAT (1 << 21)
 #define FAST_PATH_HAS_TRANSFORM(1 << 22)
 #define FAST_PATH_SAMPLES_OPAQUE   (1 << 23)
+#define FAST_PATH_UNCOMPOSITABLE   (1 << 24)
 
 #define FAST_PATH_PAD_REPEAT   \
 (FAST_PATH_NO_NONE_REPEAT  |   \
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 285bbfc..ea048cc 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -715,13 +715,6 @@ analyze_extent (pixman_image_t *image, int x, int y,
 transform = image->common.transform;
 if (image->common.type == BITS)
 {
-   /* During repeat mode calculations we might convert the
-* width/height of an image to fixed 16.16, so we need
-* them to be smaller than 16 bits.
-*/
-   if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
-   return FALSE;
-
if (image->common.repeat == PIXMAN_REPEAT_NONE &&
(x > extents->x1 || y > extents->y1 ||
 x + image->bits.width < extents->x2 ||
@@ -882,6 +875,9 @@ pixman_image_composite32 (pixman_op_t  op,
 dest_format = dest->common.extended_format_code;
 dest_flags = dest->common.flags;
 
+if ((src_flags | dest_flags | mask_flags) & FAST_PATH_UNCOMPOSITABLE)
+   return;
+
 /* Check for pixbufs */
 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
(src->type == BITS && src->bits.bits == mask->bits.bits)   &&
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 2/3] Move some of the FAST_PATH_COVERS_CLIP computation to pixman-image.c

2010-09-16 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

When an image is solid or repeating, the FAST_PATH_COVERS_CLIP flag
can be set in compute_image_info().

Also the code that turned this flag off in pixman.c was not correct;
it didn't take transformations into account. With this patch, pixman.c
doesn't set the flag by default, but instead relies on the call to
compute_samples_extents() to set it when possible.
---
 pixman/pixman-image.c |   25 +
 pixman/pixman.c   |   21 +
 2 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 512142d..8d92dd9 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -353,19 +353,34 @@ compute_image_info (pixman_image_t *image)
 switch (image->common.repeat)
 {
 case PIXMAN_REPEAT_NONE:
-   flags |= FAST_PATH_NO_REFLECT_REPEAT | FAST_PATH_NO_PAD_REPEAT | 
FAST_PATH_NO_NORMAL_REPEAT;
+   flags |=
+   FAST_PATH_NO_REFLECT_REPEAT |
+   FAST_PATH_NO_PAD_REPEAT |
+   FAST_PATH_NO_NORMAL_REPEAT;
break;
 
 case PIXMAN_REPEAT_REFLECT:
-   flags |= FAST_PATH_NO_PAD_REPEAT | FAST_PATH_NO_NONE_REPEAT | 
FAST_PATH_NO_NORMAL_REPEAT;
+   flags |=
+   FAST_PATH_NO_PAD_REPEAT |
+   FAST_PATH_NO_NONE_REPEAT|
+   FAST_PATH_NO_NORMAL_REPEAT  |
+   FAST_PATH_COVERS_CLIP;
break;
 
 case PIXMAN_REPEAT_PAD:
-   flags |= FAST_PATH_NO_REFLECT_REPEAT | FAST_PATH_NO_NONE_REPEAT | 
FAST_PATH_NO_NORMAL_REPEAT;
+   flags |=
+   FAST_PATH_NO_REFLECT_REPEAT |
+   FAST_PATH_NO_NONE_REPEAT|
+   FAST_PATH_NO_NORMAL_REPEAT  |
+   FAST_PATH_COVERS_CLIP;
break;
 
 default:
-   flags |= FAST_PATH_NO_REFLECT_REPEAT | FAST_PATH_NO_PAD_REPEAT | 
FAST_PATH_NO_NONE_REPEAT;
+   flags |=
+   FAST_PATH_NO_REFLECT_REPEAT |
+   FAST_PATH_NO_PAD_REPEAT |
+   FAST_PATH_NO_NONE_REPEAT|
+   FAST_PATH_COVERS_CLIP;
break;
 }
 
@@ -385,6 +400,8 @@ compute_image_info (pixman_image_t *image)
 
if (image->solid.color.alpha == 0x)
flags |= FAST_PATH_IS_OPAQUE;
+
+   flags |= FAST_PATH_COVERS_CLIP;
break;
 
 case BITS:
diff --git a/pixman/pixman.c b/pixman/pixman.c
index ea048cc..bf7de7d 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -708,22 +708,9 @@ analyze_extent (pixman_image_t *image, int x, int y,
 pixman_fixed_t width, height;
 pixman_box32_t ex;
 
-*flags |= FAST_PATH_COVERS_CLIP;
 if (!image)
return TRUE;
 
-transform = image->common.transform;
-if (image->common.type == BITS)
-{
-   if (image->common.repeat == PIXMAN_REPEAT_NONE &&
-   (x > extents->x1 || y > extents->y1 ||
-x + image->bits.width < extents->x2 ||
-y + image->bits.height < extents->y2))
-   {
-   (*flags) &= ~FAST_PATH_COVERS_CLIP;
-   }
-}
-
 /* Some compositing functions walk one step
  * outside the destination rectangle, so we
  * check here that the expanded-by-one source
@@ -779,14 +766,16 @@ analyze_extent (pixman_image_t *image, int x, int y,
 }
 
 /* Check that the extents expanded by one don't overflow. This ensures that
- * compositing functions can simply walk the source space using 16.16 
variables
- * without worrying about overflow.
+ * compositing functions can simply walk the source space using 16.16
+ * variables without worrying about overflow.
  */
 ex.x1 = extents->x1 - 1;
 ex.y1 = extents->y1 - 1;
 ex.x2 = extents->x2 + 1;
 ex.y2 = extents->y2 + 1;
 
+transform = image->common.transform;
+
 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, 
height))
return FALSE;
 
@@ -799,7 +788,7 @@ analyze_extent (pixman_image_t *image, int x, int y,
if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, 
height))
{
if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 
<= image->bits.height)
-   *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
+   *flags |= (FAST_PATH_SAMPLES_COVER_CLIP | 
FAST_PATH_COVERS_CLIP);
}
 }
 
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 3/3] analyze_extents: Fast path for non-transformed BITS images

2010-09-16 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Profiling various cairo traces showed that we were spending a lot of
time in analyze_extents and compute_sample_extents(). This was
especially bad for glyphs where all this computation was completely
unnecessary.

This patch adds a fast path for the case of non-transformed BITS
images. The result is approximately a 6% improvement on the
firefox-talos-gfx benchmark:

Before:

[ # ]  backend test   min(s) median(s) stddev. count
[  0]imagefirefox-talos-gfx   13.797   13.848   0.20%6/6

After:

[ # ]  backend test   min(s) median(s) stddev. count
[  0]imagefirefox-talos-gfx   12.946   13.018   0.39%6/6
---
 pixman/pixman.c |   39 ---
 1 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index bf7de7d..26fe823 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -724,8 +724,21 @@ analyze_extent (pixman_image_t *image, int x, int y,
return FALSE;
 }
 
+transform = image->common.transform;
 if (image->common.type == BITS)
 {
+#define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
+   
+   if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
+   extents->x1 - x >= 0 &&
+   extents->y1 - y >= 0 &&
+   extents->x2 - x <= image->bits.width &&
+   extents->y2 - y <= image->bits.height)
+   {
+   *flags |= (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_COVERS_CLIP);
+   return TRUE;
+   }
+
switch (image->common.filter)
{
case PIXMAN_FILTER_CONVOLUTION:
@@ -756,6 +769,17 @@ analyze_extent (pixman_image_t *image, int x, int y,
default:
return FALSE;
}
+
+   /* Check whether the non-expanded, transformed extent is entirely within
+* the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
+*/
+   ex = *extents;
+   if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, 
height) &&
+   ex.x1 >= 0 && ex.y1 >= 0 &&
+   ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
+   {
+   *flags |= (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_COVERS_CLIP);
+   }
 }
 else
 {
@@ -774,24 +798,9 @@ analyze_extent (pixman_image_t *image, int x, int y,
 ex.x2 = extents->x2 + 1;
 ex.y2 = extents->y2 + 1;
 
-transform = image->common.transform;
-
 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, 
height))
return FALSE;
 
-if (image->type == BITS)
-{
-   /* Check whether the non-expanded, transformed extent is entirely within
-* the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
-*/
-   ex = *extents;
-   if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, 
height))
-   {
-   if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 
<= image->bits.height)
-   *flags |= (FAST_PATH_SAMPLES_COVER_CLIP | 
FAST_PATH_COVERS_CLIP);
-   }
-}
-
 return TRUE;
 }
 
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] Fast paths for bilinear transformation

2010-09-16 Thread Søren Sandmann
Hi,

The following patches add some fast paths for bilinear transformation
for the most important formats: a8, r5g6b5, x8r8g8b8, and a8r8g8b8.

The code is actually commented out in the patches. It is enabled in a
bunch of trivial commits here:

  http://cgit.freedesktop.org/~sandmann/pixman/log/?h=more-scalers

that I didn't want to spam the list with.


Soren


___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 01/19] test: Add affine-test

2010-09-16 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This test tests compositing with various affine transformations. It is
almost identical to scaling-test, except that it also applies a random
rotation in addition to the random scaling and translation.
---
 test/Makefile.am|4 +
 test/affine-test.c  |  255 +++
 test/scaling-test.c |2 +-
 3 files changed, 260 insertions(+), 1 deletions(-)
 create mode 100644 test/affine-test.c

diff --git a/test/Makefile.am b/test/Makefile.am
index f3b2b58..ff851c9 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -18,6 +18,7 @@ TESTPROGRAMS =\
alphamap\
blitters-test   \
scaling-test\
+   affine-test \
composite
 
 a1_trap_test_LDADD = $(TEST_LDADD)
@@ -39,6 +40,9 @@ blitters_test_SOURCES = blitters-test.c utils.c utils.h
 scaling_test_LDADD = $(TEST_LDADD)
 scaling_test_SOURCES = scaling-test.c utils.c utils.h
 
+affine_test_LDADD = $(TEST_LDADD)
+affine_test_SOURCES = affine-test.c utils.c utils.h
+
 alphamap_LDADD = $(TEST_LDADD)
 alphamap_SOURCES = alphamap.c utils.c utils.h
 
diff --git a/test/affine-test.c b/test/affine-test.c
new file mode 100644
index 000..5c6031c
--- /dev/null
+++ b/test/affine-test.c
@@ -0,0 +1,255 @@
+/*
+ * Test program, which can detect some problems with affine transformations
+ * in pixman. Testing is done by running lots of random SRC and OVER
+ * compositing operations a8r8g8b8, x8a8r8g8b8 and r5g6b5 color formats
+ * with random scaled, rotated and translated transforms.
+ *
+ * Script 'fuzzer-find-diff.pl' can be used to narrow down the problem in
+ * the case of test failure.
+ */
+#include 
+#include 
+#include 
+#include "utils.h"
+
+#define MAX_SRC_WIDTH  10
+#define MAX_SRC_HEIGHT 10
+#define MAX_DST_WIDTH  10
+#define MAX_DST_HEIGHT 10
+#define MAX_STRIDE 4
+
+/*
+ * Composite operation with pseudorandom images
+ */
+static uint32_t
+test_composite (int  testnum,
+   int  verbose)
+{
+inti;
+pixman_image_t *   src_img;
+pixman_image_t *   dst_img;
+pixman_transform_t transform;
+pixman_region16_t  clip;
+intsrc_width, src_height;
+intdst_width, dst_height;
+intsrc_stride, dst_stride;
+intsrc_x, src_y;
+intdst_x, dst_y;
+intsrc_bpp;
+intdst_bpp;
+intw, h;
+intscale_x = 32768, scale_y = 32768;
+intop;
+intrepeat = 0;
+intsrc_fmt, dst_fmt;
+uint32_t * srcbuf;
+uint32_t * dstbuf;
+uint32_t   crc32;
+FLOAT_REGS_CORRUPTION_DETECTOR_START();
+
+lcg_srand (testnum);
+
+src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
+dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
+op = (lcg_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
+
+src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
+src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
+dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
+dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
+src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
+dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
+
+if (src_stride & 3)
+   src_stride += 2;
+
+if (dst_stride & 3)
+   dst_stride += 2;
+
+src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
+src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
+dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
+dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
+w = lcg_rand_n (dst_width * 3 / 2 - dst_x);
+h = lcg_rand_n (dst_height * 3 / 2 - dst_y);
+
+srcbuf = (uint32_t *)malloc (src_stride * src_height);
+dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
+
+for (i = 0; i < src_stride * src_height; i++)
+   *((uint8_t *)srcbuf + i) = lcg_rand_n (256);
+
+for (i = 0; i < dst_stride * dst_height; i++)
+   *((uint8_t *)dstbuf + i) = lcg_rand_n (256);
+
+src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ?
+  PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : 
PIXMAN_r5g6b5;
+
+dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ?
+  PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : 
PIXMAN_r5g6b5;
+
+src_img = pixman_image_create_bits (
+src_fmt, src_width, src_height, srcbuf, src_stride);
+
+dst_img = pixman_image_create_bits (
+dst_fmt, dst_width, dst_height, dstbuf, dst_stride);
+
+image_endian_swap (src_img, src_bpp * 8);
+image_endian_swap (dst_img, dst_bpp * 8);
+
+pixman_transform_init_identity (&transform);
+
+if (lcg_rand_n (8) > 0)
+{
+   scale_x = 32768 + lcg_rand_n (65536);
+   scale_y = 32768 + lcg_rand_n (65536);
+

[Pixman] [PATCH 02/19] Add nearest scaler for x888 on 8888

2010-09-16 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

---
 pixman/pixman-fast-path.c |   10 +-
 pixman/pixman-private.h   |5 -
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 6dee472..64e69e5 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1430,9 +1430,10 @@ repeat (pixman_repeat_t repeat, int *c, int size)
  */
 
 #define GET__ALPHA(s) ((s) >> 24)
+#define GET_x888_ALPHA(s) (0xff)
  /* This is not actually used since we don't have an OVER with
 565 source, but it is needed to build. */
-#define GET_0565_ALPHA(s) 0xff
+#define GET_0565_ALPHA(s) (0xff)
 
 #define FAST_NEAREST(scale_func_name, SRC_FORMAT, DST_FORMAT,  
\
 src_type_t, dst_type_t, OP, repeat_mode)   
\
@@ -1623,6 +1624,10 @@ FAST_NEAREST (__none, , , uint32_t, 
uint32_t, SRC, NONE);
 FAST_NEAREST (__normal, , , uint32_t, uint32_t, SRC, NORMAL);
 FAST_NEAREST (__none, , , uint32_t, uint32_t, OVER, NONE);
 FAST_NEAREST (__normal, , , uint32_t, uint32_t, OVER, NORMAL);
+
+FAST_NEAREST (x888__none, x888, , uint32_t, uint32_t, SRC, NONE);
+FAST_NEAREST (x888__normal, x888, , uint32_t, uint32_t, SRC, NORMAL);
+
 FAST_NEAREST (_565_none, , 0565, uint32_t, uint16_t, SRC, NONE);
 FAST_NEAREST (_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL);
 FAST_NEAREST (565_565_none, 0565, 0565, uint16_t, uint16_t, SRC, NONE);
@@ -1888,6 +1893,9 @@ static const pixman_fast_path_t c_fast_paths[] =
 SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, _),
 SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, _),
 
+SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, a8r8g8b8, x888_),
+SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, a8b8g8r8, x888_),
+
 SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, _),
 SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, _),
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index b05a68d..ef87678 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -707,7 +707,7 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
 
 #define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : 
(v)))
 
-/* Conversion between  and 0565 */
+/* Various conversion macros */
 
 #define CONVERT__TO_0565(s)
\
 s) >> 3) & 0x001f) |   \
@@ -721,6 +721,9 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
 
 #define CONVERT_0565_TO_(s) (CONVERT_0565_TO_0888(s) | 0xff00)
 
+#define CONVERT_x888_TO_(s)
\
+((s) | 0xff00)
+
 /* Trivial versions that are useful in macros */
 #define CONVERT__TO_(s) (s)
 #define CONVERT_0565_TO_0565(s) (s)
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 03/19] Use a macro to generate some {a, x}8r8g8b8, a8, and r5g6b5 bilinear fetchers.

2010-09-16 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

There are versions for all combinations of x8r8g8b8/a8r8g8b8 and
pad/repeat/none/normal repeat modes. The bulk of each scaler is an
inline function that takes a format and a repeat mode as parameters.

The new scalers are all commented out, but the next commits will
enable them one at a time to facilitate bisecting.
---
 pixman/pixman-bits-image.c |  257 +++-
 test/composite-test.c  |5 +-
 2 files changed, 255 insertions(+), 7 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index a32ebcc..98dc28a 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -637,7 +637,7 @@ bits_image_fetch_affine_no_alpha (pixman_image_t * image,
buffer[i] = bits_image_fetch_pixel_filtered (
&image->bits, x, y, fetch_pixel_no_alpha);
}
-   
+
x += ux;
y += uy;
 }
@@ -749,6 +749,222 @@ bits_image_fetch_general (pixman_image_t * image,
 }
 }
 
+static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
+
+static force_inline void
+bits_image_fetch_bilinear_affine (pixman_image_t * image,
+ int  offset,
+ int  line,
+ int  width,
+ uint32_t *   buffer,
+ const uint32_t * mask,
+
+ convert_pixel_t   convert_pixel,
+ pixman_format_code_t  format,
+ pixman_repeat_t   repeat_mode)
+{
+pixman_fixed_t x, y;
+pixman_fixed_t ux, uy;
+pixman_vector_t v;
+bits_image_t *bits = &image->bits;
+int i;
+
+/* reference point is the center of the pixel */
+v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
+v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
+v.vector[2] = pixman_fixed_1;
+
+if (!pixman_transform_point_3d (image->common.transform, &v))
+   return;
+
+ux = image->common.transform->matrix[0][0];
+uy = image->common.transform->matrix[1][0];
+
+x = v.vector[0];
+y = v.vector[1];
+
+for (i = 0; i < width; ++i)
+{
+   int x1, y1, x2, y2;
+   uint32_t tl, tr, bl, br;
+   int32_t distx, disty;
+   int width = image->bits.width;
+   int height = image->bits.height;
+   const uint8_t *row1;
+   const uint8_t *row2;
+
+   if (mask && !mask[i])
+   goto next;
+
+   x1 = x - pixman_fixed_1 / 2;
+   y1 = y - pixman_fixed_1 / 2;
+
+   distx = (x1 >> 8) & 0xff;
+   disty = (y1 >> 8) & 0xff;
+
+   y1 = pixman_fixed_to_int (y1);
+   y2 = y1 + 1;
+   x1 = pixman_fixed_to_int (x1);
+   x2 = x1 + 1;
+
+   if (repeat_mode != PIXMAN_REPEAT_NONE)
+   {
+   uint32_t mask;
+
+   mask = PIXMAN_FORMAT_A (format)? 0 : 0xff00;
+
+   repeat (repeat_mode, width, &x1);
+   repeat (repeat_mode, height, &y1);
+   repeat (repeat_mode, width, &x2);
+   repeat (repeat_mode, height, &y2);
+
+   row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
+   row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
+
+   tl = convert_pixel (row1, x1) | mask;
+   tr = convert_pixel (row1, x2) | mask;
+   bl = convert_pixel (row2, x1) | mask;
+   br = convert_pixel (row2, x2) | mask;
+   }
+   else
+   {
+   uint32_t mask1, mask2;
+   int bpp;
+
+   /* Note: PIXMAN_FORMAT_BPP() returns an unsigned value,
+* which means if you use it in expressions, those
+* expressions become unsigned themselves. Since
+* the variables below can be negative in some cases,
+* that will lead to crashes on 64 bit architectures.
+*
+* So this line makes sure bpp is signed
+*/
+   bpp = PIXMAN_FORMAT_BPP (format);
+
+   if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0)
+   {
+   buffer[i] = 0;
+   goto next;
+   }
+
+   if (y2 == 0)
+   {
+   row1 = zero;
+   mask1 = 0;
+   }
+   else
+   {
+   row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
+   row1 += bpp / 8 * x1;
+
+   mask1 = PIXMAN_FORMAT_A (format)? 0 : 0xff00;
+   }
+
+   if (y1 == height - 1)
+   {
+   row2 = zero;
+   mask2 = 0;
+   }
+   else
+   {
+   row2 = (uint8_t *)bits->bits + bits->ro

[Pixman] [PATCH] Rename all the fast paths with _8000 in their names to _8

2010-09-22 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This inconsistent naming somehow survived the refactoring from a while
back.
---
 pixman/pixman-arm-neon-asm.S |   22 +++---
 pixman/pixman-arm-neon.c |4 ++--
 pixman/pixman-arm-simd-asm.S |2 +-
 pixman/pixman-arm-simd.c |   16 
 pixman/pixman-fast-path.c|   28 ++--
 pixman/pixman-mmx.c  |   28 ++--
 pixman/pixman-sse2.c |   30 +++---
 test/lowlevel-blt-bench.c|6 +++---
 8 files changed, 68 insertions(+), 68 deletions(-)

diff --git a/pixman/pixman-arm-neon-asm.S b/pixman/pixman-arm-neon-asm.S
index 9f6568f..b854ab3 100644
--- a/pixman/pixman-arm-neon-asm.S
+++ b/pixman/pixman-arm-neon-asm.S
@@ -495,15 +495,15 @@ generate_composite_function \
 
 
/**/
 
-.macro pixman_composite_add_8000_8000_process_pixblock_head
+.macro pixman_composite_add_8_8_process_pixblock_head
 vqadd.u8q14, q0, q2
 vqadd.u8q15, q1, q3
 .endm
 
-.macro pixman_composite_add_8000_8000_process_pixblock_tail
+.macro pixman_composite_add_8_8_process_pixblock_tail
 .endm
 
-.macro pixman_composite_add_8000_8000_process_pixblock_tail_head
+.macro pixman_composite_add_8_8_process_pixblock_tail_head
 vld1.8  {d0, d1, d2, d3}, [SRC]!
 PF add PF_X, PF_X, #32
 PF tst PF_CTL, #0xF
@@ -523,15 +523,15 @@ generate_composite_function \
 .endm
 
 generate_composite_function \
-pixman_composite_add_8000_8000_asm_neon, 8, 0, 8, \
+pixman_composite_add_8_8_asm_neon, 8, 0, 8, \
 FLAG_DST_READWRITE, \
 32, /* number of pixels, processed in a single block */ \
 10, /* prefetch distance */ \
 default_init, \
 default_cleanup, \
-pixman_composite_add_8000_8000_process_pixblock_head, \
-pixman_composite_add_8000_8000_process_pixblock_tail, \
-pixman_composite_add_8000_8000_process_pixblock_tail_head
+pixman_composite_add_8_8_process_pixblock_head, \
+pixman_composite_add_8_8_process_pixblock_tail, \
+pixman_composite_add_8_8_process_pixblock_tail_head
 
 
/**/
 
@@ -561,8 +561,8 @@ generate_composite_function \
 10, /* prefetch distance */ \
 default_init, \
 default_cleanup, \
-pixman_composite_add_8000_8000_process_pixblock_head, \
-pixman_composite_add_8000_8000_process_pixblock_tail, \
+pixman_composite_add_8_8_process_pixblock_head, \
+pixman_composite_add_8_8_process_pixblock_tail, \
 pixman_composite_add___process_pixblock_tail_head
 
 generate_composite_function_single_scanline \
@@ -571,8 +571,8 @@ generate_composite_function_single_scanline \
 8, /* number of pixels, processed in a single block */ \
 default_init, \
 default_cleanup, \
-pixman_composite_add_8000_8000_process_pixblock_head, \
-pixman_composite_add_8000_8000_process_pixblock_tail, \
+pixman_composite_add_8_8_process_pixblock_head, \
+pixman_composite_add_8_8_process_pixblock_tail, \
 pixman_composite_add___process_pixblock_tail_head
 
 
/**/
diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index ece6054..cdaa29a 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -52,7 +52,7 @@ PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_0565_rev,
uint8_t, 3, uint16_t, 1)
 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_pixbuf_,
uint32_t, 1, uint32_t, 1)
-PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8000_8000,
+PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8_8,
uint8_t, 1, uint8_t, 1)
 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add__,
uint32_t, 1, uint32_t, 1)
@@ -257,7 +257,7 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
 PIXMAN_STD_FAST_PATH (ADD,  solid,a8,   a8,   
neon_composite_add_n_8_8),
 PIXMAN_STD_FAST_PATH (ADD,  a8,   a8,   a8,   
neon_composite_add_8_8_8),
 PIXMAN_STD_FAST_PATH (ADD,  a8r8g8b8, a8r8g8b8, a8r8g8b8, 
neon_composite_add___),
-PIXMAN_STD_FAST_PATH (ADD,  a8,   null, a8,   
neon_composite_add_8000_8000),
+PIXMAN_STD_FAST_PATH (ADD,  a8,   null, a8,   
neon_composite_add_8_8),
 PIXMAN_STD_FAST_PATH (ADD,  a8r8g8b8, null, a8r8g8b8, 
neon_composite_add__),
 PIXMAN_STD_FAST_PATH (ADD,  a8b8g8r8, null, a8b8g8r8, 
neon_composite_add__),
 PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, 
neon_composite_over_reverse_n_),
diff --git a/pixman/pixman-arm-simd-asm.S b/pixman/pixman-arm-simd-asm.S
index 1a1a0d6..a3d2d40 100644
--- a

[Pixman] [PATCH 1/2] Fix bug in FAST_PATH_STD_FAST_PATH

2010-09-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The standard fast paths deal with two kinds of images: solids and
bits. These two image types require different flags, but
PIXMAN_STD_FAST_PATH uses the same ones for both.

This patch makes it so that solid images just get the standard flags,
while bits images must be untransformed, and the destination clip
contained within the sample grid.

This means that old FAST_PATH_COVERS_CLIP flag is now not used
anymore, so it can be deleted.
---
 pixman/pixman-image.c   |   11 ++--
 pixman/pixman-private.h |   55 +-
 pixman/pixman.c |4 +-
 3 files changed, 30 insertions(+), 40 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 8397f6a..9802d8c 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -363,24 +363,21 @@ compute_image_info (pixman_image_t *image)
flags |=
FAST_PATH_NO_PAD_REPEAT |
FAST_PATH_NO_NONE_REPEAT|
-   FAST_PATH_NO_NORMAL_REPEAT  |
-   FAST_PATH_COVERS_CLIP;
+   FAST_PATH_NO_NORMAL_REPEAT;
break;
 
 case PIXMAN_REPEAT_PAD:
flags |=
FAST_PATH_NO_REFLECT_REPEAT |
FAST_PATH_NO_NONE_REPEAT|
-   FAST_PATH_NO_NORMAL_REPEAT  |
-   FAST_PATH_COVERS_CLIP;
+   FAST_PATH_NO_NORMAL_REPEAT;
break;
 
 default:
flags |=
FAST_PATH_NO_REFLECT_REPEAT |
FAST_PATH_NO_PAD_REPEAT |
-   FAST_PATH_NO_NONE_REPEAT|
-   FAST_PATH_COVERS_CLIP;
+   FAST_PATH_NO_NONE_REPEAT;
break;
 }
 
@@ -400,8 +397,6 @@ compute_image_info (pixman_image_t *image)
 
if (image->solid.color.alpha == 0x)
flags |= FAST_PATH_IS_OPAQUE;
-
-   flags |= FAST_PATH_COVERS_CLIP;
break;
 
 case BITS:
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d85868f..59d9c5d 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -554,9 +554,9 @@ _pixman_choose_implementation (void);
 #define FAST_PATH_NO_PAD_REPEAT(1 <<  3)
 #define FAST_PATH_NO_REFLECT_REPEAT(1 <<  4)
 #define FAST_PATH_NO_ACCESSORS (1 <<  5)
-#define FAST_PATH_NARROW_FORMAT(1 <<  6)
-#define FAST_PATH_COVERS_CLIP  (1 <<  7)
+#define FAST_PATH_NARROW_FORMAT(1 <<  6)
 #define FAST_PATH_COMPONENT_ALPHA  (1 <<  8)
+#define FAST_PATH_SAMPLES_OPAQUE   (1 <<  7)
 #define FAST_PATH_UNIFIED_ALPHA(1 <<  9)
 #define FAST_PATH_SCALE_TRANSFORM  (1 << 10)
 #define FAST_PATH_NEAREST_FILTER   (1 << 11)
@@ -571,7 +571,6 @@ _pixman_choose_implementation (void);
 #define FAST_PATH_BILINEAR_FILTER  (1 << 20)
 #define FAST_PATH_NO_NORMAL_REPEAT (1 << 21)
 #define FAST_PATH_HAS_TRANSFORM(1 << 22)
-#define FAST_PATH_SAMPLES_OPAQUE   (1 << 23)
 
 #define FAST_PATH_PAD_REPEAT   \
 (FAST_PATH_NO_NONE_REPEAT  |   \
@@ -593,29 +592,25 @@ _pixman_choose_implementation (void);
  FAST_PATH_NO_NORMAL_REPEAT|   
\
  FAST_PATH_NO_PAD_REPEAT)
 
-#define _FAST_PATH_STANDARD_FLAGS  \
-(FAST_PATH_ID_TRANSFORM|   \
- FAST_PATH_NO_ALPHA_MAP|   \
- FAST_PATH_NO_CONVOLUTION_FILTER   |   \
- FAST_PATH_NO_PAD_REPEAT   |   \
- FAST_PATH_NO_REFLECT_REPEAT   |   \
+#define FAST_PATH_STANDARD_FLAGS   \
+(FAST_PATH_NO_CONVOLUTION_FILTER   |   \
  FAST_PATH_NO_ACCESSORS|   \
- FAST_PATH_NARROW_FORMAT   |   \
- FAST_PATH_COVERS_CLIP)
-
-#define FAST_PATH_STD_SRC_FLAGS
\
-_FAST_PATH_STANDARD_FLAGS
-#define FAST_PATH_STD_MASK_U_FLAGS \
-(_FAST_PATH_STANDARD_FLAGS |   \
- FAST_PATH_UNIFIED_ALPHA)
-#define FAST_PATH_STD_MASK_CA_FLAGS\
-(_FAST_PATH_STANDARD_FLAGS |   \
- FAST_PATH_COMPONENT_ALPHA)
+ FAST_PATH_NO_ALPHA_MAP|   \
+ FAST_PATH_NARROW_FORMAT)
+
 #define FAST_PATH_STD_DEST_FLAGS   \
 (FAS

[Pixman] [PATCH 2/2] Delete simple repeat code

2010-09-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This was supposedly an optimization, but it has pathological cases
where it definitely isn't. For example it has terrible memory access
patterns when called with a 1 x n image. With small images in general,
it will do lots and lots of modulus operations.

Since no one has ever measure whether it actually is an improvement,
and since it is doing the repeating at the wrong the stage in the
pipeline, just delete it.
---
 pixman/pixman-image.c   |6 --
 pixman/pixman-private.h |3 +-
 pixman/pixman.c |  148 ++
 3 files changed, 21 insertions(+), 136 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 9802d8c..7a9c423 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -409,12 +409,6 @@ compute_image_info (pixman_image_t *image)
else
{
code = image->bits.format;
-
-   if (!image->common.transform &&
-   image->common.repeat == PIXMAN_REPEAT_NORMAL)
-   {
-   flags |= FAST_PATH_SIMPLE_REPEAT;
-   }
}
 
if (!PIXMAN_FORMAT_A (image->bits.format)   
&&
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 59d9c5d..3979f60 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -560,7 +560,7 @@ _pixman_choose_implementation (void);
 #define FAST_PATH_UNIFIED_ALPHA(1 <<  9)
 #define FAST_PATH_SCALE_TRANSFORM  (1 << 10)
 #define FAST_PATH_NEAREST_FILTER   (1 << 11)
-#define FAST_PATH_SIMPLE_REPEAT(1 << 12)
+#define FAST_PATH_HAS_TRANSFORM(1 << 12)
 #define FAST_PATH_IS_OPAQUE(1 << 13)
 #define FAST_PATH_NEEDS_WORKAROUND (1 << 14)
 #define FAST_PATH_NO_NONE_REPEAT   (1 << 15)
@@ -570,7 +570,6 @@ _pixman_choose_implementation (void);
 #define FAST_PATH_Y_UNIT_ZERO  (1 << 19)
 #define FAST_PATH_BILINEAR_FILTER  (1 << 20)
 #define FAST_PATH_NO_NORMAL_REPEAT (1 << 21)
-#define FAST_PATH_HAS_TRANSFORM(1 << 22)
 
 #define FAST_PATH_PAD_REPEAT   \
 (FAST_PATH_NO_NONE_REPEAT  |   \
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 15e7fbf..3a62b2d 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -377,126 +377,6 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 return TRUE;
 }
 
-static void
-walk_region_internal (pixman_implementation_t *imp,
-  pixman_op_t  op,
-  pixman_image_t * src_image,
-  pixman_image_t * mask_image,
-  pixman_image_t * dst_image,
-  int32_t  src_x,
-  int32_t  src_y,
-  int32_t  mask_x,
-  int32_t  mask_y,
-  int32_t  dest_x,
-  int32_t  dest_y,
-  int32_t  width,
-  int32_t  height,
-  pixman_bool_tsrc_repeat,
-  pixman_bool_tmask_repeat,
-  pixman_region32_t *  region,
-  pixman_composite_func_t  composite_rect)
-{
-int w, h, w_this, h_this;
-int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
-int src_dy = src_y - dest_y;
-int src_dx = src_x - dest_x;
-int mask_dy = mask_y - dest_y;
-int mask_dx = mask_x - dest_x;
-const pixman_box32_t *pbox;
-int n;
-
-pbox = pixman_region32_rectangles (region, &n);
-
-/* Fast path for non-repeating sources */
-if (!src_repeat && !mask_repeat)
-{
-   while (n--)
-   {
-   (*composite_rect) (imp, op,
-  src_image, mask_image, dst_image,
-  pbox->x1 + src_dx,
-  pbox->y1 + src_dy,
-  pbox->x1 + mask_dx,
-  pbox->y1 + mask_dy,
-  pbox->x1,
-  pbox->y1,
-  pbox->x2 - pbox->x1,
-  pbox->y2 - pbox->y1);
-   
-   pbox++;
-   }
-
-   return;
-}
-
-while (n--)
-{
-   h = pbox->y2 - pbox->y1;
-   y_src = pbox->y1 + src_dy;
-   y_msk = pbox->y1 + mask_dy;
-   y_dst = pbox->y1;
-
-   while (h)
-   {
-   h_this = h;
-   w

[Pixman] [PATCH] Remove broken optimizations in combine_disjoint_over_u()

2010-10-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The first broken optimization is that it checks "a != 0x00" where it
should check "s != 0x00". The other is that it skips the computation
when alpha is 0xff. That is wrong because in the formula:

 min (1, (1 - Aa)/Ab)

the render specification states that if Ab is 0, the quotient is
defined to positive infinity. That is the case even if (1 - Aa) is 0.
---
 pixman/pixman-combine.c.template |   14 +-
 test/blitters-test.c |2 +-
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template
index c129980..0d3b95d 100644
--- a/pixman/pixman-combine.c.template
+++ b/pixman/pixman-combine.c.template
@@ -1296,17 +1296,13 @@ combine_disjoint_over_u (pixman_implementation_t *imp,
comp4_t s = combine_mask (src, mask, i);
comp2_t a = s >> A_SHIFT;
 
-   if (a != 0x00)
+   if (s != 0x00)
{
-   if (a != MASK)
-   {
-   comp4_t d = *(dest + i);
-   a = combine_disjoint_out_part (d >> A_SHIFT, a);
-   UNcx4_MUL_UNc_ADD_UNcx4 (d, a, s);
-   s = d;
-   }
+   comp4_t d = *(dest + i);
+   a = combine_disjoint_out_part (d >> A_SHIFT, a);
+   UNcx4_MUL_UNc_ADD_UNcx4 (d, a, s);
 
-   *(dest + i) = s;
+   *(dest + i) = d;
}
 }
 }
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 7ba80eb..77a26dd 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -465,6 +465,6 @@ main (int argc, const char *argv[])
 }
 
 return fuzzer_test_main("blitters", 200,
-   0x217CF14A,
+   0x1DB8BDF8,
test_composite, argc, argv);
 }
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Add no-op combiners for DST and the CA versions of the HSL operators.

2010-10-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

We already exit early for DST, but for the HSL operators with
component alpha, we crash at the moment. Fix that by adding a dummy
combine_dst() function.
---
 pixman/pixman-combine.c.template |   31 +--
 1 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template
index 0d3b95d..56dfb43 100644
--- a/pixman/pixman-combine.c.template
+++ b/pixman/pixman-combine.c.template
@@ -133,6 +133,17 @@ combine_clear (pixman_implementation_t *imp,
 }
 
 static void
+combine_dst (pixman_implementation_t *imp,
+pixman_op_t  op,
+comp4_t *dest,
+const comp4_t *  src,
+const comp4_t *  mask,
+int  width)
+{
+return;
+}
+
+static void
 combine_src_u (pixman_implementation_t *imp,
pixman_op_t  op,
comp4_t *dest,
@@ -2310,7 +2321,7 @@ _pixman_setup_combiner_functions_width 
(pixman_implementation_t *imp)
 /* Unified alpha */
 imp->combine_width[PIXMAN_OP_CLEAR] = combine_clear;
 imp->combine_width[PIXMAN_OP_SRC] = combine_src_u;
-/* dest */
+imp->combine_width[PIXMAN_OP_DST] = combine_dst;
 imp->combine_width[PIXMAN_OP_OVER] = combine_over_u;
 imp->combine_width[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u;
 imp->combine_width[PIXMAN_OP_IN] = combine_in_u;
@@ -2326,7 +2337,7 @@ _pixman_setup_combiner_functions_width 
(pixman_implementation_t *imp)
 /* Disjoint, unified */
 imp->combine_width[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear;
 imp->combine_width[PIXMAN_OP_DISJOINT_SRC] = combine_src_u;
-/* dest */
+imp->combine_width[PIXMAN_OP_DISJOINT_DST] = combine_dst;
 imp->combine_width[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u;
 imp->combine_width[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u;
 imp->combine_width[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u;
@@ -2340,7 +2351,7 @@ _pixman_setup_combiner_functions_width 
(pixman_implementation_t *imp)
 /* Conjoint, unified */
 imp->combine_width[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear;
 imp->combine_width[PIXMAN_OP_CONJOINT_SRC] = combine_src_u;
-/* dest */
+imp->combine_width[PIXMAN_OP_CONJOINT_DST] = combine_dst;
 imp->combine_width[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u;
 imp->combine_width[PIXMAN_OP_CONJOINT_OVER_REVERSE] = 
combine_conjoint_over_reverse_u;
 imp->combine_width[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u;
@@ -2386,7 +2397,7 @@ _pixman_setup_combiner_functions_width 
(pixman_implementation_t *imp)
 /* Disjoint CA */
 imp->combine_width_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca;
 imp->combine_width_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca;
-/* dest */
+imp->combine_width_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst;
 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca;
 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = 
combine_saturate_ca;
 imp->combine_width_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca;
@@ -2400,7 +2411,7 @@ _pixman_setup_combiner_functions_width 
(pixman_implementation_t *imp)
 /* Conjoint CA */
 imp->combine_width_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca;
 imp->combine_width_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca;
-/* dest */
+imp->combine_width_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst;
 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca;
 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = 
combine_conjoint_over_reverse_ca;
 imp->combine_width_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca;
@@ -2423,10 +2434,10 @@ _pixman_setup_combiner_functions_width 
(pixman_implementation_t *imp)
 imp->combine_width_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca;
 imp->combine_width_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca;
 
-/* It is not clear that these make sense, so leave them out for now */
-imp->combine_width_ca[PIXMAN_OP_HSL_HUE] = NULL;
-imp->combine_width_ca[PIXMAN_OP_HSL_SATURATION] = NULL;
-imp->combine_width_ca[PIXMAN_OP_HSL_COLOR] = NULL;
-imp->combine_width_ca[PIXMAN_OP_HSL_LUMINOSITY] = NULL;
+/* It is not clear that these make sense, so make them noops for now */
+imp->combine_width_ca[PIXMAN_OP_HSL_HUE] = combine_dst;
+imp->combine_width_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst;
+imp->combine_width_ca[PIXMAN_OP_HSL_COLOR] = combine_dst;
+imp->combine_width_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst;
 }
 
-- 
1.7.1.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Plug leak in the alphamap test.

2010-10-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The images are being created with non-NULL data, so we have to free it
outselves. This is important because the Cygwin tinderbox is running
out of memory and produces this:

mmap failed on 2 1507328
mmap failed on 4 1507328
mmap failed on 2 1507328
mmap failed on 4 1507328
mmap failed on 4 1507328
mmap failed on 4 1507328

http://tinderbox.x.org/builds/2010-10-05-0014/logs/pixman/#check
---
 test/alphamap.c |   14 +-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/test/alphamap.c b/test/alphamap.c
index 09de387..498fdab 100644
--- a/test/alphamap.c
+++ b/test/alphamap.c
@@ -45,15 +45,27 @@ format_name (pixman_format_code_t format)
 return "";
 }
 
+static void
+on_destroy (pixman_image_t *image, void *data)
+{
+uint32_t *bits = pixman_image_get_data (image);
+
+fence_free (bits);
+}
+
 static pixman_image_t *
 make_image (pixman_format_code_t format)
 {
 uint32_t *bits;
 uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
+pixman_image_t *image;
 
 bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
 
-return pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
+image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * 
bpp);
+
+if (image && bits)
+   pixman_image_set_destroy_function (image, on_destroy, NULL);
 }
 
 static pixman_image_t *
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Remove workaround for a bug in the 1.6 X server.

2010-10-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

There used to be a bug in the X server where it would rely on
out-of-bounds accesses when it was asked to composite with a
window as the source. It would create a pixman image pointing
to some bogus position in memory, but then set a clip region
to the position where the actual bits were.

Due to a bug in old versions of pixman, where it would not clip
against the image bounds when a clip region was set, this would
actually work. So when the pixman bug was fixed, a workaround was
added to allow certain out-of-bound accesses. This function disabled
those workarounds.

However, the 1.6 X server is so old now that we can remove this
workaround. This does mean that if you update pixman to 0.22 or later,
you will need to use a 1.7 X server or later.
---
 pixman/pixman-image.c   |   56 
 pixman/pixman-private.h |3 +-
 pixman/pixman.c |   75 
 pixman/pixman.h |   22 --
 test/Makefile.am|2 -
 test/window-test.c  |  173 ---
 6 files changed, 28 insertions(+), 303 deletions(-)
 delete mode 100644 test/window-test.c

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index fabcd63..aa988a8 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -238,54 +238,27 @@ _pixman_image_reset_clip_region (pixman_image_t *image)
 image->common.have_clip_region = FALSE;
 }
 
-static pixman_bool_t out_of_bounds_workaround = TRUE;
-
-/* Old X servers rely on out-of-bounds accesses when they are asked
- * to composite with a window as the source. They create a pixman image
- * pointing to some bogus position in memory, but then they set a clip
- * region to the position where the actual bits are.
+/* Executive Summary: This function is a no-op that only exists
+ * for historical reasons.
+ *
+ * There used to be a bug in the X server where it would rely on
+ * out-of-bounds accesses when it was asked to composite with a
+ * window as the source. It would create a pixman image pointing
+ * to some bogus position in memory, but then set a clip region
+ * to the position where the actual bits were. 
  *
  * Due to a bug in old versions of pixman, where it would not clip
  * against the image bounds when a clip region was set, this would
- * actually work. So by default we allow certain out-of-bound access
- * to happen unless explicitly disabled.
+ * actually work. So when the pixman bug was fixed, a workaround was
+ * added to allow certain out-of-bound accesses. This function disabled
+ * those workarounds.
  *
- * Fixed X servers should call this function to disable the workaround.
+ * Since 0.21.2 pixman doen't do these workaround anymore, so now this
+ * function is a no-op.
  */
 PIXMAN_EXPORT void
 pixman_disable_out_of_bounds_workaround (void)
 {
-out_of_bounds_workaround = FALSE;
-}
-
-static pixman_bool_t
-source_image_needs_out_of_bounds_workaround (bits_image_t *image)
-{
-if (image->common.clip_sources  &&
-image->common.repeat == PIXMAN_REPEAT_NONE  &&
-   image->common.have_clip_region  &&
-out_of_bounds_workaround)
-{
-   if (!image->common.client_clip)
-   {
-   /* There is no client clip, so if the clip region extends beyond the
-* drawable geometry, it must be because the X server generated the
-* bogus clip region.
-*/
-   const pixman_box32_t *extents =
-   pixman_region32_extents (&image->common.clip_region);
-
-   if (extents->x1 >= 0 && extents->x2 <= image->width &&
-   extents->y1 >= 0 && extents->y2 <= image->height)
-   {
-   return FALSE;
-   }
-   }
-
-   return TRUE;
-}
-
-return FALSE;
 }
 
 static void
@@ -420,9 +393,6 @@ compute_image_info (pixman_image_t *image)
flags |= FAST_PATH_IS_OPAQUE;
}
 
-   if (source_image_needs_out_of_bounds_workaround (&image->bits))
-   flags |= FAST_PATH_NEEDS_WORKAROUND;
-
if (image->bits.read_func || image->bits.write_func)
flags &= ~FAST_PATH_NO_ACCESSORS;
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index c43172b..497c3fb 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -561,14 +561,13 @@ _pixman_choose_implementation (void);
 #define FAST_PATH_NEAREST_FILTER   (1 << 11)
 #define FAST_PATH_HAS_TRANSFORM(1 << 12)
 #define FAST_PATH_IS_OPAQUE(1 << 13)
-#define FAST_PATH_NEEDS_WORKAROUND (1 << 14)
+#define FAST_PATH_NO_NORMAL_REPEAT (1 << 14)
 #define FAST_PATH_NO_NONE_REPEAT   (1 << 15)
 #define FAST_PATH_SAMPLES_COVER_CLIP   (1 << 16)
 #

[Pixman] [PATCH] [mmx] Mark some of the output variables as earlyclobber.

2010-10-30 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

GCC assumes that input variables in inline assembly are fully consumed
before any output variable is written. This means it may allocate the
variables in the same register unless the output variables are marked
as early-clobber.

From Jeremy Huddleston:

I noticed a problem building pixman with clang and reported it to
the clang developers.  They responded back with a comment about
the inline asm in pixman-mmx.c and suggested a fix:

"""
Incidentally, Jeremy, in the asm that reads
__asm__ (
"movq %7, %0\n"
"movq %7, %1\n"
"movq %7, %2\n"
"movq %7, %3\n"
"movq %7, %4\n"
"movq %7, %5\n"
"movq %7, %6\n"
: "=y" (v1), "=y" (v2), "=y" (v3),
  "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
: "y" (vfill));

all the output operands except the last one should be marked as
earlyclobber ("=&y"). This is working by accident with gcc.
"""

Cc: jerem...@apple.com
---
 pixman/pixman-mmx.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index e936c4c..34637a4 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -1921,8 +1921,8 @@ pixman_fill_mmx (uint32_t *bits,
 "movq  %7, %4\n"
 "movq  %7, %5\n"
 "movq  %7, %6\n"
-   : "=y" (v1), "=y" (v2), "=y" (v3),
- "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
+   : "=&y" (v1), "=&y" (v2), "=&y" (v3),
+ "=&y" (v4), "=&y" (v5), "=&y" (v6), "=y" (v7)
: "y" (vfill));
 #endif
 
-- 
1.7.3.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Delete the source_image_t struct.

2010-10-30 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

It serves no purpose anymore now that the source_class_t field is gone.
---
 pixman/pixman-conical-gradient.c |   17 -
 pixman/pixman-linear-gradient.c  |   30 ++
 pixman/pixman-private.h  |   11 ++-
 pixman/pixman-radial-gradient.c  |   19 +--
 4 files changed, 33 insertions(+), 44 deletions(-)

diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 897948b..a3685d1 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -58,8 +58,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
   uint32_t *  buffer,
   const uint32_t *mask)
 {
-source_image_t *source = (source_image_t *)image;
-gradient_t *gradient = (gradient_t *)source;
+gradient_t *gradient = (gradient_t *)image;
 conical_gradient_t *conical = (conical_gradient_t *)image;
 uint32_t   *end = buffer + width;
 pixman_gradient_walker_t walker;
@@ -71,9 +70,9 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
 double ry = y + 0.5;
 double rz = 1.;
 
-_pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
+_pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
 
-if (source->common.transform)
+if (image->common.transform)
 {
pixman_vector_t v;
 
@@ -82,19 +81,19 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
v.vector[2] = pixman_fixed_1;
 
-   if (!pixman_transform_point_3d (source->common.transform, &v))
+   if (!pixman_transform_point_3d (image->common.transform, &v))
return;
 
-   cx = source->common.transform->matrix[0][0] / 65536.;
-   cy = source->common.transform->matrix[1][0] / 65536.;
-   cz = source->common.transform->matrix[2][0] / 65536.;
+   cx = image->common.transform->matrix[0][0] / 65536.;
+   cy = image->common.transform->matrix[1][0] / 65536.;
+   cz = image->common.transform->matrix[2][0] / 65536.;
 
rx = v.vector[0] / 65536.;
ry = v.vector[1] / 65536.;
rz = v.vector[2] / 65536.;
 
affine =
-   source->common.transform->matrix[2][0] == 0 &&
+   image->common.transform->matrix[2][0] == 0 &&
v.vector[2] == pixman_fixed_1;
 }
 
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index b048e7b..1547882 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -38,7 +38,6 @@ linear_gradient_classify (pixman_image_t *image,
   int width,
   int height)
 {
-source_image_t *source = (source_image_t *)image;
 linear_gradient_t *linear = (linear_gradient_t *)image;
 pixman_vector_t v;
 pixman_fixed_32_32_t l;
@@ -48,19 +47,19 @@ linear_gradient_classify (pixman_image_t *image,
 
 class = SOURCE_IMAGE_CLASS_UNKNOWN;
 
-if (source->common.transform)
+if (image->common.transform)
 {
/* projective transformation */
-   if (source->common.transform->matrix[2][0] != 0 ||
-   source->common.transform->matrix[2][1] != 0 ||
-   source->common.transform->matrix[2][2] == 0)
+   if (image->common.transform->matrix[2][0] != 0 ||
+   image->common.transform->matrix[2][1] != 0 ||
+   image->common.transform->matrix[2][2] == 0)
{
return class;
}
 
-   v.vector[0] = source->common.transform->matrix[0][1];
-   v.vector[1] = source->common.transform->matrix[1][1];
-   v.vector[2] = source->common.transform->matrix[2][2];
+   v.vector[0] = image->common.transform->matrix[0][1];
+   v.vector[1] = image->common.transform->matrix[1][1];
+   v.vector[2] = image->common.transform->matrix[2][2];
 }
 else
 {
@@ -104,26 +103,25 @@ linear_gradient_get_scanline_32 (pixman_image_t *image,
 pixman_fixed_32_32_t l;
 pixman_fixed_48_16_t dx, dy;
 gradient_t *gradient = (gradient_t *)image;
-source_image_t *source = (source_image_t *)image;
 linear_gradient_t *linear = (linear_gradient_t *)image;
 uint32_t *end = buffer + width;
 pixman_gradient_walker_t walker;
 
-_pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
+_pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
 
 /* reference point is the center of the pixel */
 v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
 v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
 v.vector[2] = pixman_fixed_1;
 
- 

[Pixman] [PATCH] Generate {a, x}8r8g8b8, a8, 565 fetchers for nearest/affine images

2010-11-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

There are versions for all combinations of x8r8g8b8/a8r8g8b8 and
pad/repeat/none/normal repeat modes. The bulk of each function is an
inline function that takes a format and a repeat mode as parameters.
---
 pixman/pixman-bits-image.c |  177 +++
 1 files changed, 144 insertions(+), 33 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 2e83c82..ff2dde3 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -907,6 +907,77 @@ bits_image_fetch_bilinear_affine (pixman_image_t * image,
 }
 }
 
+static force_inline void
+bits_image_fetch_nearest_affine (pixman_image_t * image,
+int  offset,
+int  line,
+int  width,
+uint32_t *   buffer,
+const uint32_t * mask,
+
+convert_pixel_tconvert_pixel,
+pixman_format_code_t   format,
+pixman_repeat_trepeat_mode)
+{
+pixman_fixed_t x, y;
+pixman_fixed_t ux, uy;
+pixman_vector_t v;
+bits_image_t *bits = &image->bits;
+int i;
+
+/* reference point is the center of the pixel */
+v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
+v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
+v.vector[2] = pixman_fixed_1;
+
+if (!pixman_transform_point_3d (image->common.transform, &v))
+   return;
+
+ux = image->common.transform->matrix[0][0];
+uy = image->common.transform->matrix[1][0];
+
+x = v.vector[0];
+y = v.vector[1];
+
+for (i = 0; i < width; ++i)
+{
+   int width, height, x0, y0;
+   const uint8_t *row;
+
+   if (mask && !mask[i])
+   goto next;
+   
+   width = image->bits.width;
+   height = image->bits.height;
+   x0 = pixman_fixed_to_int (x - pixman_fixed_e);
+   y0 = pixman_fixed_to_int (y - pixman_fixed_e);
+
+   if (repeat_mode == PIXMAN_REPEAT_NONE &&
+   (y0 < 0 || y0 >= height || x0 < 0 || x0 >= width))
+   {
+   buffer[i] = 0;
+   }
+   else
+   {
+   uint32_t mask = PIXMAN_FORMAT_A (format)? 0 : 0xff00;
+
+   if (repeat_mode != PIXMAN_REPEAT_NONE)
+   {
+   repeat (repeat_mode, width, &x0);
+   repeat (repeat_mode, height, &y0);
+   }
+
+   row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0;
+
+   buffer[i] = convert_pixel (row, x0) | mask;
+   }
+
+next:
+   x += ux;
+   y += uy;
+}
+}
+
 static force_inline uint32_t
 convert_a8r8g8b8 (const uint8_t *row, int x)
 {
@@ -940,29 +1011,51 @@ convert_r5g6b5 (const uint8_t *row, int x)
   uint32_t *   buffer, \
   const uint32_t * mask)   \
 {  \
-   bits_image_fetch_bilinear_affine (image, offset, line, width, buffer, 
mask, \
+   bits_image_fetch_bilinear_affine (image, offset, line,  \
+ width, buffer, mask,  \
  convert_ ## format,   \
  PIXMAN_ ## format,\
  repeat_mode); \
 }  \
 extern int no_such_variable
 
-MAKE_BILINEAR_FETCHER (pad_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_PAD);
-MAKE_BILINEAR_FETCHER (none_a8r8g8b8,a8r8g8b8, PIXMAN_REPEAT_NONE);
-MAKE_BILINEAR_FETCHER (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT);
-MAKE_BILINEAR_FETCHER (normal_a8r8g8b8,  a8r8g8b8, PIXMAN_REPEAT_NORMAL);
-MAKE_BILINEAR_FETCHER (pad_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_PAD);
-MAKE_BILINEAR_FETCHER (none_x8r8g8b8,x8r8g8b8, PIXMAN_REPEAT_NONE);
-MAKE_BILINEAR_FETCHER (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT);
-MAKE_BILINEAR_FETCHER (normal_x8r8g8b8,  x8r8g8b8, PIXMAN_REPEAT_NORMAL);
-MAKE_BILINEAR_FETCHER (pad_a8,   a8,   PIXMAN_REPEAT_PAD);
-MAKE_BILINEAR_FETCHER (none_a8,  a8,   PIXMAN_REPEAT_NONE);
-MAKE_BILINEAR_FETCHER (reflect_a8,  a8,   PIXMAN_REPEAT_REFLECT);
-MAKE_BILINEAR_FETCHER (normal_a8,   a8,   PIXMAN_REPEAT_NORMAL);
-MAKE_BILINEAR_FETCHER (pad_r5g6b5,   r5g6b5,   PIXMAN_REPEAT_PAD);
-MAKE_BILINEAR_FETCHER (none_r5g6b5,  r5g6b5,   PIXMAN_REPEAT_NONE);
-MAKE_BILINEAR_FETCHER (reflect_r5g6b5,   r5g6b5,   PIXMAN_REPEAT_REFLECT);
-MAKE_BILINEAR_FETCHER (normal_r5g6b5,r5g6b5,   P

[Pixman] [PATCH] Add support for AltiVec detection for OpenBSD/PowerPC.

2010-12-14 Thread Søren Sandmann
From: Brad Smith 

Bug 29331.
---
 pixman/pixman-cpu.c |   25 -
 1 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index e96b140..1b31885 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -61,6 +61,29 @@ pixman_have_vmx (void)
 return have_vmx;
 }
 
+#elif defined (__OpenBSD__)
+#include 
+#include 
+#include 
+
+static pixman_bool_t
+pixman_have_vmx (void)
+{
+if (!initialized)
+{
+   int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
+   size_t length = sizeof(have_vmx);
+   int error =
+   sysctl (&mib, 2, &have_vmx, &length, NULL, 0);
+
+   if (error)
+   have_vmx = FALSE;
+
+   initialized = TRUE;
+}
+return have_vmx;
+}
+
 #elif defined (__linux__)
 #include 
 #include 
@@ -123,7 +146,7 @@ pixman_have_vmx (void)
 return have_vmx;
 }
 
-#else /* !__APPLE__ && !__linux__ */
+#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
 #include 
 #include 
 
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] pixman_image_set_alpha_map(): Disallow alpha map cycles

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

If someone tries to set an alpha map that itself has an alpha map,
simply return. Also, if someone tries to add an alpha map to an image
that is being _used_ as an alpha map, simply return.

This ensures that an alpha map can never have an alpha map.
---
 pixman/pixman-image.c   |   30 +++---
 pixman/pixman-private.h |1 +
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 269c3c1..0b8bb3c 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -101,6 +101,7 @@ _pixman_image_allocate (void)
 
pixman_region32_init (&common->clip_region);
 
+   common->alpha_count = 0;
common->have_clip_region = FALSE;
common->clip_sources = FALSE;
common->transform = NULL;
@@ -195,9 +196,6 @@ pixman_image_unref (pixman_image_t *image)
if (common->filter_params)
free (common->filter_params);
 
-   if (common->alpha_map)
-   pixman_image_unref ((pixman_image_t *)common->alpha_map);
-
if (image->type == LINEAR ||
image->type == RADIAL ||
image->type == CONICAL)
@@ -668,15 +666,41 @@ pixman_image_set_alpha_map (pixman_image_t *image,
 
 return_if_fail (!alpha_map || alpha_map->type == BITS);
 
+if (alpha_map && common->alpha_count > 0)
+{
+   /* If this image is being used as an alpha map itself,
+* then you can't give it an alpha map of its own.
+*/
+   return;
+}
+
+if (alpha_map && alpha_map->common.alpha_map)
+{
+   /* If the image has an alpha map of its own,
+* then it can't be used as an alpha map itself
+*/
+   return;
+}
+
 if (common->alpha_map != (bits_image_t *)alpha_map)
 {
if (common->alpha_map)
+   {
+   common->alpha_map->common.alpha_count--;
+
pixman_image_unref ((pixman_image_t *)common->alpha_map);
+   }
 
if (alpha_map)
+   {
common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
+
+   common->alpha_map->common.alpha_count++;
+   }
else
+   {
common->alpha_map = NULL;
+   }
 }
 
 common->alpha_origin_x = x;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0629c42..c4e6bb8 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -80,6 +80,7 @@ struct image_common
 image_type_ttype;
 int32_t ref_count;
 pixman_region32_t   clip_region;
+int32_talpha_count;/* How many times this 
image is being used as an alpha map */
 pixman_bool_t   have_clip_region;   /* FALSE if there is no 
clip */
 pixman_bool_t   client_clip;/* Whether the source clip 
was
   set by a client */
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] Some test suite improvements

2010-12-14 Thread Søren Sandmann

Here is a set of patches that contain some updates to the test
suite. Specifically,

- gradient-crash-test is extended to test more scenarios

- floating point exceptions are enabled in some cases

- The argument to fence_malloc() becomes a signed integer, and it will
  abort() if someone tries to malloc a negative size.

- A new stress-test program that tries to use various combinations of
  unusual features. The hope is that this will provoke crashes or
  irregular behavior.


Soren

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Add alpha-loop test program

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This tests what happens if you attempt to make an image with an alpha
map that has the image as its alpha map. This results in an infinite
loop in _pixman_image_validate(), so the test sets up a SIGALRM to
exit if it runs for more than five seconds.
---
 configure.ac  |   12 +++-
 test/Makefile.am  |4 
 test/alpha-loop.c |   29 +
 test/utils.c  |   33 +
 test/utils.h  |3 +++
 5 files changed, 80 insertions(+), 1 deletions(-)
 create mode 100644 test/alpha-loop.c

diff --git a/configure.ac b/configure.ac
index 98c2783..acec8a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -600,13 +600,23 @@ AC_SUBST(DEP_CFLAGS)
 AC_SUBST(DEP_LIBS)
 
 dnl =
-dnl posix_memalign 
+dnl posix_memalign, sigaction, alarm
 
 AC_CHECK_FUNC(posix_memalign, have_posix_memalign=yes, have_posix_memalign=no)
 if test x$have_posix_memalign = xyes; then
AC_DEFINE(HAVE_POSIX_MEMALIGN, 1, [Whether we have posix_memalign()])
 fi
 
+AC_CHECK_FUNC(sigaction, have_sigaction=yes, have_sigaction=no)
+if test x$have_sigaction = xyes; then
+   AC_DEFINE(HAVE_SIGACTION, 1, [Whether we have sigaction()])
+fi
+
+AC_CHECK_FUNC(alarm, have_alarm=yes, have_alarm=no)
+if test x$have_alarm = xyes; then
+   AC_DEFINE(HAVE_ALARM, 1, [Whether we have alarm()])
+fi
+
 dnl =
 dnl Thread local storage
 
diff --git a/test/Makefile.am b/test/Makefile.am
index 2a7aea2..5273bec 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,6 +13,7 @@ TESTPROGRAMS =\
gradient-crash-test \
trap-crasher\
alphamap\
+   alpha-loop  \
scaling-crash-test  \
blitters-test   \
scaling-test\
@@ -39,6 +40,9 @@ scaling_test_SOURCES = scaling-test.c utils.c utils.h
 alphamap_LDADD = $(TEST_LDADD)
 alphamap_SOURCES = alphamap.c utils.c utils.h
 
+alpha_loop_LDADD = $(TEST_LDADD)
+alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/alpha-loop.c b/test/alpha-loop.c
new file mode 100644
index 000..e4d90a9
--- /dev/null
+++ b/test/alpha-loop.c
@@ -0,0 +1,29 @@
+#include 
+#include 
+#include "utils.h"
+
+#define WIDTH 400
+#define HEIGHT 200
+
+int
+main (int argc, char **argv)
+{
+uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
+uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+
+pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, 
(uint32_t *)alpha, WIDTH);
+pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, 
HEIGHT, dest, WIDTH * 4);
+pixman_image_t *s = pixman_image_create_bits (PIXMAN_a2r10g10b10, WIDTH, 
HEIGHT, src, WIDTH * 4);
+
+fail_after (5, "Infinite loop detected: 5 seconds without progress\n");
+
+pixman_image_set_alpha_map (s, a, 0, 0);
+pixman_image_set_alpha_map (a, s, 0, 0);
+
+pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, 
WIDTH, HEIGHT);
+
+pixman_image_unref (s);
+
+return 0;
+}
diff --git a/test/utils.c b/test/utils.c
index 1ee5c9c..d95cbc2 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -1,4 +1,9 @@
 #include "utils.h"
+#include 
+
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
 
 /* Random number seed
  */
@@ -319,3 +324,31 @@ fuzzer_test_main (const char *test_name,
 
 return 0;
 }
+
+static const char *global_msg;
+
+static void
+on_alarm (int signo)
+{
+printf ("%s\n", global_msg);
+exit (1);
+}
+
+void
+fail_after (int seconds, const char *msg)
+{
+#ifdef HAVE_SIGACTION
+#ifdef HAVE_ALARM
+struct sigaction action;
+
+global_msg = msg;
+
+memset (&action, 0, sizeof (action));
+action.sa_handler = on_alarm;
+
+alarm (seconds);
+
+sigaction (SIGALRM, &action, NULL);
+#endif
+#endif
+}
diff --git a/test/utils.h b/test/utils.h
index 95d809a..bfb76a5 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -62,3 +62,6 @@ fuzzer_test_main (const char *test_name,
  uint32_t(*test_function)(int testnum, int verbose),
  int argc,
  const char *argv[]);
+
+void
+fail_after (int seconds, const char *msg);
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] Store a2b2g2r2 pixel through the WRITE macro

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Otherwise, accessor functions won't work.
---
 pixman/pixman-access.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 56de711..f1ce0ba 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -2425,11 +2425,11 @@ store_scanline_a2b2g2r2 (bits_image_t *  image,
 {
SPLIT_A (values[i]);

-   *(pixel++) =
-   ((a ) & 0xc0) |
-   ((b >> 2) & 0x30) |
-   ((g >> 4) & 0x0c) |
-   ((r >> 6)   );
+   WRITE (image, pixel++,
+  ((a ) & 0xc0) |
+  ((b >> 2) & 0x30) |
+  ((g >> 4) & 0x0c) |
+  ((r >> 6)   ));
 }
 }
 
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] test: Make composite test use some existing macros instead of defining its own

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Also move the ARRAY_LENGTH macro into utils.h so it can be used elsewhere.
---
 test/composite.c |   56 +
 test/utils.h |2 +
 2 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/test/composite.c b/test/composite.c
index 5cdc521..e14f954 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -31,10 +31,6 @@
 #include 
 #include "utils.h"
 
-#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
-#define min(a,b) ((a) <= (b) ? (a) : (b))
-#define max(a,b) ((a) >= (b) ? (a) : (b))
-
 typedef struct color_t color_t;
 typedef struct format_t format_t;
 typedef struct image_t image_t;
@@ -211,7 +207,7 @@ static const operator_t operators[] =
 static double
 calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
 {
-#define mult_chan(src, dst, Fa, Fb) min ((src) * (Fa) + (dst) * (Fb), 1.0)
+#define mult_chan(src, dst, Fa, Fb) MIN ((src) * (Fa) + (dst) * (Fb), 1.0)
 
 double Fa, Fb;
 
@@ -267,150 +263,150 @@ calc_op (pixman_op_t op, double src, double dst, double 
srca, double dsta)
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, (1.0 - dsta) / srca);
+   Fa = MIN (1.0, (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 1.0);
 
 case PIXMAN_OP_DISJOINT_OVER:
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, (1.0 - srca) / dsta);
+   Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, 1.0, Fb);
 
 case PIXMAN_OP_DISJOINT_IN:
if (srca == 0.0)
Fa = 0.0;
else
-   Fa = max (0.0, 1.0 - (1.0 - dsta) / srca);
+   Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 0.0);
 
 case PIXMAN_OP_DISJOINT_IN_REVERSE:
if (dsta == 0.0)
Fb = 0.0;
else
-   Fb = max (0.0, 1.0 - (1.0 - srca) / dsta);
+   Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
return mult_chan (src, dst, 0.0, Fb);
 
 case PIXMAN_OP_DISJOINT_OUT:
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, (1.0 - dsta) / srca);
+   Fa = MIN (1.0, (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 0.0);
 
 case PIXMAN_OP_DISJOINT_OUT_REVERSE:
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, (1.0 - srca) / dsta);
+   Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, 0.0, Fb);
 
 case PIXMAN_OP_DISJOINT_ATOP:
if (srca == 0.0)
Fa = 0.0;
else
-   Fa = max (0.0, 1.0 - (1.0 - dsta) / srca);
+   Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, (1.0 - srca) / dsta);
+   Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
 
 case PIXMAN_OP_DISJOINT_ATOP_REVERSE:
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, (1.0 - dsta) / srca);
+   Fa = MIN (1.0, (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 0.0;
else
-   Fb = max (0.0, 1.0 - (1.0 - srca) / dsta);
+   Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
 
 case PIXMAN_OP_DISJOINT_XOR:
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, (1.0 - dsta) / srca);
+   Fa = MIN (1.0, (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, (1.0 - srca) / dsta);
+   Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
 
 case PIXMAN_OP_CONJOINT_OVER:
if (dsta == 0.0)
Fb = 0.0;
else
-   Fb = max (0.0, 1.0 - srca / dsta);
+   Fb = MAX (0.0, 1.0 - srca / dsta);
return mult_chan (src, dst, 1.0, Fb);
 
 case PIXMAN_OP_CONJOINT_OVER_REVERSE:
if (srca == 0.0)
Fa = 0.0;
else
-   Fa = max (0.0, 1.0 - dsta / srca);
+   Fa = MAX (0.0, 1.0 - dsta / srca);
return mult_chan (src, dst, Fa, 1.0);
 
 case PIXMAN_OP_CONJOINT_IN:
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, dsta / srca);
+   Fa = MIN (1.0, dsta / srca);
return mult_chan (src, dst, Fa, 0.0);
 
 case PIXMAN_OP_CONJOINT_IN_REVERSE:
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, srca / dsta);
+   Fb = MIN (1.0, srca / dsta);
return mult_chan (src, dst, 0.0, Fb);
 
 case PIXMAN_OP_CONJOINT_OUT:
if (srca == 0.0)
Fa = 0.0;
else
-   Fa = max (0.0, 1.0 - dsta / srca);
+   Fa = MAX (0.0, 1.0 - dsta / srca);
return mult_chan (src, dst, Fa, 0

[Pixman] [PATCH] Add enable_fp_exceptions() function in utils.[ch]

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This function enables floating point traps if possible.
---
 configure.ac |8 
 test/utils.c |   26 ++
 test/utils.h |3 +++
 3 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/configure.ac b/configure.ac
index 147e1bf..2570c84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -639,6 +639,14 @@ if test x$have_getpagesize = xyes; then
AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()])
 fi
 
+AC_CHECK_HEADER([fenv.h],
+   [AC_DEFINE(HAVE_FENV_H, [1], [Define to 1 if we have ])])
+
+AC_CHECK_LIB(m, feenableexcept, have_feenableexcept=yes, 
have_feenableexcept=no)
+if test x$have_feenableexcept = xyes; then
+   AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()])
+fi
+
 AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no)
 AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no)
 if test x$have_gettimeofday = xyes && test x$have_sys_time_h = xyes; then
diff --git a/test/utils.c b/test/utils.c
index f6278fe..a7c55f6 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -1,3 +1,5 @@
+#define _GNU_SOURCE
+
 #include "utils.h"
 #include 
 
@@ -15,6 +17,10 @@
 #include 
 #endif
 
+#ifdef HAVE_FENV_H
+#include 
+#endif
+
 /* Random number seed
  */
 
@@ -469,6 +475,26 @@ fail_after (int seconds, const char *msg)
 #endif
 }
 
+void
+enable_fp_exceptions (void)
+{
+#ifdef HAVE_FENV_H
+#ifdef HAVE_FEENABLEEXCEPT
+/* Note: we don't enable the FE_INEXACT trap because
+ * that happens quite commonly. It is possible that
+ * over- and underflow should similarly be considered
+ * okay, but for now the test suite passes with them
+ * enabled, and it's useful to know if they start
+ * occuring.
+ */
+feenableexcept (FE_DIVBYZERO   |
+   FE_INVALID  |
+   FE_OVERFLOW |
+   FE_UNDERFLOW);
+#endif
+#endif
+}
+
 void *
 aligned_malloc (size_t align, size_t size)
 {
diff --git a/test/utils.h b/test/utils.h
index 2ea4170..bac2916 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -82,6 +82,9 @@ fuzzer_test_main (const char *test_name,
 void
 fail_after (int seconds, const char *msg);
 
+/* If possible, enable traps for floating point exceptions */
+void enable_fp_exceptions(void);
+
 /* A pair of macros which can help to detect corruption of
  * floating point registers after a function call. This may
  * happen if _mm_empty() call is forgotten in MMX/SSE2 fast
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] When pixman_compute_composite_region32() return FALSE, don't fini the region.

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The rule is that the region passed in must be initialized and that the
region returned will still be valid. Ie., the lifecycle is the
responsibility of the caller, regardless of what the function returns.

Previously, composite_region32() would finalize the region and then
return FALSE, and then the caller would finalize the region again,
leading to memory corruption in some cases.
---
 pixman/pixman.c |   14 +-
 1 files changed, 1 insertions(+), 13 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index 402c72c..62b58b8 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -302,17 +302,13 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 if (region->extents.x1 >= region->extents.x2 ||
 region->extents.y1 >= region->extents.y2)
 {
-   pixman_region32_init (region);
return FALSE;
 }
 
 if (dst_image->common.have_clip_region)
 {
if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
-   {
-   pixman_region32_fini (region);
return FALSE;
-   }
 }
 
 if (dst_image->common.alpha_map && 
dst_image->common.alpha_map->common.have_clip_region)
@@ -321,7 +317,6 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 -dst_image->common.alpha_origin_x,
 -dst_image->common.alpha_origin_y))
{
-   pixman_region32_fini (region);
return FALSE;
}
 }
@@ -330,10 +325,7 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 if (src_image->common.have_clip_region)
 {
if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - 
src_y))
-   {
-   pixman_region32_fini (region);
return FALSE;
-   }
 }
 if (src_image->common.alpha_map && 
src_image->common.alpha_map->common.have_clip_region)
 {
@@ -341,7 +333,6 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
dest_x - (src_x - 
src_image->common.alpha_origin_x),
dest_y - (src_y - 
src_image->common.alpha_origin_y)))
{
-   pixman_region32_fini (region);
return FALSE;
}
 }
@@ -349,17 +340,14 @@ pixman_compute_composite_region32 (pixman_region32_t * 
region,
 if (mask_image && mask_image->common.have_clip_region)
 {
if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - 
mask_y))
-   {
-   pixman_region32_fini (region);
return FALSE;
-   }
+
if (mask_image->common.alpha_map && 
mask_image->common.alpha_map->common.have_clip_region)
{
if (!clip_source_image (region, (pixman_image_t 
*)mask_image->common.alpha_map,
dest_x - (mask_x - 
mask_image->common.alpha_origin_x),
dest_y - (mask_y - 
mask_image->common.alpha_origin_y)))
{
-   pixman_region32_fini (region);
return FALSE;
}
}
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] bits: Fix potential divide-by-zero in projective code

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

If the homogeneous coordinate is 0, just set the coordinates to 0.
---
 pixman/pixman-bits-image.c |   16 
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 95710b4..36ea0af 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -695,12 +695,20 @@ bits_image_fetch_transformed (pixman_image_t * image,
 {
for (i = 0; i < width; ++i)
{
-   pixman_fixed_t x0, y0;
-
if (!mask || mask[i])
{
-   x0 = ((pixman_fixed_48_16_t)x << 16) / w;
-   y0 = ((pixman_fixed_48_16_t)y << 16) / w;
+   pixman_fixed_t x0, y0;
+
+   if (w != 0)
+   {
+   x0 = ((pixman_fixed_48_16_t)x << 16) / w;
+   y0 = ((pixman_fixed_48_16_t)y << 16) / w;
+   }
+   else
+   {
+   x0 = 0;
+   y0 = 0;
+   }
 
buffer[i] =
bits_image_fetch_pixel_filtered (&image->bits, x0, y0);
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 0/7] Some test suite improvements (second attempt)

2010-12-14 Thread Søren Sandmann

Sorry about the spam I just sent with a jumble of old and new
patches. Hopefully this time it will work better.

Here is a set of patches that contain some updates to the test
suite. Specifically,

- gradient-crash-test is extended to test more scenarios

- floating point exceptions are enabled in some cases

- The argument to fence_malloc() becomes a signed integer, and it will
  abort() if someone tries to malloc a negative size.

- A new stress-test program that tries to use various combinations of
  unusual features. The hope is that this will provoke crashes or
  irregular behavior.


Soren
___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 2/7] Add enable_fp_exceptions() function in utils.[ch]

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This function enables floating point traps if possible.
---
 configure.ac |8 
 test/utils.c |   26 ++
 test/utils.h |3 +++
 3 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/configure.ac b/configure.ac
index 147e1bf..2570c84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -639,6 +639,14 @@ if test x$have_getpagesize = xyes; then
AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()])
 fi
 
+AC_CHECK_HEADER([fenv.h],
+   [AC_DEFINE(HAVE_FENV_H, [1], [Define to 1 if we have ])])
+
+AC_CHECK_LIB(m, feenableexcept, have_feenableexcept=yes, 
have_feenableexcept=no)
+if test x$have_feenableexcept = xyes; then
+   AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()])
+fi
+
 AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no)
 AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no)
 if test x$have_gettimeofday = xyes && test x$have_sys_time_h = xyes; then
diff --git a/test/utils.c b/test/utils.c
index f6278fe..a7c55f6 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -1,3 +1,5 @@
+#define _GNU_SOURCE
+
 #include "utils.h"
 #include 
 
@@ -15,6 +17,10 @@
 #include 
 #endif
 
+#ifdef HAVE_FENV_H
+#include 
+#endif
+
 /* Random number seed
  */
 
@@ -469,6 +475,26 @@ fail_after (int seconds, const char *msg)
 #endif
 }
 
+void
+enable_fp_exceptions (void)
+{
+#ifdef HAVE_FENV_H
+#ifdef HAVE_FEENABLEEXCEPT
+/* Note: we don't enable the FE_INEXACT trap because
+ * that happens quite commonly. It is possible that
+ * over- and underflow should similarly be considered
+ * okay, but for now the test suite passes with them
+ * enabled, and it's useful to know if they start
+ * occuring.
+ */
+feenableexcept (FE_DIVBYZERO   |
+   FE_INVALID  |
+   FE_OVERFLOW |
+   FE_UNDERFLOW);
+#endif
+#endif
+}
+
 void *
 aligned_malloc (size_t align, size_t size)
 {
diff --git a/test/utils.h b/test/utils.h
index 2ea4170..bac2916 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -82,6 +82,9 @@ fuzzer_test_main (const char *test_name,
 void
 fail_after (int seconds, const char *msg);
 
+/* If possible, enable traps for floating point exceptions */
+void enable_fp_exceptions(void);
+
 /* A pair of macros which can help to detect corruption of
  * floating point registers after a function call. This may
  * happen if _mm_empty() call is forgotten in MMX/SSE2 fast
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 1/7] test: Make composite test use some existing macros instead of defining its own

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Also move the ARRAY_LENGTH macro into utils.h so it can be used elsewhere.
---
 test/composite.c |   56 +
 test/utils.h |2 +
 2 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/test/composite.c b/test/composite.c
index 5cdc521..e14f954 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -31,10 +31,6 @@
 #include 
 #include "utils.h"
 
-#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
-#define min(a,b) ((a) <= (b) ? (a) : (b))
-#define max(a,b) ((a) >= (b) ? (a) : (b))
-
 typedef struct color_t color_t;
 typedef struct format_t format_t;
 typedef struct image_t image_t;
@@ -211,7 +207,7 @@ static const operator_t operators[] =
 static double
 calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
 {
-#define mult_chan(src, dst, Fa, Fb) min ((src) * (Fa) + (dst) * (Fb), 1.0)
+#define mult_chan(src, dst, Fa, Fb) MIN ((src) * (Fa) + (dst) * (Fb), 1.0)
 
 double Fa, Fb;
 
@@ -267,150 +263,150 @@ calc_op (pixman_op_t op, double src, double dst, double 
srca, double dsta)
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, (1.0 - dsta) / srca);
+   Fa = MIN (1.0, (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 1.0);
 
 case PIXMAN_OP_DISJOINT_OVER:
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, (1.0 - srca) / dsta);
+   Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, 1.0, Fb);
 
 case PIXMAN_OP_DISJOINT_IN:
if (srca == 0.0)
Fa = 0.0;
else
-   Fa = max (0.0, 1.0 - (1.0 - dsta) / srca);
+   Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 0.0);
 
 case PIXMAN_OP_DISJOINT_IN_REVERSE:
if (dsta == 0.0)
Fb = 0.0;
else
-   Fb = max (0.0, 1.0 - (1.0 - srca) / dsta);
+   Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
return mult_chan (src, dst, 0.0, Fb);
 
 case PIXMAN_OP_DISJOINT_OUT:
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, (1.0 - dsta) / srca);
+   Fa = MIN (1.0, (1.0 - dsta) / srca);
return mult_chan (src, dst, Fa, 0.0);
 
 case PIXMAN_OP_DISJOINT_OUT_REVERSE:
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, (1.0 - srca) / dsta);
+   Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, 0.0, Fb);
 
 case PIXMAN_OP_DISJOINT_ATOP:
if (srca == 0.0)
Fa = 0.0;
else
-   Fa = max (0.0, 1.0 - (1.0 - dsta) / srca);
+   Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, (1.0 - srca) / dsta);
+   Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
 
 case PIXMAN_OP_DISJOINT_ATOP_REVERSE:
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, (1.0 - dsta) / srca);
+   Fa = MIN (1.0, (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 0.0;
else
-   Fb = max (0.0, 1.0 - (1.0 - srca) / dsta);
+   Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
 
 case PIXMAN_OP_DISJOINT_XOR:
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, (1.0 - dsta) / srca);
+   Fa = MIN (1.0, (1.0 - dsta) / srca);
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, (1.0 - srca) / dsta);
+   Fb = MIN (1.0, (1.0 - srca) / dsta);
return mult_chan (src, dst, Fa, Fb);
 
 case PIXMAN_OP_CONJOINT_OVER:
if (dsta == 0.0)
Fb = 0.0;
else
-   Fb = max (0.0, 1.0 - srca / dsta);
+   Fb = MAX (0.0, 1.0 - srca / dsta);
return mult_chan (src, dst, 1.0, Fb);
 
 case PIXMAN_OP_CONJOINT_OVER_REVERSE:
if (srca == 0.0)
Fa = 0.0;
else
-   Fa = max (0.0, 1.0 - dsta / srca);
+   Fa = MAX (0.0, 1.0 - dsta / srca);
return mult_chan (src, dst, Fa, 1.0);
 
 case PIXMAN_OP_CONJOINT_IN:
if (srca == 0.0)
Fa = 1.0;
else
-   Fa = min (1.0, dsta / srca);
+   Fa = MIN (1.0, dsta / srca);
return mult_chan (src, dst, Fa, 0.0);
 
 case PIXMAN_OP_CONJOINT_IN_REVERSE:
if (dsta == 0.0)
Fb = 1.0;
else
-   Fb = min (1.0, srca / dsta);
+   Fb = MIN (1.0, srca / dsta);
return mult_chan (src, dst, 0.0, Fb);
 
 case PIXMAN_OP_CONJOINT_OUT:
if (srca == 0.0)
Fa = 0.0;
else
-   Fa = max (0.0, 1.0 - dsta / srca);
+   Fa = MAX (0.0, 1.0 - dsta / srca);
return mult_chan (src, dst, Fa, 0

[Pixman] [PATCH 3/7] Extend gradient-crash-test

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Test the gradients with various transformations, and test cases where
the gradients are specified with two identical points.
---
 test/Makefile.am   |5 ++-
 test/gradient-crash-test.c |  124 +--
 2 files changed, 87 insertions(+), 42 deletions(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 79a1223..4f950d9 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -14,6 +14,7 @@ TESTPROGRAMS =\
trap-crasher\
alpha-loop  \
scaling-crash-test  \
+   gradient-crash-test \
alphamap\
blitters-test   \
scaling-test\
@@ -22,7 +23,6 @@ TESTPROGRAMS =\
 
 a1_trap_test_LDADD = $(TEST_LDADD)
 fetch_test_LDADD = $(TEST_LDADD)
-gradient_crash_test_LDADD = $(TEST_LDADD)
 trap_crasher_LDADD = $(TEST_LDADD)
 oob_test_LDADD = $(TEST_LDADD)
 scaling_crash_test_LDADD = $(TEST_LDADD)
@@ -49,6 +49,9 @@ alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
 composite_LDADD = $(TEST_LDADD)
 composite_SOURCES = composite.c utils.c utils.h
 
+gradient_crash_test_LDADD = $(TEST_LDADD)
+gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/gradient-crash-test.c b/test/gradient-crash-test.c
index 804f83b..395c469 100644
--- a/test/gradient-crash-test.c
+++ b/test/gradient-crash-test.c
@@ -1,6 +1,7 @@
 #include 
 #include 
-#include "pixman.h"
+#include 
+#include "utils.h"
 
 int
 main (int argc, char **argv)
@@ -11,8 +12,14 @@ main (int argc, char **argv)
 uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
 pixman_image_t *src_img;
 pixman_image_t *dest_img;
-int i, j;
+int i, j, k, p;
 
+typedef struct
+{
+   pixman_point_fixed_t p0;
+   pixman_point_fixed_t p1;
+} point_pair_t;
+
 pixman_gradient_stop_t onestop[1] =
{
{ pixman_int_to_fixed (1), { 0x, 0x, 0x, 0x } },
@@ -30,29 +37,56 @@ main (int argc, char **argv)
{ pixman_int_to_fixed (1), { 0x, 0x, 0x, 0x } }
};
 
-pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 };
-pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH / 8.),
-   pixman_int_to_fixed (0) };
-
-#if 0
-pixman_transform_t trans = {
-   { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), 
pixman_double_to_fixed (-100), },
- { pixman_double_to_fixed (0), pixman_double_to_fixed (3), 
pixman_double_to_fixed (0), },
- { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), 
pixman_double_to_fixed (1.0) } 
-   }
-};
-#else
-pixman_transform_t trans = {
-   { { pixman_fixed_1, 0, 0 },
- { 0, pixman_fixed_1, 0 },
- { 0, 0, pixman_fixed_1 } }
+point_pair_t point_pairs [] =
+   { { { pixman_double_to_fixed (0), 0 },
+   { pixman_double_to_fixed (WIDTH / 8.), pixman_int_to_fixed (0) } },
+ { { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed 
(HEIGHT / 2.0) },
+   { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed 
(HEIGHT / 2.0) } }
+   };
+
+pixman_transform_t transformations[] = {
+   {
+   { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), 
pixman_double_to_fixed (-100), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (3), 
pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), 
pixman_double_to_fixed (1.0) } 
+   }
+   },
+   {
+   { { pixman_double_to_fixed (1), pixman_double_to_fixed (0), 
pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (1), 
pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), 
pixman_double_to_fixed (1.0) } 
+   }
+   },
+   {
+   { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), 
pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (1), pixman_double_to_fixed (1), 
pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (2), pixman_double_to_fixed (1.000), 
pixman_double_to_fixed (1.0) } 
+   }
+   },
+   {
+   { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), 
pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (1), pixman_double_to_fixed (1), 
pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (0), pixman_double_to_fixed (0), 
pixman_double_to_fixed (0) } 
+   }
+   },
+   {
+   { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), 
pixman_double_to_fixed (0), },
+ { pixman_double_to_fixed (1), pixman_double_to_fixed (1), 
pixma

[Pixman] [PATCH 4/7] test: Move palette initialization to utils.[ch]

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

---
 test/blitters-test.c |   57 +
 test/utils.c |   54 +++
 test/utils.h |3 ++
 3 files changed, 59 insertions(+), 55 deletions(-)

diff --git a/test/blitters-test.c b/test/blitters-test.c
index 77a26dd..21685b1 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -400,59 +400,6 @@ test_composite (int testnum, int verbose)
 return crc32;
 }
 
-#define CONVERT_15(c, is_rgb)  \
-(is_rgb?   \
- c) >> 3) & 0x001f) |  \
-  (((c) >> 6) & 0x03e0) |  \
-  (((c) >> 9) & 0x7c00)) : \
- (c) >> 16) & 0xff) * 153 +\
-   (((c) >>  8) & 0xff) * 301 +\
-   (((c)  ) & 0xff) * 58) >> 2))
-
-static void
-initialize_palette (pixman_indexed_t *palette, uint32_t mask, int is_rgb)
-{
-int i;
-
-for (i = 0; i < 32768; ++i)
-   palette->ent[i] = lcg_rand() & mask;
-
-for (i = 0; i < mask + 1; ++i)
-{
-   uint32_t rgba24;
-   pixman_bool_t retry;
-   uint32_t i15;
-
-   /* We filled the rgb->index map with random numbers, but we
-* do need the ability to round trip, that is if some indexed
-* color expands to an argb24, then the 15 bit version of that
-* color must map back to the index. Anything else, we don't
-* care about too much.
-*/
-   do
-   {
-   uint32_t old_idx;
-   
-   rgba24 = lcg_rand();
-   i15 = CONVERT_15 (rgba24, is_rgb);
-
-   old_idx = palette->ent[i15];
-   if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
-   retry = 1;
-   else
-   retry = 0;
-   } while (retry);
-   
-   palette->rgba[i] = rgba24;
-   palette->ent[i15] = i;
-}
-
-for (i = 0; i < mask + 1; ++i)
-{
-   assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
-}
-}
-
 int
 main (int argc, const char *argv[])
 {
@@ -460,8 +407,8 @@ main (int argc, const char *argv[])
 
 for (i = 1; i <= 8; i++)
 {
-   initialize_palette (&(rgb_palette[i]), (1 << i) - 1, TRUE);
-   initialize_palette (&(y_palette[i]), (1 << i) - 1, FALSE);
+   initialize_palette (&(rgb_palette[i]), i, TRUE);
+   initialize_palette (&(y_palette[i]), i, FALSE);
 }
 
 return fuzzer_test_main("blitters", 200,
diff --git a/test/utils.c b/test/utils.c
index a7c55f6..4701bf6 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -509,3 +509,57 @@ aligned_malloc (size_t align, size_t size)
 
 return result;
 }
+
+#define CONVERT_15(c, is_rgb)  \
+(is_rgb?   \
+ c) >> 3) & 0x001f) |  \
+  (((c) >> 6) & 0x03e0) |  \
+  (((c) >> 9) & 0x7c00)) : \
+ (c) >> 16) & 0xff) * 153 +\
+   (((c) >>  8) & 0xff) * 301 +\
+   (((c)  ) & 0xff) * 58) >> 2))
+
+void
+initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
+{
+int i;
+uint32_t mask = (1 << depth) - 1;
+
+for (i = 0; i < 32768; ++i)
+   palette->ent[i] = lcg_rand() & mask;
+
+for (i = 0; i < mask + 1; ++i)
+{
+   uint32_t rgba24;
+   pixman_bool_t retry;
+   uint32_t i15;
+
+   /* We filled the rgb->index map with random numbers, but we
+* do need the ability to round trip, that is if some indexed
+* color expands to an argb24, then the 15 bit version of that
+* color must map back to the index. Anything else, we don't
+* care about too much.
+*/
+   do
+   {
+   uint32_t old_idx;
+
+   rgba24 = lcg_rand();
+   i15 = CONVERT_15 (rgba24, is_rgb);
+
+   old_idx = palette->ent[i15];
+   if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
+   retry = 1;
+   else
+   retry = 0;
+   } while (retry);
+
+   palette->rgba[i] = rgba24;
+   palette->ent[i15] = i;
+}
+
+for (i = 0; i < mask + 1; ++i)
+{
+   assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
+}
+}
diff --git a/test/utils.h b/test/utils.h
index bac2916..7b33461 100644

[Pixman] [PATCH 6/7] Make the argument to fence_malloc() an int64_t

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

That way we can detect if someone attempts to allocate a negative size
and abort instead of just returning NULL and segfaulting later.
---
 test/utils.c |7 +--
 test/utils.h |2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/test/utils.c b/test/utils.c
index cde9c62..6bcc935 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -232,7 +232,7 @@ typedef struct
 #endif
 
 void *
-fence_malloc (uint32_t len)
+fence_malloc (int64_t len)
 {
 unsigned long page_size = getpagesize();
 unsigned long page_mask = page_size - 1;
@@ -246,12 +246,15 @@ fence_malloc (uint32_t len)
 uint8_t *payload;
 uint8_t *addr;
 
+if (len < 0)
+   abort();
+
 addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | 
MAP_ANONYMOUS,
 -1, 0);
 
 if (addr == MAP_FAILED)
 {
-   printf ("mmap failed on %u %u\n", len, n_bytes);
+   printf ("mmap failed on %lld %u\n", len, n_bytes);
return NULL;
 }
 
diff --git a/test/utils.h b/test/utils.h
index 7b33461..abd11ec 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -57,7 +57,7 @@ image_endian_swap (pixman_image_t *img, int bpp);
  * so that out-of-bounds access will cause segfaults
  */
 void *
-fence_malloc (uint32_t len);
+fence_malloc (int64_t len);
 
 void
 fence_free (void *data);
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 5/7] test/utils.c: Initialize palette->rgba to 0.

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

That way it can be used with palettes that are not statically
allocated, without causing valgrind issues.
---
 test/utils.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/test/utils.c b/test/utils.c
index 4701bf6..cde9c62 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -528,6 +528,8 @@ initialize_palette (pixman_indexed_t *palette, uint32_t 
depth, int is_rgb)
 for (i = 0; i < 32768; ++i)
palette->ent[i] = lcg_rand() & mask;
 
+memset (palette->rgba, 0, sizeof (palette->rgba));
+
 for (i = 0; i < mask + 1; ++i)
 {
uint32_t rgba24;
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 7/7] Add a stress-test program.

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This test program tries to use as many rarely-used features as
possible, including alpha maps, accessor functions, oddly-sized
images, strange transformations, conical gradients, etc.

The hope is to provoke crashes or irregular behavior in pixman.
---
 test/Makefile.am   |4 +
 test/stress-test.c |  858 
 test/utils.h   |9 +
 3 files changed, 871 insertions(+), 0 deletions(-)
 create mode 100644 test/stress-test.c

diff --git a/test/Makefile.am b/test/Makefile.am
index 4f950d9..e557d7a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -16,6 +16,7 @@ TESTPROGRAMS =\
scaling-crash-test  \
gradient-crash-test \
alphamap\
+   stress-test \
blitters-test   \
scaling-test\
affine-test \
@@ -52,6 +53,9 @@ composite_SOURCES = composite.c utils.c utils.h
 gradient_crash_test_LDADD = $(TEST_LDADD)
 gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h
 
+stress_test_LDADD = $(TEST_LDADD)
+stress_test_SOURCES = stress-test.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/stress-test.c b/test/stress-test.c
new file mode 100644
index 000..d8dd79c
--- /dev/null
+++ b/test/stress-test.c
@@ -0,0 +1,858 @@
+#include "utils.h"
+
+#if 0
+#define fence_malloc malloc
+#define fence_free free
+#define make_random_bytes malloc
+#endif
+
+static const pixman_format_code_t image_formats[] =
+{
+PIXMAN_a8r8g8b8,
+PIXMAN_x8r8g8b8,
+PIXMAN_r5g6b5,
+PIXMAN_r3g3b2,
+PIXMAN_a8,
+PIXMAN_a8b8g8r8,
+PIXMAN_x8b8g8r8,
+PIXMAN_b8g8r8a8,
+PIXMAN_b8g8r8x8,
+PIXMAN_x14r6g6b6,
+PIXMAN_r8g8b8,
+PIXMAN_b8g8r8,
+PIXMAN_r5g6b5,
+PIXMAN_b5g6r5,
+PIXMAN_x2r10g10b10,
+PIXMAN_a2r10g10b10,
+PIXMAN_x2b10g10r10,
+PIXMAN_a2b10g10r10,
+PIXMAN_a1r5g5b5,
+PIXMAN_x1r5g5b5,
+PIXMAN_a1b5g5r5,
+PIXMAN_x1b5g5r5,
+PIXMAN_a4r4g4b4,
+PIXMAN_x4r4g4b4,
+PIXMAN_a4b4g4r4,
+PIXMAN_x4b4g4r4,
+PIXMAN_a8,
+PIXMAN_r3g3b2,
+PIXMAN_b2g3r3,
+PIXMAN_a2r2g2b2,
+PIXMAN_a2b2g2r2,
+PIXMAN_c8,
+PIXMAN_g8,
+PIXMAN_x4c4,
+PIXMAN_x4g4,
+PIXMAN_c4,
+PIXMAN_g4,
+PIXMAN_g1,
+PIXMAN_x4a4,
+PIXMAN_a4,
+PIXMAN_r1g2b1,
+PIXMAN_b1g2r1,
+PIXMAN_a1r1g1b1,
+PIXMAN_a1b1g1r1,
+PIXMAN_a1
+};
+
+static pixman_filter_t filters[] =
+{
+PIXMAN_FILTER_NEAREST,
+PIXMAN_FILTER_BILINEAR,
+PIXMAN_FILTER_FAST,
+PIXMAN_FILTER_GOOD,
+PIXMAN_FILTER_BEST,
+PIXMAN_FILTER_CONVOLUTION
+};
+
+static int
+get_size (void)
+{
+switch (lcg_rand_n (28))
+{
+case 0:
+   return 1;
+
+case 1:
+   return 2;
+
+default:
+case 2:
+   return lcg_rand_n (200);
+
+case 4:
+   return lcg_rand_n (2000) + 1000;
+
+case 5:
+   return 65535;
+
+case 6:
+   return 65536;
+
+case 7:
+   return lcg_rand_N (64000) + 63000;
+}
+}
+
+static void
+destroy (pixman_image_t *image, void *data)
+{
+if (image->type == BITS && image->bits.free_me != image->bits.bits)
+{
+   uint32_t *bits;
+
+   if (image->bits.bits != (void *)0x01)
+   {
+   bits = image->bits.bits;
+
+   if (image->bits.rowstride < 0)
+   {
+   bits -= (- image->bits.rowstride * (image->bits.height - 1));
+
+   }
+
+   fence_free (bits);
+   }
+}
+
+free (data);
+}
+
+static uint32_t
+real_reader (const void *src, int size)
+{
+switch (size)
+{
+case 1:
+   return *(uint8_t *)src;
+case 2:
+   return *(uint16_t *)src;
+case 4:
+   return *(uint32_t *)src;
+default:
+   assert (0);
+   break;
+}
+}
+
+static void
+real_writer (void *src, uint32_t value, int size)
+{
+switch (size)
+{
+case 1:
+   *(uint8_t *)src = value;
+   break;
+
+case 2:
+   *(uint16_t *)src = value;
+   break;
+
+case 4:
+   *(uint32_t *)src = value;
+   break;
+
+default:
+   assert (0);
+   break;
+}
+}
+
+static uint32_t
+fake_reader (const void *src, int size)
+{
+uint32_t r = lcg_rand_u32 ();
+
+assert (size == 1 || size == 2 || size == 4);
+return r & ((1 << (size * 8)) - 1);
+}
+
+static void
+fake_writer (void *src, uint32_t value, int size)
+{
+assert (size == 1 || size == 2 || size == 4);
+}
+
+static int32_t
+log_rand (void)
+{
+uint32_t mask;
+
+mask = (1 << lcg_rand_n (31)) - 1;
+
+return (lcg_rand () & mask) - (mask >> 1);
+}
+
+static pixman_image_t *
+create_random_bits_image (void)
+{
+pixman_format_code_t format;
+pixman_indexed_t *indexed;
+pixman_image_t *image;
+int width, height, stride;
+uint32_t *bits;
+pixman_read_mem

[Pixman] [PATCH 1/2] Add a test compositing with the various PDF operators.

2010-12-18 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The test has floating point exceptions enabled, and currently fails
with a divide-by-zero.
---
 test/Makefile.am   |4 ++
 test/pdf-op-test.c |   84 
 2 files changed, 88 insertions(+), 0 deletions(-)
 create mode 100644 test/pdf-op-test.c

diff --git a/test/Makefile.am b/test/Makefile.am
index 52e4183..3d40157 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -6,6 +6,7 @@ INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
 
 TESTPROGRAMS = \
a1-trap-test\
+   pdf-op-test \
region-test \
region-translate-test   \
fetch-test  \
@@ -28,6 +29,9 @@ oob_test_LDADD = $(TEST_LDADD)
 scaling_crash_test_LDADD = $(TEST_LDADD)
 region_translate_test_LDADD = $(TEST_LDADD)
 
+pdf_op_test_LDADD = $(TEST_LDADD)
+pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h
+
 region_test_LDADD = $(TEST_LDADD)
 region_test_SOURCES = region-test.c utils.c utils.h
 
diff --git a/test/pdf-op-test.c b/test/pdf-op-test.c
new file mode 100644
index 000..dc7a4fd
--- /dev/null
+++ b/test/pdf-op-test.c
@@ -0,0 +1,84 @@
+#include 
+#include 
+#include "utils.h"
+
+static const pixman_op_t pdf_ops[] =
+{
+PIXMAN_OP_MULTIPLY,
+PIXMAN_OP_SCREEN,
+PIXMAN_OP_OVERLAY,
+PIXMAN_OP_DARKEN,
+PIXMAN_OP_LIGHTEN,
+PIXMAN_OP_COLOR_DODGE,
+PIXMAN_OP_COLOR_BURN,
+PIXMAN_OP_HARD_LIGHT,
+PIXMAN_OP_SOFT_LIGHT,
+PIXMAN_OP_DIFFERENCE,
+PIXMAN_OP_EXCLUSION,
+PIXMAN_OP_HSL_HUE,
+PIXMAN_OP_HSL_SATURATION,
+PIXMAN_OP_HSL_COLOR,
+PIXMAN_OP_HSL_LUMINOSITY
+};
+
+static const uint32_t pixels[] =
+{
+0x00808080,
+0x80123456,
+0x,
+0x,
+0x00ff,
+0x80808080,
+0x00123456,
+};
+
+int
+main ()
+{
+int o, s, m, d;
+
+enable_fp_exceptions();
+
+for (o = 0; o < ARRAY_LENGTH (pdf_ops); ++o)
+{
+   pixman_op_t op = pdf_ops[o];
+
+   for (s = 0; s < ARRAY_LENGTH (pixels); ++s)
+   {
+   pixman_image_t *src;
+
+   src = pixman_image_create_bits (
+   PIXMAN_a8r8g8b8, 1, 1, (uint32_t *)&(pixels[s]), 4);
+
+   for (m = -1; m < ARRAY_LENGTH (pixels); ++m)
+   {
+   pixman_image_t *msk = NULL;
+   if (m >= 0)
+   {
+   msk = pixman_image_create_bits (
+   PIXMAN_a8r8g8b8, 1, 1, (uint32_t *)&(pixels[m]), 4);
+   }
+
+   for (d = 0; d < ARRAY_LENGTH (pixels); ++d)
+   {
+   pixman_image_t *dst;
+   uint32_t dp = pixels[d];
+
+   dst = pixman_image_create_bits (
+   PIXMAN_a8r8g8b8, 1, 1, &dp, 4);
+
+   pixman_image_composite (op, src, msk, dst,
+   0, 0, 0, 0, 0, 0, 1, 1);
+
+   pixman_image_unref (dst);
+   }
+   if (msk)
+   pixman_image_unref (msk);
+   }
+
+   pixman_image_unref (src);
+   }
+}
+
+return 0;
+}
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 2/2] Fix divide-by-zero in set_lum().

2010-12-18 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

When (l - min) or (max - l) are zero, simply set all the channels to
the limit, 0 in the case of (l - min), and a in the case of (max - l).
---
 pixman/pixman-combine.c.template |   30 --
 1 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template
index 56dfb43..f5dd8e1 100644
--- a/pixman/pixman-combine.c.template
+++ b/pixman/pixman-combine.c.template
@@ -959,15 +959,33 @@ set_lum (comp4_t dest[3], comp4_t src[3], comp4_t sa, 
comp4_t lum)
 
 if (min < 0)
 {
-   tmp[0] = l + (tmp[0] - l) * l / (l - min);
-   tmp[1] = l + (tmp[1] - l) * l / (l - min);
-   tmp[2] = l + (tmp[2] - l) * l / (l - min);
+   if (l - min == 0.0)
+   {
+   tmp[0] = 0;
+   tmp[1] = 0;
+   tmp[2] = 0;
+   }
+   else
+   {
+   tmp[0] = l + (tmp[0] - l) * l / (l - min);
+   tmp[1] = l + (tmp[1] - l) * l / (l - min);
+   tmp[2] = l + (tmp[2] - l) * l / (l - min);
+   }
 }
 if (max > a)
 {
-   tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l);
-   tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l);
-   tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l);
+   if (max - l == 0.0)
+   {
+   tmp[0] = a;
+   tmp[1] = a;
+   tmp[2] = a;
+   }
+   else
+   {
+   tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l);
+   tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l);
+   tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l);
+   }
 }
 
 dest[0] = tmp[0] * MASK + 0.5;
-- 
1.6.0.6

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH] sse2: Skip src pixels that are zero in sse2_composite_over_8888_n_8888()

2010-12-20 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This is a big speed-up in the SVG helicopter game:

   http://ie.microsoft.com/testdrive/Performance/Helicopter/Default.xhtml

when rendered by Firefox 4 since it is compositing big images
consisting almost entirely of zeros.
---
 pixman/pixman-sse2.c |   75 +
 1 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 5907de0..032f13b 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -3051,37 +3051,45 @@ sse2_composite_over__n_ 
(pixman_implementation_t *imp,
while (w && (unsigned long)dst & 15)
{
uint32_t s = *src++;
-   uint32_t d = *dst;
-
-   __m64 ms = unpack_32_1x64 (s);
-   __m64 alpha= expand_alpha_1x64 (ms);
-   __m64 dest = _mm_movepi64_pi64 (xmm_mask);
-   __m64 alpha_dst = unpack_32_1x64 (d);
-
-   *dst++ = pack_1x64_32 (
-   in_over_1x64 (&ms, &alpha, &dest, &alpha_dst));
 
+   if (s)
+   {
+   uint32_t d = *dst;
+   
+   __m64 ms = unpack_32_1x64 (s);
+   __m64 alpha= expand_alpha_1x64 (ms);
+   __m64 dest = _mm_movepi64_pi64 (xmm_mask);
+   __m64 alpha_dst = unpack_32_1x64 (d);
+   
+   *dst = pack_1x64_32 (
+   in_over_1x64 (&ms, &alpha, &dest, &alpha_dst));
+   }
+   dst++;
w--;
}
 
while (w >= 4)
{
xmm_src = load_128_unaligned ((__m128i*)src);
-   xmm_dst = load_128_aligned ((__m128i*)dst);
-
-   unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi);
-   unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi);
-   expand_alpha_2x128 (xmm_src_lo, xmm_src_hi,
-   &xmm_alpha_lo, &xmm_alpha_hi);
-
-   in_over_2x128 (&xmm_src_lo, &xmm_src_hi,
-  &xmm_alpha_lo, &xmm_alpha_hi,
-  &xmm_mask, &xmm_mask,
-  &xmm_dst_lo, &xmm_dst_hi);
-
-   save_128_aligned (
-   (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi));
 
+   if (!is_zero (xmm_src))
+   {
+   xmm_dst = load_128_aligned ((__m128i*)dst);
+   
+   unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi);
+   unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi);
+   expand_alpha_2x128 (xmm_src_lo, xmm_src_hi,
+   &xmm_alpha_lo, &xmm_alpha_hi);
+   
+   in_over_2x128 (&xmm_src_lo, &xmm_src_hi,
+  &xmm_alpha_lo, &xmm_alpha_hi,
+  &xmm_mask, &xmm_mask,
+  &xmm_dst_lo, &xmm_dst_hi);
+   
+   save_128_aligned (
+   (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi));
+   }
+   
dst += 4;
src += 4;
w -= 4;
@@ -3090,16 +3098,21 @@ sse2_composite_over__n_ 
(pixman_implementation_t *imp,
while (w)
{
uint32_t s = *src++;
-   uint32_t d = *dst;
 
-   __m64 ms = unpack_32_1x64 (s);
-   __m64 alpha = expand_alpha_1x64 (ms);
-   __m64 mask  = _mm_movepi64_pi64 (xmm_mask);
-   __m64 dest  = unpack_32_1x64 (d);
-
-   *dst++ = pack_1x64_32 (
-   in_over_1x64 (&ms, &alpha, &mask, &dest));
+   if (s)
+   {
+   uint32_t d = *dst;
+   
+   __m64 ms = unpack_32_1x64 (s);
+   __m64 alpha = expand_alpha_1x64 (ms);
+   __m64 mask  = _mm_movepi64_pi64 (xmm_mask);
+   __m64 dest  = unpack_32_1x64 (d);
+   
+   *dst = pack_1x64_32 (
+   in_over_1x64 (&ms, &alpha, &mask, &dest));
+   }
 
+   dst++;
w--;
}
 }
-- 
1.7.3.1

___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


  1   2   3   4   5   6   7   8   9   >