[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 s...@redhat.com

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 inttypes.h
 #elif defined (_MSC_VER)
@@ -101,6 +104,8 @@ typedef unsigned __int64 uint64_t;
 #  include stdint.h
 #endif
 
+#endif
+
 /*
  * Boolean
  */
-- 
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] Don't use __thread on MinGW.

2010-05-03 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 s...@redhat.com

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 windows.h 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

[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 s...@redhat.com

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 s...@redhat.com

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] bits: Fix potential divide-by-zero in projective code

2010-07-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 s...@redhat.com

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,
region, src, mask, dest,
src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
 {
-   return;
+   goto out;
 }
 
 extents = pixman_region32_extents (region);
@@ -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),
  region, 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] [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 s...@redhat.com

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 y,
+get_pixel_tget_pixel)
 {
 switch (image-common.filter)
 {
 case PIXMAN_FILTER_NEAREST:
 case PIXMAN_FILTER_FAST:
-   return bits_image_fetch_pixel_nearest (image, x, y);
+   return

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

2010-07-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 s...@redhat.com

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_image_t *  image,
  int width,
  const uint32_t *buffer)
 {
-image

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

2010-07-31 Thread Søren Sandmann
From: Brad Smith b...@comstyle.com

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 sys/param.h
+#include sys/sysctl.h
+#include machine/cpu.h
+
+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 sys/types.h
 #include sys/stat.h
@@ -123,7 +146,7 @@ pixman_have_vmx (void)
 return have_vmx;
 }
 
-#else /* !__APPLE__  !__linux__ */
+#else /* !__APPLE__  !__OpenBSD__  !__linux__ */
 #include signal.h
 #include setjmp.h
 
-- 
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 s...@redhat.com

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 s...@redhat.com

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),
- region, 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,
+ dest_x, dest_y,
+ width

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

2010-08-29 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 s...@redhat.com

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 s...@redhat.com

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] Do opacity computation with shifts instead of comparing with 0

2010-09-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 2/5] Update and extend the alphamap test

2010-09-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

- 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 stdlib.h
 #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 unknown - bug in alphamap.c;
+}
+
+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 ((A) [0])))
+
+static int
+run_test (int s, int d, int sa, int da, int soff, int doff)
+{
+pixman_format_code_t sf = formats[s];
+pixman_format_code_t df = formats[d

[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 s...@redhat.com

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
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -379,7 +379,7 @@ compute_image_info (pixman_image_t *image

[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 s...@redhat.com

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 s...@redhat.com

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 sandm...@daimi.au.dk

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] Rename all the fast paths with _8000 in their names to _8

2010-09-22 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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

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

2010-10-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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] Plug leak in the alphamap test.

2010-10-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 unknown - bug in alphamap.c;
 }
 
+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] Delete the source_image_t struct.

2010-10-30 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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;
 
-if (source-common.transform)
+if (image-common.transform)
 {
-   if (!pixman_transform_point_3d (source-common.transform, v))
+   if (!pixman_transform_point_3d (image-common.transform, v))
return

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

2010-12-14 Thread Søren Sandmann
From: Brad Smith b...@comstyle.com

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 sys/param.h
+#include sys/sysctl.h
+#include machine/cpu.h
+
+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 sys/types.h
 #include sys/stat.h
@@ -123,7 +146,7 @@ pixman_have_vmx (void)
 return have_vmx;
 }
 
-#else /* !__APPLE__  !__linux__ */
+#else /* !__APPLE__  !__OpenBSD__  !__linux__ */
 #include signal.h
 #include setjmp.h
 
-- 
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 enable_fp_exceptions() function in utils.[ch]

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 fenv.h])])
+
+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 signal.h
 
@@ -15,6 +17,10 @@
 #include sys/mman.h
 #endif
 
+#ifdef HAVE_FENV_H
+#include fenv.h
+#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] bits: Fix potential divide-by-zero in projective code

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 2/7] Add enable_fp_exceptions() function in utils.[ch]

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 fenv.h])])
+
+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 signal.h
 
@@ -15,6 +17,10 @@
 #include sys/mman.h
 #endif
 
+#ifdef HAVE_FENV_H
+#include fenv.h
+#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 3/7] Extend gradient-crash-test

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 stdio.h
 #include stdlib.h
-#include pixman.h
+#include fenv.h
+#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), 
pixman_double_to_fixed

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

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

---
 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
--- a/test/utils.h
+++ b/test/utils.h
@@ -123,3 +123,6 @@ void enable_fp_exceptions(void);
 /* Try to get an aligned memory chunk */
 void *
 aligned_malloc (size_t align, size_t size);
+
+void
+initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb);
-- 
1.6.0.6

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

2010-12-14 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 1/2] Add a test compositing with the various PDF operators.

2010-12-18 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

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 config.h
+#include stdlib.h
+#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 s...@redhat.com

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 s...@redhat.com

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


[Pixman] [PATCH 03/18] Eliminate the _pixman_image_store_scanline_32/64 functions.

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

They were only called from next_line_write_narrow/wide, so they could
simply be absorbed into those functions.
---
 pixman/pixman-bits-image.c |   79 
 pixman/pixman-private.h|   17 -
 2 files changed, 36 insertions(+), 60 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 33b908a..15a12da 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -35,45 +35,6 @@
 #include pixman-private.h
 #include pixman-combine32.h
 
-/* Store functions */
-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);
-
-if (image-common.alpha_map)
-{
-   x -= image-common.alpha_origin_x;
-   y -= image-common.alpha_origin_y;
-
-   image-common.alpha_map-store_scanline_32 (
-   image-common.alpha_map, 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);
-
-if (image-common.alpha_map)
-{
-   x -= image-common.alpha_origin_x;
-   y -= image-common.alpha_origin_y;
-
-   image-common.alpha_map-store_scanline_64 (
-   image-common.alpha_map, x, y, width, buffer);
-}
-}
-
 /* Fetch functions */
 
 static force_inline uint32_t
@@ -1369,15 +1330,47 @@ get_scanline_wide (pixman_iter_t *iter, const uint32_t 
*mask)
 static void
 next_line_write_narrow (pixman_iter_t *iter)
 {
-_pixman_image_store_scanline_32 (
-   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
+bits_image_t *  image  = iter-image-bits;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+const uint32_t *buffer = iter-buffer;
+
+image-store_scanline_32 (image, x, y, width, buffer);
+
+if (image-common.alpha_map)
+{
+   x -= image-common.alpha_origin_x;
+   y -= image-common.alpha_origin_y;
+
+   image-common.alpha_map-store_scanline_32 (
+   image-common.alpha_map, x, y, width, buffer);
+}
+
+iter-y++;
 }
 
 static void
 next_line_write_wide (pixman_iter_t *iter)
 {
-_pixman_image_store_scanline_64 (
-   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
+bits_image_t *  image  = iter-image-bits;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+const uint32_t *buffer = iter-buffer;
+
+image-store_scanline_64 (image, x, y, width, buffer);
+
+if (image-common.alpha_map)
+{
+   x -= image-common.alpha_origin_x;
+   y -= image-common.alpha_origin_y;
+
+   image-common.alpha_map-store_scanline_64 (
+   image-common.alpha_map, x, y, width, buffer);
+}
+
+iter-y++;
 }
 
 void
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 5e441fe..0511ade 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -254,23 +254,6 @@ _pixman_image_get_scanline_64 (pixman_image_t *image,
uint32_t *  buffer,
const uint32_t *unused);
 
-void
-_pixman_image_store_scanline_32 (bits_image_t *  image,
- int x,
- int y,
- int width,
- const uint32_t *buffer);
-
-/* Even though the type of buffer is uint32_t *, the function
- * actually expects a uint64_t *buffer.
- */
-void
-_pixman_image_store_scanline_64 (bits_image_t *  image,
- int x,
- int y,
- int width,
- const uint32_t *buffer);
-
 pixman_image_t *
 _pixman_image_allocate (void);
 
-- 
1.6.0.6

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


[Pixman] [PATCH 06/18] Add _pixman_radial_gradient_iter_init() and call it from pixman-general.c

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

---
 pixman/pixman-general.c |5 +
 pixman/pixman-private.h |   11 +++
 pixman/pixman-radial-gradient.c |   34 ++
 3 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index a2697ef..5865143 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -91,6 +91,11 @@ iter_init (pixman_implementation_t *imp,
_pixman_linear_gradient_iter_init (
image, iter, x, y, width, height, buffer, flags);
 }
+else if (image-type == RADIAL)
+{
+   _pixman_radial_gradient_iter_init (
+   image, iter, x, y, width, height, buffer, flags);
+}
 else if (image-type == BITS)
 {
_pixman_bits_image_iter_init (
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d22f242..1c6f041 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -232,6 +232,17 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image,
   uint8_t *buffer, iter_flags_t flags);
 
 void
+_pixman_solid_fill_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags);
+void
+_pixman_radial_gradient_iter_init (pixman_image_t *image,
+  pixman_iter_t *iter,
+  int x, int y, int width, int height,
+  uint8_t *buffer, iter_flags_t flags);
+
+void
 _pixman_image_get_scanline_generic_64  (pixman_image_t *image,
 int x,
 int y,
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index b595ba7..9b8c49b 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -377,6 +377,40 @@ radial_gradient_property_changed (pixman_image_t *image)
 image-common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
 }
 
+static uint32_t *
+radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+radial_gradient_get_scanline_32 (
+   iter-image, iter-x, iter-y, iter-width,
+   iter-buffer, mask);
+
+return iter-buffer;
+}
+
+static uint32_t *
+radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+uint32_t *buffer = radial_get_scanline_narrow (iter, NULL);
+
+pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter-width);
+
+return buffer;
+}
+
+void
+_pixman_radial_gradient_iter_init (pixman_image_t *image,
+  pixman_iter_t *iter,
+  int x, int y, int width, int height,
+  uint8_t *buffer, iter_flags_t flags)
+{
+if (flags  ITER_NARROW)
+   iter-get_scanline = radial_get_scanline_narrow;
+else
+   iter-get_scanline = radial_get_scanline_wide;
+
+iter-next_line = _pixman_iter_next_line_regular;
+}
+
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_radial_gradient (pixman_point_fixed_t *inner,
  pixman_point_fixed_t *outer,
-- 
1.6.0.6

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


[Pixman] [PATCH 01/18] Add iterators in the general implementation

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

We add a new structure called a pixman_iter_t that encapsulates the
information required to read scanlines from an image. It contains two
functions, get_scanline() and next_line(), where get_scanline() will
generate pixels for the current scanline, and next_line() will step to
the next scanline.

When the iterator is initialized, it is passed this information:

   - The image to iterate

   - The rectangle to be iterated

   - A buffer that the iterator may use (but is not required to)

   - Flags indicating,
- whether a8r8g8b8 or a16r16g16b16 pixels should be fetched
- whether the pixels should be written back during next_line().

There are a number of (eventual) benefits to the iterators:

   - The initialization of the iterator can be virtualized such that
 implementations can plug in their own CPU specific get_scanline()
 and next_line() functions.

   - If an image is horizontal, it can simply plug in an appropriate
 get_scanline(). This way we can get rid of the annoying
 classify() virtual function.

   - In general, iterators can remember what they did on the last
 scanline, so for example a REPEAT_NONE image might reuse the same
 data for all the empty scanlines generated by the zero-extension.

   - More detailed information can be passed to iterator, allowing
 more specialized fetchers to be used.

   - We can fix the bug where destination filters and transformations
 are not currently being ignored as they should be.

However, this initial implementation is not optimized at all. We lose
several existing optimizations:

   - The ability to composite directly in the destination
   - The ability to only fetch one scanline for horizontal images
   - The ability to avoid fetching the src and mask for the CLEAR
 operator

Later patches will re-introduce these optimizations.
---
 pixman/pixman-general.c |  287 +++
 1 files changed, 140 insertions(+), 147 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 8130f16..05d97cc 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -39,6 +39,112 @@
 #include pixman-combine32.h
 #include pixman-private.h
 
+typedef struct pixman_iter_t pixman_iter_t;
+typedef enum
+{
+ITER_NARROW= (1  0),
+ITER_WRITE =  (1  1)
+} iter_flags_t;
+
+struct pixman_iter_t
+{
+uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask);
+void  (* next_line)(pixman_iter_t *iter);
+
+pixman_image_t *image;
+uint32_t *  buffer;
+int x, y;
+int width;
+};
+
+static uint32_t *
+get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
+{
+return NULL;
+}
+
+static uint32_t *
+get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+_pixman_image_get_scanline_32 (
+   iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
+
+return iter-buffer;
+}
+
+static uint32_t *
+get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+_pixman_image_get_scanline_64 (
+   iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
+
+return iter-buffer;
+}
+
+static void
+next_line_write_narrow (pixman_iter_t *iter)
+{
+_pixman_image_store_scanline_32 (
+   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
+}
+
+static void
+next_line_write_wide (pixman_iter_t *iter)
+{
+_pixman_image_store_scanline_64 (
+   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
+}
+
+static void
+next_line_regular (pixman_iter_t *iter)
+{
+iter-y++;
+}
+
+static void
+next_line_noop (pixman_iter_t *iter)
+{
+}
+
+static void
+iter_init (pixman_implementation_t *imp,
+  pixman_iter_t *iter,
+  pixman_image_t *image,
+  int x, int y, int width, int height,
+  uint8_t *buffer, iter_flags_t flags)
+{
+iter-image = image;
+iter-x = x;
+iter-y = y;
+iter-width = width;
+iter-buffer = (uint32_t *)buffer;
+
+if (!image)
+{
+   iter-get_scanline = get_scanline_null;
+   iter-next_line = next_line_noop;
+}
+else if ((flags  (ITER_NARROW | ITER_WRITE)) == (ITER_NARROW | 
ITER_WRITE))
+{
+   iter-get_scanline = get_scanline_narrow;
+   iter-next_line = next_line_write_narrow;
+}
+else if (flags  ITER_WRITE)
+{
+   iter-get_scanline = get_scanline_wide;
+   iter-next_line = next_line_write_wide;
+}
+else
+{
+   if (flags  ITER_NARROW)
+   iter-get_scanline = get_scanline_narrow;
+   else
+   iter-get_scanline = get_scanline_wide;
+
+   iter-next_line = next_line_regular;
+}
+}
+
 #define SCANLINE_BUFFER_LENGTH 8192
 
 static void
@@ -59,21 +165,25 @@ general_composite_rect  (pixman_implementation_t *imp,
 uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
 uint8_t

[Pixman] [PATCH 10/18] Move get_scanline_32/64 to the bits part of the image struct.

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

At this point these functions are basically a cache that the bits
image uses for its fetchers, so they can be moved to the bits image.

With the scanline getters only being initialized in the bits image,
the _pixman_image_get_scanline_generic_64 can be moved to
pixman-bits-image.c. That gets rid of the final user of
_pixman_image_get_scanline_32/64, so these can be deleted.
---
 pixman/pixman-bits-image.c   |   45 +--
 pixman/pixman-conical-gradient.c |2 -
 pixman/pixman-image.c|   62 --
 pixman/pixman-linear-gradient.c  |2 -
 pixman/pixman-private.h  |   32 ++-
 pixman/pixman-radial-gradient.c  |2 -
 pixman/pixman-solid-fill.c   |2 -
 7 files changed, 44 insertions(+), 103 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 15a12da..9cd8b5a 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -35,6 +35,43 @@
 #include pixman-private.h
 #include pixman-combine32.h
 
+/*
+ * By default, just evaluate the image at 32bpp and expand.  Individual image
+ * types can plug in a better scanline getter if they want to. For example
+ * we  could produce smoother gradients by evaluating them at higher color
+ * depth, but that's a project for the future.
+ */
+static void
+_pixman_image_get_scanline_generic_64 (pixman_image_t * image,
+   int  x,
+   int  y,
+   int  width,
+   uint32_t *   buffer,
+   const uint32_t * mask)
+{
+uint32_t *mask8 = NULL;
+
+/* Contract the mask image, if one exists, so that the 32-bit fetch
+ * function can use it.
+ */
+if (mask)
+{
+   mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
+   if (!mask8)
+   return;
+
+   pixman_contract (mask8, (uint64_t *)mask, width);
+}
+
+/* Fetch the source image into the first half of buffer. */
+image-bits.get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
+
+/* Expand from 32bpp to 64bpp in place. */
+pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
+
+free (mask8);
+}
+
 /* Fetch functions */
 
 static force_inline uint32_t
@@ -1300,8 +1337,8 @@ bits_image_property_changed (pixman_image_t *image)
if ((info-format == format || info-format == PIXMAN_any)  
(info-flags  flags) == info-flags)
{
-   image-common.get_scanline_32 = info-fetch_32;
-   image-common.get_scanline_64 = info-fetch_64;
+   image-bits.get_scanline_32 = info-fetch_32;
+   image-bits.get_scanline_64 = info-fetch_64;
break;
}
 
@@ -1312,7 +1349,7 @@ bits_image_property_changed (pixman_image_t *image)
 static uint32_t *
 get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
 {
-iter-image-common.get_scanline_32 (
+iter-image-bits.get_scanline_32 (
iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
 
 return iter-buffer;
@@ -1321,7 +1358,7 @@ get_scanline_narrow (pixman_iter_t *iter, const uint32_t 
*mask)
 static uint32_t *
 get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
 {
-iter-image-common.get_scanline_64 (
+iter-image-bits.get_scanline_64 (
iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
 
 return iter-buffer;
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 960ef9d..7d16b89 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -159,8 +159,6 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
 static void
 conical_gradient_property_changed (pixman_image_t *image)
 {
-image-common.get_scanline_32 = conical_gradient_get_scanline_32;
-image-common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
 }
 
 static uint32_t *
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 3e17000..566a28f 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -50,43 +50,6 @@ _pixman_init_gradient (gradient_t *  
gradient,
 return TRUE;
 }
 
-/*
- * By default, just evaluate the image at 32bpp and expand.  Individual image
- * types can plug in a better scanline getter if they want to. For example
- * we  could produce smoother gradients by evaluating them at higher color
- * depth, but that's a project for the future.
- */
-void
-_pixman_image_get_scanline_generic_64 (pixman_image_t * image,
-   int  x,
-   int  y,
-   int  width,
-   uint32_t *   buffer

[Pixman] [PATCH 02/18] Move initialization of iterators for bits images to pixman-bits-image.c

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

pixman_iter_t is now defined in pixman-private.h, and iterators for
bits images are being.

The function next_line_regular() is needed in both pixman-general.c
and pixman-bits-image.c, so rename it to
_pixman_iter_next_line_regular() and move it to pixman-utils.
---
 pixman/pixman-bits-image.c |   59 
 pixman/pixman-general.c|   51 +++---
 pixman/pixman-private.h|   26 +++
 pixman/pixman-utils.c  |6 
 4 files changed, 95 insertions(+), 47 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index ff2dde3..33b908a 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1349,6 +1349,65 @@ bits_image_property_changed (pixman_image_t *image)
 }
 
 static uint32_t *
+get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+iter-image-common.get_scanline_32 (
+   iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
+
+return iter-buffer;
+}
+
+static uint32_t *
+get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+iter-image-common.get_scanline_64 (
+   iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
+
+return iter-buffer;
+}
+
+static void
+next_line_write_narrow (pixman_iter_t *iter)
+{
+_pixman_image_store_scanline_32 (
+   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
+}
+
+static void
+next_line_write_wide (pixman_iter_t *iter)
+{
+_pixman_image_store_scanline_64 (
+   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
+}
+
+void
+_pixman_bits_image_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+if ((flags  (ITER_NARROW | ITER_WRITE)) == (ITER_NARROW | ITER_WRITE))
+{
+   iter-get_scanline = get_scanline_narrow;
+   iter-next_line = next_line_write_narrow;
+}
+else if (flags  ITER_WRITE)
+{
+   iter-get_scanline = get_scanline_wide;
+   iter-next_line = next_line_write_wide;
+}
+else
+{
+   if (flags  ITER_NARROW)
+   iter-get_scanline = get_scanline_narrow;
+   else
+   iter-get_scanline = get_scanline_wide;
+
+   iter-next_line = _pixman_iter_next_line_regular;
+}
+}
+
+static uint32_t *
 create_bits (pixman_format_code_t format,
  int  width,
  int  height,
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 05d97cc..a66298a 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -39,24 +39,6 @@
 #include pixman-combine32.h
 #include pixman-private.h
 
-typedef struct pixman_iter_t pixman_iter_t;
-typedef enum
-{
-ITER_NARROW= (1  0),
-ITER_WRITE =  (1  1)
-} iter_flags_t;
-
-struct pixman_iter_t
-{
-uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask);
-void  (* next_line)(pixman_iter_t *iter);
-
-pixman_image_t *image;
-uint32_t *  buffer;
-int x, y;
-int width;
-};
-
 static uint32_t *
 get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
 {
@@ -82,26 +64,6 @@ get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
 }
 
 static void
-next_line_write_narrow (pixman_iter_t *iter)
-{
-_pixman_image_store_scanline_32 (
-   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
-}
-
-static void
-next_line_write_wide (pixman_iter_t *iter)
-{
-_pixman_image_store_scanline_64 (
-   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
-}
-
-static void
-next_line_regular (pixman_iter_t *iter)
-{
-iter-y++;
-}
-
-static void
 next_line_noop (pixman_iter_t *iter)
 {
 }
@@ -124,15 +86,10 @@ iter_init (pixman_implementation_t *imp,
iter-get_scanline = get_scanline_null;
iter-next_line = next_line_noop;
 }
-else if ((flags  (ITER_NARROW | ITER_WRITE)) == (ITER_NARROW | 
ITER_WRITE))
-{
-   iter-get_scanline = get_scanline_narrow;
-   iter-next_line = next_line_write_narrow;
-}
-else if (flags  ITER_WRITE)
+else if (image-type == BITS)
 {
-   iter-get_scanline = get_scanline_wide;
-   iter-next_line = next_line_write_wide;
+   _pixman_bits_image_iter_init (
+   image, iter, x, y, width, height, buffer, flags);
 }
 else
 {
@@ -141,7 +98,7 @@ iter_init (pixman_implementation_t *imp,
else
iter-get_scanline = get_scanline_wide;
 
-   iter-next_line = next_line_regular;
+   iter-next_line = _pixman_iter_next_line_regular;
 }
 }
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 383748a..5e441fe 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -193,10 +193,34

[Pixman] [PATCH 04/18] Add _pixman_linear_gradient_iter_init().

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Call it from pixman-general.c to initialize linear gradient iterators.
---
 pixman/pixman-general.c |5 
 pixman/pixman-linear-gradient.c |   43 +++
 pixman/pixman-private.h |5 
 3 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index a66298a..7ff2dd2 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -86,6 +86,11 @@ iter_init (pixman_implementation_t *imp,
iter-get_scanline = get_scanline_null;
iter-next_line = next_line_noop;
 }
+else if (image-type == LINEAR)
+{
+   _pixman_linear_gradient_iter_init (
+   image, iter, x, y, width, height, buffer, flags);
+}
 else if (image-type == BITS)
 {
_pixman_bits_image_iter_init (
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 1547882..a2de693 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -226,6 +226,49 @@ linear_gradient_property_changed (pixman_image_t *image)
 image-common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
 }
 
+static uint32_t *
+linear_gradient_get_scanline_narrow (pixman_iter_t  *iter,
+const uint32_t *mask)
+{
+pixman_image_t *image  = iter-image;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+uint32_t *  buffer = iter-buffer;
+
+linear_gradient_get_scanline_32 (image, x, y, width, buffer, mask);
+
+return iter-buffer;
+}
+
+static uint32_t *
+linear_gradient_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+uint32_t *buffer = linear_gradient_get_scanline_narrow (iter, NULL);
+
+pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter-width);
+
+return buffer;
+}
+
+void
+_pixman_linear_gradient_iter_init (pixman_image_t *image,
+  pixman_iter_t  *iter,
+  int x,
+  int y,
+  int width,
+  int height,
+  uint8_t*buffer,
+  iter_flags_tflags)
+{
+if (flags  ITER_NARROW)
+   iter-get_scanline = linear_gradient_get_scanline_narrow;
+else
+   iter-get_scanline = linear_gradient_get_scanline_wide;
+
+iter-next_line = _pixman_iter_next_line_regular;
+}
+
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_linear_gradient (pixman_point_fixed_t *p1,
  pixman_point_fixed_t *p2,
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0511ade..0be38ed 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -219,6 +219,11 @@ _pixman_bits_image_iter_init (pixman_image_t *image,
  pixman_iter_t *iter,
  int x, int y, int width, int height,
  uint8_t *buffer, iter_flags_t flags);
+void
+_pixman_linear_gradient_iter_init (pixman_image_t *image,
+  pixman_iter_t  *iter,
+  int x, int y, int width, int height,
+  uint8_t *buffer, iter_flags_t flags);
 
 void
 _pixman_image_get_scanline_generic_64  (pixman_image_t *image,
-- 
1.6.0.6

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


[Pixman] [PATCH 05/18] Add _pixman_solid_fill_iter_init() and call it from pixman-general.c

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Also move next_line_noop() to pixman-utils.c since it is used in both
pixman-solid-fill.c and pixman-general.c
---
 pixman/pixman-general.c|   12 ++--
 pixman/pixman-private.h|   12 
 pixman/pixman-solid-fill.c |   21 +
 pixman/pixman-utils.c  |   11 +++
 4 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 7ff2dd2..a2697ef 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -64,11 +64,6 @@ get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
 }
 
 static void
-next_line_noop (pixman_iter_t *iter)
-{
-}
-
-static void
 iter_init (pixman_implementation_t *imp,
   pixman_iter_t *iter,
   pixman_image_t *image,
@@ -84,7 +79,12 @@ iter_init (pixman_implementation_t *imp,
 if (!image)
 {
iter-get_scanline = get_scanline_null;
-   iter-next_line = next_line_noop;
+   iter-next_line = _pixman_iter_next_line_noop;
+}
+else if (image-type == SOLID)
+{
+   _pixman_solid_fill_iter_init (
+   image, iter, x, y, width, height, buffer, flags);
 }
 else if (image-type == LINEAR)
 {
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0be38ed..d22f242 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -220,6 +220,12 @@ _pixman_bits_image_iter_init (pixman_image_t *image,
  int x, int y, int width, int height,
  uint8_t *buffer, iter_flags_t flags);
 void
+_pixman_solid_fill_iter_init (pixman_image_t *image,
+ pixman_iter_t  *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags);
+
+void
 _pixman_linear_gradient_iter_init (pixman_image_t *image,
   pixman_iter_t  *iter,
   int x, int y, int width, int height,
@@ -541,6 +547,12 @@ _pixman_choose_implementation (void);
 void
 _pixman_iter_next_line_regular (pixman_iter_t *iter);
 
+void
+_pixman_iter_next_line_noop (pixman_iter_t *iter);
+
+uint32_t *
+_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
+
 /* These formats all have depth 0, so they
  * will never clash with any real ones
  */
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 1d911e9..2f06f58 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -76,6 +76,27 @@ solid_fill_property_changed (pixman_image_t *image)
 image-common.get_scanline_64 = solid_fill_get_scanline_64;
 }
 
+void
+_pixman_solid_fill_iter_init (pixman_image_t *image,
+ pixman_iter_t  *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+if (flags  ITER_NARROW)
+{
+   solid_fill_get_scanline_32 (
+   image, x, y, width, (uint32_t *)buffer, NULL);
+}
+else
+{
+   solid_fill_get_scanline_64 (
+   image, x, y, width, (uint32_t *)buffer, NULL);
+}
+
+iter-get_scanline = _pixman_iter_get_scanline_noop;
+iter-next_line = _pixman_iter_next_line_noop;
+}
+
 static uint32_t
 color_to_uint32 (const pixman_color_t *color)
 {
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 630c870..09e4ee0 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -173,6 +173,17 @@ _pixman_iter_next_line_regular (pixman_iter_t *iter)
 iter-y++;
 }
 
+void
+_pixman_iter_next_line_noop (pixman_iter_t *iter)
+{
+}
+
+uint32_t *
+_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
+{
+return iter-buffer;
+}
+
 #define N_TMP_BOXES (16)
 
 pixman_bool_t
-- 
1.6.0.6

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


[Pixman] [PATCH 16/18] Skip fetching pixels when possible

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Add two new iterator flags, ITER_IGNORE_ALPHA and ITER_IGNORE_RGB that
are set when the alpha and rgb values are not needed. If both are set,
then we can skip fetching entirely and just use
_pixman_iter_get_scanline_noop.
---
 pixman/pixman-bits-image.c |   11 +-
 pixman/pixman-general.c|   74 +++
 pixman/pixman-implementation.c |7 
 pixman/pixman-private.h|4 ++-
 4 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index df8d56e..7d588a9 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1444,7 +1444,16 @@ _pixman_bits_image_iter_init (pixman_image_t *image,
}
else
{
-   iter-get_scanline = get_scanline_narrow;
+   if ((flags  (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
+(ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
+   {
+   iter-get_scanline = _pixman_iter_get_scanline_noop;
+   }
+   else
+   {
+   iter-get_scanline = get_scanline_narrow;
+   }
+
iter-next_line = next_line_write_narrow;
}
 }
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 84b52c2..25d1fe4 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -83,6 +83,34 @@ general_iter_init (pixman_implementation_t *imp,
 }
 }
 
+typedef struct op_info_t op_info_t;
+struct op_info_t
+{
+uint8_t src, dst;
+};
+
+#define ITER_IGNORE_BOTH   \
+(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA)
+
+static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
+{
+/* Src   Dst   */
+{ ITER_IGNORE_BOTH,  ITER_IGNORE_BOTH  }, /* CLEAR */
+{ ITER_LOCALIZED_ALPHA,  ITER_IGNORE_BOTH  }, /* SRC */
+{ ITER_IGNORE_BOTH,  ITER_LOCALIZED_ALPHA  }, /* DST */
+{ 0, ITER_LOCALIZED_ALPHA  }, /* OVER */
+{ ITER_LOCALIZED_ALPHA,  0 }, /* OVER_REVERSE */
+{ ITER_LOCALIZED_ALPHA,  ITER_IGNORE_RGB   }, /* IN */
+{ ITER_IGNORE_RGB,   ITER_LOCALIZED_ALPHA  }, /* IN_REVERSE */
+{ ITER_LOCALIZED_ALPHA,  ITER_IGNORE_RGB   }, /* OUT */
+{ ITER_IGNORE_RGB,   ITER_LOCALIZED_ALPHA  }, /* OUT_REVERSE */
+{ 0, 0 }, /* ATOP */
+{ 0, 0 }, /* ATOP_REVERSE */
+{ 0, 0 }, /* XOR */
+{ ITER_LOCALIZED_ALPHA,  ITER_LOCALIZED_ALPHA  }, /* ADD */
+{ 0, 0 }, /* SATURATE */
+};
+
 #define SCANLINE_BUFFER_LENGTH 8192
 
 static void
@@ -106,7 +134,7 @@ general_composite_rect  (pixman_implementation_t *imp,
 pixman_iter_t src_iter, mask_iter, dest_iter;
 pixman_combine_32_func_t compose;
 pixman_bool_t component_alpha;
-iter_flags_t narrow, dest_flags;
+iter_flags_t narrow, src_flags;
 int Bpp;
 int i;
 
@@ -135,39 +163,39 @@ general_composite_rect  (pixman_implementation_t *imp,
 mask_buffer = src_buffer + width * Bpp;
 dest_buffer = mask_buffer + width * Bpp;
 
+/* src iter */
+src_flags = narrow | op_flags[op].src;
+
 _pixman_implementation_iter_init (imp-toplevel, src_iter, src,
  src_x, src_y, width, height,
- src_buffer, narrow);
-
-_pixman_implementation_iter_init (imp-toplevel, mask_iter, mask,
- mask_x, mask_y, width, height,
- mask_buffer, narrow);
-
-if (op == PIXMAN_OP_CLEAR  ||
-   op == PIXMAN_OP_SRC ||
-   op == PIXMAN_OP_DST ||
-   op == PIXMAN_OP_OVER||
-   op == PIXMAN_OP_IN_REVERSE  ||
-   op == PIXMAN_OP_OUT_REVERSE ||
-   op == PIXMAN_OP_ADD)
-{
-   dest_flags = narrow | ITER_WRITE | ITER_LOCALIZED_ALPHA;
-}
-else
+ src_buffer, src_flags);
+
+/* mask iter */
+if ((src_flags  (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
+   (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
 {
-   dest_flags = narrow | ITER_WRITE;
+   /* If it doesn't matter what the source is, then it doesn't matter
+* what the mask is
+*/
+   mask = NULL;
 }
 
-_pixman_implementation_iter_init (imp-toplevel, dest_iter, dest,
- dest_x, dest_y, width, height,
- dest_buffer, dest_flags);
-
 component_alpha =
 mask
 mask-common.type == BITS   
 mask-common.component_alpha
 PIXMAN_FORMAT_RGB (mask-bits.format);
 
+_pixman_implementation_iter_init (
+   imp

[Pixman] [PATCH 18/18] Fix destination fetching.

2011-01-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

When fetching from destinations, we need to ignore transformations,
repeat and filtering. Currently we don't ignore them, which means all
kinds of bad things can happen.

This bug fixes this problem by separating the concepts of source and
destination iterator instead of using the ITER_WRITE flag to indicate
which is which.

Apart from making it simple for destination iterators to plug in
alternate fetchers, this also allows a small optimization where source
iterators no longer have a separate next line call; instead they are
supposed to prepare themselves for the next line in the get_scanline
call.

Destination iterators do now have a separate write_back call that is
supposed to write the pixels back to the destination and prepare the
iterator for the next scanline.
---
 pixman/pixman-bits-image.c   |  107 ++---
 pixman/pixman-conical-gradient.c |3 +-
 pixman/pixman-general.c  |   59 ++--
 pixman/pixman-image.c|2 +-
 pixman/pixman-implementation.c   |   77 +++-
 pixman/pixman-linear-gradient.c  |4 +-
 pixman/pixman-private.h  |   60 -
 pixman/pixman-radial-gradient.c  |3 +-
 pixman/pixman-solid-fill.c   |1 -
 pixman/pixman-utils.c|   11 
 10 files changed, 208 insertions(+), 119 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 7d588a9..4d8c1dc 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1350,7 +1350,7 @@ static uint32_t *
 get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
 {
 iter-image-bits.get_scanline_32 (
-   iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
+   iter-image, iter-x, iter-y++, iter-width, iter-buffer, mask);
 
 return iter-buffer;
 }
@@ -1359,13 +1359,59 @@ static uint32_t *
 get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
 {
 iter-image-bits.get_scanline_64 (
-   iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
+   iter-image, iter-x, iter-y++, iter-width, iter-buffer, mask);
+
+return iter-buffer;
+}
+
+static uint32_t *
+dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+pixman_image_t *image  = iter-image;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+uint32_t * buffer = iter-buffer;
+
+image-bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
+if (image-common.alpha_map)
+{
+   x -= image-common.alpha_origin_x;
+   y -= image-common.alpha_origin_y;
+
+   image-common.alpha_map-fetch_scanline_32 (
+   (pixman_image_t *)image-common.alpha_map,
+   x, y, width, buffer, mask);
+}
+
+return iter-buffer;
+}
+
+static uint32_t *
+dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+bits_image_t *  image  = iter-image-bits;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+uint32_t * buffer = iter-buffer;
+
+image-fetch_scanline_64 (
+   (pixman_image_t *)image, x, y, width, buffer, mask);
+if (image-common.alpha_map)
+{
+   x -= image-common.alpha_origin_x;
+   y -= image-common.alpha_origin_y;
+
+   image-common.alpha_map-fetch_scanline_64 (
+   (pixman_image_t *)image-common.alpha_map, x, y, width, buffer, 
mask);
+}
 
 return iter-buffer;
 }
 
 static void
-next_line_write_narrow (pixman_iter_t *iter)
+write_back_narrow (pixman_iter_t *iter)
 {
 bits_image_t *  image  = iter-image-bits;
 int x  = iter-x;
@@ -1388,7 +1434,7 @@ next_line_write_narrow (pixman_iter_t *iter)
 }
 
 static void
-next_line_write_wide (pixman_iter_t *iter)
+write_back_wide (pixman_iter_t *iter)
 {
 bits_image_t *  image  = iter-image-bits;
 int x  = iter-x;
@@ -1410,25 +1456,19 @@ next_line_write_wide (pixman_iter_t *iter)
 iter-y++;
 }
 
-static uint32_t *
-get_scanline_direct_write (pixman_iter_t *iter, const uint32_t *mask)
-{
-return iter-buffer;
-}
-
 static void
-next_line_direct_write (pixman_iter_t *iter)
+write_back_direct (pixman_iter_t *iter)
 {
 iter-buffer += iter-image-bits.rowstride;
 }
 
 void
-_pixman_bits_image_iter_init (pixman_image_t *image,
- pixman_iter_t *iter,
- int x, int y, int width, int height,
- uint8_t *buffer, iter_flags_t flags)
+_pixman_bits_image_dest_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
 {
-if ((flags  (ITER_NARROW | ITER_WRITE)) == (ITER_NARROW | ITER_WRITE))
+if (flags

[Pixman] [PATCH 03/15] Eliminate the _pixman_image_store_scanline_32/64 functions.

2011-01-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

They were only called from next_line_write_narrow/wide, so they could
simply be absorbed into those functions.
---
 pixman/pixman-bits-image.c |   79 
 pixman/pixman-private.h|   17 -
 2 files changed, 36 insertions(+), 60 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index e0a6645..0c5f4e4 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -35,45 +35,6 @@
 #include pixman-private.h
 #include pixman-combine32.h
 
-/* Store functions */
-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);
-
-if (image-common.alpha_map)
-{
-   x -= image-common.alpha_origin_x;
-   y -= image-common.alpha_origin_y;
-
-   image-common.alpha_map-store_scanline_32 (
-   image-common.alpha_map, 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);
-
-if (image-common.alpha_map)
-{
-   x -= image-common.alpha_origin_x;
-   y -= image-common.alpha_origin_y;
-
-   image-common.alpha_map-store_scanline_64 (
-   image-common.alpha_map, x, y, width, buffer);
-}
-}
-
 /* Fetch functions */
 
 static force_inline uint32_t
@@ -1399,15 +1360,47 @@ dest_get_scanline_wide (pixman_iter_t *iter, const 
uint32_t *mask)
 static void
 dest_write_back_narrow (pixman_iter_t *iter)
 {
-_pixman_image_store_scanline_32 (
-   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
+bits_image_t *  image  = iter-image-bits;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+const uint32_t *buffer = iter-buffer;
+
+image-store_scanline_32 (image, x, y, width, buffer);
+
+if (image-common.alpha_map)
+{
+   x -= image-common.alpha_origin_x;
+   y -= image-common.alpha_origin_y;
+
+   image-common.alpha_map-store_scanline_32 (
+   image-common.alpha_map, x, y, width, buffer);
+}
+
+iter-y++;
 }
 
 static void
 dest_write_back_wide (pixman_iter_t *iter)
 {
-_pixman_image_store_scanline_64 (
-   iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer);
+bits_image_t *  image  = iter-image-bits;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+const uint32_t *buffer = iter-buffer;
+
+image-store_scanline_64 (image, x, y, width, buffer);
+
+if (image-common.alpha_map)
+{
+   x -= image-common.alpha_origin_x;
+   y -= image-common.alpha_origin_y;
+
+   image-common.alpha_map-store_scanline_64 (
+   image-common.alpha_map, x, y, width, buffer);
+}
+
+iter-y++;
 }
 
 void
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 853fb5a..d9d19ce 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -258,23 +258,6 @@ _pixman_image_get_scanline_64 (pixman_image_t *image,
uint32_t *  buffer,
const uint32_t *unused);
 
-void
-_pixman_image_store_scanline_32 (bits_image_t *  image,
- int x,
- int y,
- int width,
- const uint32_t *buffer);
-
-/* Even though the type of buffer is uint32_t *, the function
- * actually expects a uint64_t *buffer.
- */
-void
-_pixman_image_store_scanline_64 (bits_image_t *  image,
- int x,
- int y,
- int width,
- const uint32_t *buffer);
-
 pixman_image_t *
 _pixman_image_allocate (void);
 
-- 
1.6.0.6

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


[Pixman] [PATCH 05/15] Virtualize iterator initialization

2011-01-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Make src_iter_init() and dest_iter_init() virtual methods in the
implementation struct. This allows individual implementations to plug
in their own CPU specific scanline fetchers.
---
 pixman/pixman-general.c|   52 +++
 pixman/pixman-implementation.c |   76 +++-
 pixman/pixman-private.h|   35 ++-
 3 files changed, 131 insertions(+), 32 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 4b837fa..e2f1dc3 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -39,18 +39,12 @@
 #include pixman-combine32.h
 #include pixman-private.h
 
-static uint32_t *
-src_get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
-{
-return NULL;
-}
-
 static void
-src_iter_init (pixman_implementation_t *imp,
-  pixman_iter_t *iter,
-  pixman_image_t *image,
-  int x, int y, int width, int height,
-  uint8_t *buffer, iter_flags_t flags)
+general_src_iter_init (pixman_implementation_t *imp,
+  pixman_iter_t *iter,
+  pixman_image_t *image,
+  int x, int y, int width, int height,
+  uint8_t *buffer, iter_flags_t flags)
 {
 iter-image = image;
 iter-x = x;
@@ -58,11 +52,7 @@ src_iter_init (pixman_implementation_t *imp,
 iter-width = width;
 iter-buffer = (uint32_t *)buffer;
 
-if (!image)
-{
-   iter-get_scanline = src_get_scanline_null;
-}
-else if (image-type == SOLID)
+if (image-type == SOLID)
 {
_pixman_solid_fill_iter_init (
image, iter, x, y, width, height, buffer, flags);
@@ -94,11 +84,11 @@ src_iter_init (pixman_implementation_t *imp,
 }
 
 static void
-dest_iter_init (pixman_implementation_t *imp,
-   pixman_iter_t *iter,
-   pixman_image_t *image,
-   int x, int y, int width, int height,
-   uint8_t *buffer, iter_flags_t flags)
+general_dest_iter_init (pixman_implementation_t *imp,
+   pixman_iter_t *iter,
+   pixman_image_t *image,
+   int x, int y, int width, int height,
+   uint8_t *buffer, iter_flags_t flags)
 {
 iter-image = image;
 iter-x = x;
@@ -169,17 +159,17 @@ general_composite_rect  (pixman_implementation_t *imp,
 mask_buffer = src_buffer + width * Bpp;
 dest_buffer = mask_buffer + width * Bpp;
 
-src_iter_init (imp-toplevel, src_iter, src,
-  src_x, src_y, width, height,
-  src_buffer, narrow);
+_pixman_implementation_src_iter_init (imp-toplevel, src_iter, src,
+ src_x, src_y, width, height,
+ src_buffer, narrow);
 
-src_iter_init (imp-toplevel, mask_iter, mask,
-  mask_x, mask_y, width, height,
-  mask_buffer, narrow);
+_pixman_implementation_src_iter_init (imp-toplevel, mask_iter, mask,
+ mask_x, mask_y, width, height,
+ mask_buffer, narrow);
 
-dest_iter_init (imp-toplevel, dest_iter, dest,
-   dest_x, dest_y, width, height,
-   dest_buffer, narrow);
+_pixman_implementation_dest_iter_init (imp-toplevel, dest_iter, dest,
+  dest_x, dest_y, width, height,
+  dest_buffer, narrow);
 
 component_alpha =
 mask
@@ -272,6 +262,8 @@ _pixman_implementation_create_general (void)
 
 imp-blt = general_blt;
 imp-fill = general_fill;
+imp-src_iter_init = general_src_iter_init;
+imp-dest_iter_init = general_dest_iter_init;
 
 return imp;
 }
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index bc3749e..e633432 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -111,6 +111,36 @@ delegate_fill (pixman_implementation_t *imp,
imp-delegate, bits, stride, bpp, x, y, width, height, xor);
 }
 
+static void
+delegate_src_iter_init (pixman_implementation_t *imp,
+   pixman_iter_t *  iter,
+   pixman_image_t * image,
+   int  x,
+   int  y,
+   int  width,
+   int  height,
+   uint8_t *buffer,
+   iter_flags_t flags)
+{
+_pixman_implementation_src_iter_init (
+   imp-delegate, iter, image, x, y, width, height, buffer, flags);
+}
+
+static void
+delegate_dest_iter_init (pixman_implementation_t *imp,
+pixman_iter_t

[Pixman] [PATCH 06/15] Use an iterator in pixman_image_get_solid().

2011-01-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

This is a step towards getting rid of the
_pixman_image_get_scanline_32/64() functions.
---
 pixman/pixman-arm-common.h |9 ++---
 pixman/pixman-fast-path.c  |   22 +++---
 pixman/pixman-image.c  |   12 +---
 pixman/pixman-mmx.c|   22 +++---
 pixman/pixman-private.h|9 +
 pixman/pixman-sse2.c   |   30 +++---
 6 files changed, 57 insertions(+), 47 deletions(-)

diff --git a/pixman/pixman-arm-common.h b/pixman/pixman-arm-common.h
index 66f448d..372e9f9 100644
--- a/pixman/pixman-arm-common.h
+++ b/pixman/pixman-arm-common.h
@@ -118,7 +118,8 @@ cputype##_composite_##name (pixman_implementation_t *imp,   
\
 int32_tdst_stride;  \
 uint32_t   src; \
 \
-src = _pixman_image_get_solid (src_image, dst_image-bits.format);  \
+src = _pixman_image_get_solid (\
+   imp, src_image, dst_image-bits.format);\
 \
 if ((flags  SKIP_ZERO_SRC)  src == 0)\
return; \
@@ -164,7 +165,8 @@ cputype##_composite_##name (pixman_implementation_t *imp,   
\
 int32_tdst_stride, mask_stride; \
 uint32_t   src; \
 \
-src = _pixman_image_get_solid (src_image, dst_image-bits.format);  \
+src = _pixman_image_get_solid (\
+   imp, src_image, dst_image-bits.format);\
 \
 if ((flags  SKIP_ZERO_SRC)  src == 0)\
return; \
@@ -212,7 +214,8 @@ cputype##_composite_##name (pixman_implementation_t *imp,   
\
 int32_tdst_stride, src_stride;  \
 uint32_t   mask;\
 \
-mask = _pixman_image_get_solid (mask_image, dst_image-bits.format);\
+mask = _pixman_image_get_solid (   \
+   imp, mask_image, dst_image-bits.format);   \
 \
 if ((flags  SKIP_ZERO_MASK)  mask == 0)  \
return; \
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 37dfbae..1d12330 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -188,7 +188,7 @@ fast_composite_in_n_8_8 (pixman_implementation_t *imp,
 int32_t w;
 uint16_t t;
 
-src = _pixman_image_get_solid (src_image, dest_image-bits.format);
+src = _pixman_image_get_solid (imp, src_image, dest_image-bits.format);
 
 srca = src  24;
 
@@ -312,7 +312,7 @@ fast_composite_over_n_8_ (pixman_implementation_t *imp,
 int dst_stride, mask_stride;
 int32_t w;
 
-src = _pixman_image_get_solid (src_image, dst_image-bits.format);
+src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
 srca = src  24;
 if (src == 0)
@@ -370,7 +370,7 @@ fast_composite_add_n___ca (pixman_implementation_t 
*imp,
 int dst_stride, mask_stride;
 int32_t w;
 
-src = _pixman_image_get_solid (src_image, dst_image-bits.format);
+src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
 srca = src  24;
 if (src == 0)
@@ -427,7 +427,7 @@ fast_composite_over_n___ca (pixman_implementation_t 
*imp,
 int dst_stride, mask_stride;
 int32_t w;
 
-src = _pixman_image_get_solid (src_image, dst_image-bits.format);
+src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
 srca = src  24;
 if (src == 0)
@@ -494,7 +494,7 @@ fast_composite_over_n_8_0888 (pixman_implementation_t *imp,
 int dst_stride, mask_stride;
 int32_t w;
 
-src = _pixman_image_get_solid (src_image, dst_image-bits.format);
+src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
 srca = src  24;
 if (src == 0)
@@ -559,7 +559,7 @@ fast_composite_over_n_8_0565 (pixman_implementation_t *imp,
 int dst_stride, mask_stride;
 int32_t w;
 
-src = _pixman_image_get_solid (src_image, dst_image-bits.format);
+src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
 srca

[Pixman] [PATCH 14/15] Turn on testing for destination transformation

2011-01-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

---
 test/alphamap.c |   11 ---
 1 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/test/alphamap.c b/test/alphamap.c
index 9fb8969..554b309 100644
--- a/test/alphamap.c
+++ b/test/alphamap.c
@@ -165,20 +165,17 @@ run_test (int s, int d, int sa, int da, int soff, int 
doff)
 orig_dst = create_image (df, daf, doff, doff);
 dst = create_image (df, daf, doff, doff);
 
-/* Transformations on destinations should be ignored, so just set some
- * random one.
+/* Transformations, repeats and filters on destinations should be ignored,
+ * so just set some random ones.
  */
 pixman_transform_init_identity (t1);
 pixman_transform_scale (t1, NULL, pixman_int_to_fixed (100), 
pixman_int_to_fixed (11));
 pixman_transform_rotate (t1, NULL, pixman_double_to_fixed (0.5), 
pixman_double_to_fixed (0.11));
 pixman_transform_translate (t1, NULL, pixman_int_to_fixed (11), 
pixman_int_to_fixed (17));
 
-#if 0
-/* Unfortunately, this is actually broken at the moment, so we can't
- * actually turn it on
- */
 pixman_image_set_transform (dst, t1);
-#endif
+pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0);
+pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT);
 
 pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst,
0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
-- 
1.6.0.6

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


[Pixman] [PATCH 15/15] Fix destination fetching.

2011-01-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

When fetching from destinations, we need to ignore transformations,
repeat and filtering. Currently we don't ignore them, which means all
kinds of bad things can happen.

This bug fixes this problem by directly calling the scanline fetchers
for destinations instead of going through the full
get_scanline_32/64().
---
 pixman/pixman-bits-image.c |   36 
 1 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index f379bb0..6c43b97 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1379,8 +1379,22 @@ _pixman_bits_image_src_iter_init (pixman_image_t *image,
 static uint32_t *
 dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
 {
-iter-image-bits.get_scanline_32 (
-   iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
+pixman_image_t *image  = iter-image;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+uint32_t * buffer = iter-buffer;
+
+image-bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
+if (image-common.alpha_map)
+{
+   x -= image-common.alpha_origin_x;
+   y -= image-common.alpha_origin_y;
+
+   image-common.alpha_map-fetch_scanline_32 (
+   (pixman_image_t *)image-common.alpha_map,
+   x, y, width, buffer, mask);
+}
 
 return iter-buffer;
 }
@@ -1388,8 +1402,22 @@ dest_get_scanline_narrow (pixman_iter_t *iter, const 
uint32_t *mask)
 static uint32_t *
 dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
 {
-iter-image-bits.get_scanline_64 (
-   iter-image, iter-x, iter-y, iter-width, iter-buffer, mask);
+bits_image_t *  image  = iter-image-bits;
+int x  = iter-x;
+int y  = iter-y;
+int width  = iter-width;
+uint32_t * buffer = iter-buffer;
+
+image-fetch_scanline_64 (
+   (pixman_image_t *)image, x, y, width, buffer, mask);
+if (image-common.alpha_map)
+{
+   x -= image-common.alpha_origin_x;
+   y -= image-common.alpha_origin_y;
+
+   image-common.alpha_map-fetch_scanline_64 (
+   (pixman_image_t *)image-common.alpha_map, x, y, width, buffer, 
mask);
+}
 
 return iter-buffer;
 }
-- 
1.6.0.6

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


[Pixman] [PATCH] Move fallback decisions from implementations into pixman-cpu.c.

2011-01-24 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Instead of having each individual implementation decide which fallback
to use, move it into pixman-cpu.c, where a more global decision can be
made.

This is accomplished by adding a fallback argument to all the
pixman_implementation_create_*() implementations, and then in
_pixman_choose_implementation() pass in the desired fallback.
---
 pixman/pixman-arm-neon.c  |7 +--
 pixman/pixman-arm-simd.c  |5 ++---
 pixman/pixman-cpu.c   |   30 +++---
 pixman/pixman-fast-path.c |5 ++---
 pixman/pixman-mmx.c   |5 ++---
 pixman/pixman-private.h   |   12 ++--
 pixman/pixman-sse2.c  |7 +--
 pixman/pixman-vmx.c   |5 ++---
 8 files changed, 35 insertions(+), 41 deletions(-)

diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index c28c481..7d6c837 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -414,13 +414,8 @@ BIND_COMBINE_U (add)
 BIND_COMBINE_U (out_reverse)
 
 pixman_implementation_t *
-_pixman_implementation_create_arm_neon (void)
+_pixman_implementation_create_arm_neon (pixman_implementation_t *fallback)
 {
-#ifdef USE_ARM_SIMD
-pixman_implementation_t *fallback = _pixman_implementation_create_arm_simd 
();
-#else
-pixman_implementation_t *fallback = 
_pixman_implementation_create_fast_path ();
-#endif
 pixman_implementation_t *imp =
_pixman_implementation_create (fallback, arm_neon_fast_paths);
 
diff --git a/pixman/pixman-arm-simd.c b/pixman/pixman-arm-simd.c
index dc2f471..6bbc109 100644
--- a/pixman/pixman-arm-simd.c
+++ b/pixman/pixman-arm-simd.c
@@ -415,10 +415,9 @@ static const pixman_fast_path_t arm_simd_fast_paths[] =
 };
 
 pixman_implementation_t *
-_pixman_implementation_create_arm_simd (void)
+_pixman_implementation_create_arm_simd (pixman_implementation_t *fallback)
 {
-pixman_implementation_t *general = _pixman_implementation_create_fast_path 
();
-pixman_implementation_t *imp = _pixman_implementation_create (general, 
arm_simd_fast_paths);
+pixman_implementation_t *imp = _pixman_implementation_create (fallback, 
arm_simd_fast_paths);
 
 return imp;
 }
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index 70253d1..0e14ecb 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -576,28 +576,36 @@ pixman_have_sse2 (void)
 pixman_implementation_t *
 _pixman_choose_implementation (void)
 {
-#ifdef USE_SSE2
-if (pixman_have_sse2 ())
-   return _pixman_implementation_create_sse2 ();
-#endif
+pixman_implementation_t *imp;
+
+imp = _pixman_implementation_create_general();
+imp = _pixman_implementation_create_fast_path (imp);
+
 #ifdef USE_MMX
 if (pixman_have_mmx ())
-   return _pixman_implementation_create_mmx ();
+   imp = _pixman_implementation_create_mmx (imp);
 #endif
 
-#ifdef USE_ARM_NEON
-if (pixman_have_arm_neon ())
-   return _pixman_implementation_create_arm_neon ();
+#ifdef USE_SSE2
+if (pixman_have_sse2 ())
+   imp = _pixman_implementation_create_sse2 (imp);
 #endif
+
 #ifdef USE_ARM_SIMD
 if (pixman_have_arm_simd ())
-   return _pixman_implementation_create_arm_simd ();
+   imp = _pixman_implementation_create_arm_simd (imp);
+#endif
+
+#ifdef USE_ARM_NEON
+if (pixman_have_arm_neon ())
+   imp = _pixman_implementation_create_arm_neon (imp);
 #endif
+
 #ifdef USE_VMX
 if (pixman_have_vmx ())
-   return _pixman_implementation_create_vmx ();
+   imp = _pixman_implementation_create_vmx (imp);
 #endif
 
-return _pixman_implementation_create_fast_path ();
+return imp;
 }
 
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 868175f..8c71371 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1926,10 +1926,9 @@ fast_path_fill (pixman_implementation_t *imp,
 }
 
 pixman_implementation_t *
-_pixman_implementation_create_fast_path (void)
+_pixman_implementation_create_fast_path (pixman_implementation_t *fallback)
 {
-pixman_implementation_t *general = _pixman_implementation_create_general 
();
-pixman_implementation_t *imp = _pixman_implementation_create (general, 
c_fast_paths);
+pixman_implementation_t *imp = _pixman_implementation_create (fallback, 
c_fast_paths);
 
 imp-fill = fast_path_fill;
 
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 6daa364..0272347 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -3340,10 +3340,9 @@ mmx_fill (pixman_implementation_t *imp,
 }
 
 pixman_implementation_t *
-_pixman_implementation_create_mmx (void)
+_pixman_implementation_create_mmx (pixman_implementation_t *fallback)
 {
-pixman_implementation_t *general = _pixman_implementation_create_fast_path 
();
-pixman_implementation_t *imp = _pixman_implementation_create (general, 
mmx_fast_paths);
+pixman_implementation_t *imp = _pixman_implementation_create (fallback, 
mmx_fast_paths);
 
 imp-combine_32

[Pixman] [PATCH 1/5] Add a test for over_x888_8_0565 in lowlevel_blt_bench().

2011-01-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

The next few commits will speed this up quite a bit.

Current output:

---
reference memcpy speed = 2217.5MB/s (554.4MP/s for 32bpp fills)
---
over_x888_8_0565 =  L1:  54.67  L2:  54.01  M: 52.33 ( 18.88%)  HT: 37.19  VT: 
35.54  R: 29.40  RT: 13.63 ( 162Kops/s)
---
 test/lowlevel-blt-bench.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/test/lowlevel-blt-bench.c b/test/lowlevel-blt-bench.c
index f7ebb1f..67c845f 100644
--- a/test/lowlevel-blt-bench.c
+++ b/test/lowlevel-blt-bench.c
@@ -618,6 +618,7 @@ tests_tbl[] =
 { over_n_1555,   PIXMAN_a8r8g8b8,1, PIXMAN_OP_OVER,
PIXMAN_null, 0, PIXMAN_a1r5g5b5 },
 { over__0565,PIXMAN_a8r8g8b8,0, PIXMAN_OP_OVER,
PIXMAN_null, 0, PIXMAN_r5g6b5 },
 { over__x888,PIXMAN_a8r8g8b8,0, PIXMAN_OP_OVER,
PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
+{ over_x888_8_0565,  PIXMAN_x8r8g8b8,0, PIXMAN_OP_OVER,
PIXMAN_a8,   0, PIXMAN_r5g6b5 },
 { over_n_8_0565, PIXMAN_a8r8g8b8,1, PIXMAN_OP_OVER,
PIXMAN_a8,   0, PIXMAN_r5g6b5 },
 { over_n_8_1555, PIXMAN_a8r8g8b8,1, PIXMAN_OP_OVER,
PIXMAN_a8,   0, PIXMAN_a1r5g5b5 },
 { over_n_8_, PIXMAN_a8r8g8b8,1, PIXMAN_OP_OVER,
PIXMAN_a8,   0, PIXMAN_a4r4g4b4 },
-- 
1.7.3.1

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


[Pixman] [PATCH 2/5] Add SSE2 fetcher for x8r8g8b8

2011-01-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

New output of lowlevel-blt-bench over_x888_8_0565:

over_x888_8_0565 =  L1:  55.68  L2:  55.11  M: 52.83 ( 19.04%)  HT: 39.62  VT: 
37.70  R: 30.88  RT: 14.62 ( 174Kops/s)

The fetcher is looked up in a table, so that other fetchers can easily
be added.
---
 pixman/pixman-private.h |   18 ++---
 pixman/pixman-sse2.c|   90 +++
 2 files changed, 102 insertions(+), 6 deletions(-)

diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 664260b..f5d0ba1 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -183,6 +183,9 @@ union pixman_image
 };
 
 typedef struct pixman_iter_t pixman_iter_t;
+typedef uint32_t *(* pixman_iter_get_scanline_t) (pixman_iter_t *iter, const 
uint32_t *mask);
+typedef void  (* pixman_iter_write_back_t)   (pixman_iter_t *iter);
+
 typedef enum
 {
 ITER_NARROW =  (1  0),
@@ -209,13 +212,16 @@ typedef enum
 
 struct pixman_iter_t
 {
-uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask);
-void  (* write_back)   (pixman_iter_t *iter);
+pixman_iter_get_scanline_t get_scanline;
+pixman_iter_write_back_t   write_back;
+
+pixman_image_t *   image;
+uint32_t * buffer;
+intx, y;
+intwidth;
 
-pixman_image_t *image;
-uint32_t *  buffer;
-int x, y;
-int width;
+uint8_t *  bits;
+intstride;
 };
 
 void
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index ae55456..10a3dd0 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -5953,6 +5953,94 @@ sse2_fill (pixman_implementation_t *imp,
 return TRUE;
 }
 
+static uint32_t *
+sse2_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask)
+{
+int w = iter-width;
+__m128i ff00 = mask_ff00;
+uint32_t *dst = iter-buffer;
+uint32_t *src = (uint32_t *)iter-bits;
+
+iter-bits += iter-stride;
+
+while (w  ((unsigned long)dst)  0x0f)
+{
+   *dst++ = (*src++) | 0xff00;
+   w--;
+}
+
+while (w = 4)
+{
+   save_128_aligned (
+   (__m128i *)dst, _mm_or_si128 (
+   load_128_unaligned ((__m128i *)src), ff00));
+
+   dst += 4;
+   src += 4;
+   w -= 4;
+}
+
+while (w)
+{
+   *dst++ = (*src++) | 0xff00;
+   w--;
+}
+
+return iter-buffer;
+}
+
+typedef struct
+{
+pixman_format_code_t   format;
+pixman_iter_get_scanline_t get_scanline;
+} fetcher_info_t;
+
+static const fetcher_info_t fetchers[] =
+{
+{ PIXMAN_x8r8g8b8, sse2_fetch_x8r8g8b8 },
+{ PIXMAN_null }
+};
+
+static void
+sse2_src_iter_init (pixman_implementation_t *imp,
+   pixman_iter_t *iter,
+   pixman_image_t *image,
+   int x, int y, int width, int height,
+   uint8_t *buffer, iter_flags_t flags)
+{
+#define FLAGS  \
+(FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM)
+
+if ((flags  ITER_NARROW)  
+   (image-common.flags  FLAGS) == FLAGS  
+   x = 0  y = 0
+   x + width = image-bits.width  
+   y + height = image-bits.height)
+{
+   const fetcher_info_t *f;
+
+   for (f = fetchers[0]; f-format != PIXMAN_null; f++)
+   {
+   if (image-common.extended_format_code == f-format)
+   {
+   uint8_t *b = (uint8_t *)image-bits.bits;
+   int s = image-bits.rowstride * 4;
+
+   iter-bits = b + s * y + x * PIXMAN_FORMAT_BPP (f-format) / 8;
+   iter-stride = s;
+   iter-width = width;
+   iter-buffer = (uint32_t *)buffer;
+
+   iter-get_scanline = f-get_scanline;
+   return;
+   }
+   }
+}
+
+_pixman_implementation_src_iter_init (
+   imp-delegate, iter, image, x, y, width, height, buffer, flags);
+}
+
 #if defined(__GNUC__)  !defined(__x86_64__)  !defined(__amd64__)
 __attribute__((__force_align_arg_pointer__))
 #endif
@@ -6020,6 +6108,8 @@ _pixman_implementation_create_sse2 
(pixman_implementation_t *fallback)
 imp-blt = sse2_blt;
 imp-fill = sse2_fill;
 
+imp-src_iter_init = sse2_src_iter_init;
+
 return imp;
 }
 
-- 
1.7.3.1

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


[Pixman] [PATCH 4/5] Improve performance of sse2_combine_over_u()

2011-01-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Split this function into two, one that has a mask, and one that
doesn't. This is a fairly substantial speed-up in many cases.

New output of lowlevel-blt-bench over_x888_8_0565:

over_x888_8_0565 =  L1:  63.76  L2:  62.75  M: 59.37 ( 21.55%)  HT: 45.89  VT: 
43.55  R: 34.51  RT: 16.80 ( 201Kops/s)
---
 pixman/pixman-sse2.c |  168 ++---
 1 files changed, 130 insertions(+), 38 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index d5ea14b..e28b986 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -610,82 +610,174 @@ combine4 (const __m128i *ps, const __m128i *pm)
 }
 
 static force_inline void
-core_combine_over_u_sse2 (uint32_t*   pd,
-  const uint32_t* ps,
-  const uint32_t* pm,
-  int w)
+core_combine_over_u_sse2_mask (uint32_t *pd,
+  const uint32_t*ps,
+  const uint32_t*pm,
+  intw)
 {
 uint32_t s, d;
 
-__m128i xmm_dst_lo, xmm_dst_hi;
-__m128i xmm_src_lo, xmm_src_hi;
-__m128i xmm_alpha_lo, xmm_alpha_hi;
-
 /* Align dst on a 16-byte boundary */
 while (w  ((unsigned long)pd  15))
 {
d = *pd;
s = combine1 (ps, pm);
 
-   *pd++ = core_combine_over_u_pixel_sse2 (s, d);
+   if (s)
+   *pd = core_combine_over_u_pixel_sse2 (s, d);
+   pd++;
ps++;
-   if (pm)
-   pm++;
+   pm++;
w--;
 }
 
 while (w = 4)
 {
-   /* I'm loading unaligned because I'm not sure about
-* the address alignment.
-*/
-   xmm_src_hi = combine4 ((__m128i*)ps, (__m128i*)pm);
+   __m128i mask = load_128_unaligned ((__m128i *)pm);
 
-   if (is_opaque (xmm_src_hi))
+   if (!is_zero (mask))
{
-   save_128_aligned ((__m128i*)pd, xmm_src_hi);
-   }
-   else if (!is_zero (xmm_src_hi))
-   {
-   xmm_dst_hi = load_128_aligned ((__m128i*) pd);
+   __m128i src;
+   __m128i src_hi, src_lo;
+   __m128i mask_hi, mask_lo;
+   __m128i alpha_hi, alpha_lo;
 
-   unpack_128_2x128 (xmm_src_hi, xmm_src_lo, xmm_src_hi);
-   unpack_128_2x128 (xmm_dst_hi, xmm_dst_lo, xmm_dst_hi);
+   src = load_128_unaligned ((__m128i *)ps);
 
-   expand_alpha_2x128 (
-   xmm_src_lo, xmm_src_hi, xmm_alpha_lo, xmm_alpha_hi);
+   if (is_opaque (_mm_and_si128 (src, mask)))
+   {
+   save_128_aligned ((__m128i *)pd, src);
+   }
+   else
+   {
+   __m128i dst = load_128_aligned ((__m128i *)pd);
+   __m128i dst_hi, dst_lo;
 
-   over_2x128 (xmm_src_lo, xmm_src_hi,
-   xmm_alpha_lo, xmm_alpha_hi,
-   xmm_dst_lo, xmm_dst_hi);
+   unpack_128_2x128 (mask, mask_lo, mask_hi);
+   unpack_128_2x128 (src, src_lo, src_hi);
 
-   /* rebuid the 4 pixel data and save*/
-   save_128_aligned ((__m128i*)pd,
- pack_2x128_128 (xmm_dst_lo, xmm_dst_hi));
+   expand_alpha_2x128 (mask_lo, mask_hi, mask_lo, mask_hi);
+   pix_multiply_2x128 (src_lo, src_hi,
+   mask_lo, mask_hi,
+   src_lo, src_hi);
+
+   unpack_128_2x128 (dst, dst_lo, dst_hi);
+
+   expand_alpha_2x128 (src_lo, src_hi,
+   alpha_lo, alpha_hi);
+
+   over_2x128 (src_lo, src_hi, alpha_lo, alpha_hi,
+   dst_lo, dst_hi);
+
+   save_128_aligned (
+   (__m128i *)pd,
+   pack_2x128_128 (dst_lo, dst_hi));
+   }
}
 
-   w -= 4;
+   pm += 4;
ps += 4;
pd += 4;
-   if (pm)
-   pm += 4;
+   w -= 4;
 }
-
 while (w)
 {
d = *pd;
s = combine1 (ps, pm);
 
-   *pd++ = core_combine_over_u_pixel_sse2 (s, d);
+   if (s)
+   *pd = core_combine_over_u_pixel_sse2 (s, d);
+   pd++;
ps++;
-   if (pm)
-   pm++;
+   pm++;
 
w--;
 }
 }
 
 static force_inline void
+core_combine_over_u_sse2_no_mask (uint32_t * pd,
+ const uint32_t*ps,
+ intw)
+{
+uint32_t s, d;
+
+/* Align dst on a 16-byte boundary */
+while (w  ((unsigned long)pd  15))
+{
+   d = *pd;
+   s = *ps;
+
+   if (s)
+   *pd = core_combine_over_u_pixel_sse2 (s, d);
+   pd++;
+   ps++;
+   w--;
+}
+
+while (w = 4)
+{
+   __m128i src;
+   __m128i src_hi, src_lo, dst_hi, dst_lo;
+   __m128i alpha_hi, alpha_lo;
+
+   src

[Pixman] [PATCH 5/5] Add SSE2 fetcher for 0565

2011-01-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Before:

add_0565_0565 = L1:  61.08  L2:  61.03  M: 60.57 ( 10.95%)  HT: 46.85  VT: 
45.25  R: 39.99  RT: 20.41 ( 233Kops/s)

After:

add_0565_0565 = L1:  77.84  L2:  76.25  M: 75.38 ( 13.71%)  HT: 55.99  VT: 
54.56  R: 45.41  RT: 21.95 ( 255Kops/s)
---
 pixman/pixman-sse2.c |   47 +++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index e28b986..91adc05 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -6082,6 +6082,52 @@ sse2_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t 
*mask)
 }
 
 static uint32_t *
+sse2_fetch_r5g6b5 (pixman_iter_t *iter, const uint32_t *mask)
+{
+int w = iter-width;
+uint32_t *dst = iter-buffer;
+uint16_t *src = (uint16_t *)iter-bits;
+__m128i ff00 = mask_ff00;
+
+iter-bits += iter-stride;
+
+while (w  ((unsigned long)dst)  0x0f)
+{
+   uint16_t s = *src++;
+
+   *dst++ = CONVERT_0565_TO_ (s);
+   w--;
+}
+
+while (w = 8)
+{
+   __m128i lo, hi, s;
+
+   s = _mm_loadu_si128 ((__m128i *)src);
+
+   lo = unpack_565_to_ (_mm_unpacklo_epi16 (s, _mm_setzero_si128 ()));
+   hi = unpack_565_to_ (_mm_unpackhi_epi16 (s, _mm_setzero_si128 ()));
+
+   save_128_aligned ((__m128i *)(dst + 0), _mm_or_si128 (lo, ff00));
+   save_128_aligned ((__m128i *)(dst + 4), _mm_or_si128 (hi, ff00));
+
+   dst += 8;
+   src += 8;
+   w -= 8;
+}
+
+while (w)
+{
+   uint16_t s = *src++;
+
+   *dst++ = CONVERT_0565_TO_ (s);
+   w--;
+}
+
+return iter-buffer;
+}
+
+static uint32_t *
 sse2_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask)
 {
 int w = iter-width;
@@ -6136,6 +6182,7 @@ typedef struct
 static const fetcher_info_t fetchers[] =
 {
 { PIXMAN_x8r8g8b8, sse2_fetch_x8r8g8b8 },
+{ PIXMAN_r5g6b5,   sse2_fetch_r5g6b5 },
 { PIXMAN_a8,   sse2_fetch_a8 },
 { PIXMAN_null }
 };
-- 
1.7.3.1

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


[Pixman] [PATCH 2/3] Add @TESTPROGS_EXTRA_LDFLAGS@ to AM_LDFLAGS

2011-02-10 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Instead of explicitly adding it to each test program.
---
 test/Makefile.am |   18 +-
 1 files changed, 1 insertions(+), 17 deletions(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 92ee8fd..0f03153 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,5 +1,5 @@
 AM_CFLAGS = @OPENMP_CFLAGS@
-AM_LDFLAGS = @OPENMP_CFLAGS@
+AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
 
 TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
@@ -23,61 +23,45 @@ TESTPROGRAMS =  \
composite
 
 a1_trap_test_LDADD = $(TEST_LDADD)
-a1_trap_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 fetch_test_LDADD = $(TEST_LDADD)
-fetch_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 trap_crasher_LDADD = $(TEST_LDADD)
-trap_crasher_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 oob_test_LDADD = $(TEST_LDADD)
-oob_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 scaling_crash_test_LDADD = $(TEST_LDADD)
-scaling_crash_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 region_translate_test_LDADD = $(TEST_LDADD)
-region_translate_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 pdf_op_test_LDADD = $(TEST_LDADD)
-pdf_op_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h
 
 region_test_LDADD = $(TEST_LDADD)
-region_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 region_test_SOURCES = region-test.c utils.c utils.h
 
 blitters_test_LDADD = $(TEST_LDADD)
-blitters_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 blitters_test_SOURCES = blitters-test.c utils.c utils.h
 
 scaling_test_LDADD = $(TEST_LDADD)
-scaling_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 scaling_test_SOURCES = scaling-test.c utils.c utils.h
 
 affine_test_LDADD = $(TEST_LDADD)
-affine_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 affine_test_SOURCES = affine-test.c utils.c utils.h
 
 alphamap_LDADD = $(TEST_LDADD)
-alphamap_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 alphamap_SOURCES = alphamap.c utils.c utils.h
 
 alpha_loop_LDADD = $(TEST_LDADD)
-alpha_loop_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
 
 composite_LDADD = $(TEST_LDADD)
-composite_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 composite_SOURCES = composite.c utils.c utils.h
 
 gradient_crash_test_LDADD = $(TEST_LDADD)
-gradient_crash_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h
 
 stress_test_LDADD = $(TEST_LDADD)
-stress_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 stress_test_SOURCES = stress-test.c utils.c utils.h
 
 # Benchmarks
-- 
1.7.3.1

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


[Pixman] [PATCH 3/3] test/Makefile.am: Move all the TEST_LDADD into a new global LDADD.

2011-02-10 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

This gets rid of a bunch of replicated *_LDADD clauses
---
 test/Makefile.am |   35 +--
 1 files changed, 1 insertions(+), 34 deletions(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 0f03153..3ce466e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,6 @@
 AM_CFLAGS = @OPENMP_CFLAGS@
 AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
-
-TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
+LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
 
 TESTPROGRAMS = \
@@ -22,46 +21,15 @@ TESTPROGRAMS =  \
affine-test \
composite
 
-a1_trap_test_LDADD = $(TEST_LDADD)
-
-fetch_test_LDADD = $(TEST_LDADD)
-
-trap_crasher_LDADD = $(TEST_LDADD)
-
-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
-
-blitters_test_LDADD = $(TEST_LDADD)
 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
-
-alpha_loop_LDADD = $(TEST_LDADD)
 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
-
-stress_test_LDADD = $(TEST_LDADD)
 stress_test_SOURCES = stress-test.c utils.c utils.h
 
 # Benchmarks
@@ -70,7 +38,6 @@ BENCHMARKS =  \
lowlevel-blt-bench
 
 lowlevel_blt_bench_SOURCES = lowlevel-blt-bench.c utils.c utils.h
-lowlevel_blt_bench_LDADD = $(TEST_LDADD)
 
 noinst_PROGRAMS = $(TESTPROGRAMS) $(BENCHMARKS)
 
-- 
1.7.3.1

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


[Pixman] [PATCH 1/3] In delegate_{src, dest}_iter_init() call delegate directly.

2011-03-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

There is no reason to go through
_pixman_implementation_{src,dest}_iter_init(), especially since
_pixman_implementation_src_iter_init() is doing various other checks
that only need to be done once.

Also call delegate-src_iter_init() directly in pixman-sse2.c
---
 pixman/pixman-implementation.c |4 ++--
 pixman/pixman-sse2.c   |2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index adaf9c6..892767e 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -122,7 +122,7 @@ delegate_src_iter_init (pixman_implementation_t *imp,
uint8_t *buffer,
iter_flags_t flags)
 {
-_pixman_implementation_src_iter_init (
+imp-delegate-src_iter_init (
imp-delegate, iter, image, x, y, width, height, buffer, flags);
 }
 
@@ -137,7 +137,7 @@ delegate_dest_iter_init (pixman_implementation_t *imp,
 uint8_t *buffer,
 iter_flags_t flags)
 {
-_pixman_implementation_dest_iter_init (
+imp-delegate-dest_iter_init (
imp-delegate, iter, image, x, y, width, height, buffer, flags);
 }
 
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 696005f..d4a34e9 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -6013,7 +6013,7 @@ sse2_src_iter_init (pixman_implementation_t *imp,
}
 }
 
-_pixman_implementation_src_iter_init (
+imp-delegate-src_iter_init (
imp-delegate, iter, image, x, y, width, height, buffer, flags);
 }
 
-- 
1.6.0.6

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


[Pixman] [PATCH 3/3] Simplify the prototype for iterator initializers.

2011-03-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

All of the information previously passed to the iterator initializers
is now available in the iterator itself, so there is no need to pass
it as arguments anymore.
---
 pixman/pixman-bits-image.c   |   20 +-
 pixman/pixman-conical-gradient.c |7 +---
 pixman/pixman-general.c  |   52 --
 pixman/pixman-implementation.c   |   30 -
 pixman/pixman-linear-gradient.c  |   16 +++
 pixman/pixman-private.h  |   40 ++---
 pixman/pixman-radial-gradient.c  |7 +---
 pixman/pixman-solid-fill.c   |   17 +---
 pixman/pixman-sse2.c |   25 +
 9 files changed, 61 insertions(+), 153 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index a865d71..835ecfb 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1362,12 +1362,9 @@ src_get_scanline_wide (pixman_iter_t *iter, const 
uint32_t *mask)
 }
 
 void
-_pixman_bits_image_src_iter_init (pixman_image_t *image,
- pixman_iter_t *iter,
- int x, int y, int width, int height,
- uint8_t *buffer, iter_flags_t flags)
+_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
 {
-if (flags  ITER_NARROW)
+if (iter-flags  ITER_NARROW)
iter-get_scanline = src_get_scanline_narrow;
 else
iter-get_scanline = src_get_scanline_wide;
@@ -1472,28 +1469,25 @@ dest_write_back_direct (pixman_iter_t *iter)
 }
 
 void
-_pixman_bits_image_dest_iter_init (pixman_image_t *image,
-  pixman_iter_t *iter,
-  int x, int y, int width, int height,
-  uint8_t *buffer, iter_flags_t flags)
+_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
 {
-if (flags  ITER_NARROW)
+if (iter-flags  ITER_NARROW)
 {
if (((image-common.flags 
  (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) ==
 (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) 
(image-bits.format == PIXMAN_a8r8g8b8  ||
 (image-bits.format == PIXMAN_x8r8g8b8 
- (flags  ITER_LOCALIZED_ALPHA
+ (iter-flags  ITER_LOCALIZED_ALPHA
{
-   iter-buffer = image-bits.bits + y * image-bits.rowstride + x;
+   iter-buffer = image-bits.bits + iter-y * image-bits.rowstride + 
iter-x;
 
iter-get_scanline = _pixman_iter_get_scanline_noop;
iter-write_back = dest_write_back_direct;
}
else
{
-   if ((flags  (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
+   if ((iter-flags  (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
(ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
{
iter-get_scanline = _pixman_iter_get_scanline_noop;
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 9d7d2e8..791d4f3 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -171,12 +171,9 @@ conical_get_scanline_wide (pixman_iter_t *iter, const 
uint32_t *mask)
 }
 
 void
-_pixman_conical_gradient_iter_init (pixman_image_t *image,
-   pixman_iter_t *iter,
-   int x, int y, int width, int height,
-   uint8_t *buffer, iter_flags_t flags)
+_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
 {
-if (flags  ITER_NARROW)
+if (iter-flags  ITER_NARROW)
iter-get_scanline = conical_get_scanline_narrow;
 else
iter-get_scanline = conical_get_scanline_wide;
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 1a0fa7c..727affc 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -38,60 +38,30 @@
 #include pixman-private.h
 
 static void
-general_src_iter_init (pixman_implementation_t *imp,
-  pixman_iter_t *iter,
-  pixman_image_t *image,
-  int x, int y, int width, int height,
-  uint8_t *buffer, iter_flags_t flags)
+general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
+pixman_image_t *image = iter-image;
+
 if (image-type == SOLID)
-{
-   _pixman_solid_fill_iter_init (
-   image, iter, x, y, width, height, buffer, flags);
-}
+   _pixman_solid_fill_iter_init (image, iter);
 else if (image-type == LINEAR)
-{
-   _pixman_linear_gradient_iter_init (
-   image, iter, x, y, width, height, buffer, flags);
-}
+   _pixman_linear_gradient_iter_init (image, iter);
 else if (image-type == RADIAL)
-{
-   _pixman_radial_gradient_iter_init (
-   image, iter, x, y

[Pixman] [PATCH 2/3] Fill out parts of iters in _pixman_implementation_{src, dest}_iter_init()

2011-03-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

This makes _pixman_implementation_{src,dest}_iter_init() responsible
for filling parts of the information in the iterators. Specifically,
the information passed as arguments is stored in the iterator.

Also add a height field to pixman_iter_t().
---
 pixman/pixman-general.c|6 --
 pixman/pixman-implementation.c |   16 
 pixman/pixman-private.h|   11 ---
 pixman/pixman-sse2.c   |2 --
 4 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 872fb7e..1a0fa7c 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -44,12 +44,6 @@ general_src_iter_init (pixman_implementation_t *imp,
   int x, int y, int width, int height,
   uint8_t *buffer, iter_flags_t flags)
 {
-iter-image = image;
-iter-x = x;
-iter-y = y;
-iter-width = width;
-iter-buffer = (uint32_t *)buffer;
-
 if (image-type == SOLID)
 {
_pixman_solid_fill_iter_init (
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 892767e..bdd4543 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -274,6 +274,14 @@ _pixman_implementation_src_iter_init 
(pixman_implementation_t  *imp,
  uint8_t   *buffer,
  iter_flags_t   flags)
 {
+iter-image = image;
+iter-buffer = (uint32_t *)buffer;
+iter-x = x;
+iter-y = y;
+iter-width = width;
+iter-height = height;
+iter-flags = flags;
+
 if (!image)
 {
iter-get_scanline = get_scanline_null;
@@ -301,6 +309,14 @@ _pixman_implementation_dest_iter_init 
(pixman_implementation_t *imp,
   uint8_t  *buffer,
   iter_flags_t  flags)
 {
+iter-image = image;
+iter-buffer = (uint32_t *)buffer;
+iter-x = x;
+iter-y = y;
+iter-width = width;
+iter-height = height;
+iter-flags = flags;
+
 (*imp-dest_iter_init) (
imp, iter, image, x, y, width, height, buffer, flags);
 }
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 1473dc4..ea9545f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -212,14 +212,19 @@ typedef enum
 
 struct pixman_iter_t
 {
-pixman_iter_get_scanline_t get_scanline;
-pixman_iter_write_back_t   write_back;
-
+/* These are initialized by _pixman_implementation_{src,dest}_init */
 pixman_image_t *   image;
 uint32_t * buffer;
 intx, y;
 intwidth;
+intheight;
+iter_flags_t   flags;
+
+/* These function pointers are initialized by the implementation */
+pixman_iter_get_scanline_t get_scanline;
+pixman_iter_write_back_t   write_back;
 
+/* These fields are scratch data that implementations can use */
 uint8_t *  bits;
 intstride;
 };
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index d4a34e9..43a6bf2 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -6004,8 +6004,6 @@ sse2_src_iter_init (pixman_implementation_t *imp,
 
iter-bits = b + s * y + x * PIXMAN_FORMAT_BPP (f-format) / 8;
iter-stride = s;
-   iter-width = width;
-   iter-buffer = (uint32_t *)buffer;
 
iter-get_scanline = f-get_scanline;
return;
-- 
1.6.0.6

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


[Pixman] [PATCH] test: Randomize some tests if PIXMAN_RANDOMIZE_TESTS is set

2011-03-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

This patch makes so that composite and stress-test will start from a
random seed if the PIXMAN_RANDOMIZE_TESTS environment variable is
set. Running the test suite in this mode is useful to get more test
coverage.

Also, in stress-test.c make it so that setting the initial seed causes
threads to be turned off. This makes it much easier to see when
something fails.
---
 test/composite.c   |   17 -
 test/stress-test.c |   37 ++---
 test/utils.c   |   10 ++
 test/utils.h   |3 +++
 4 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/test/composite.c b/test/composite.c
index a86e5ed..e6d52b9 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -868,7 +868,7 @@ main (int argc, char **argv)
 {
 #define N_TESTS (8 * 1024 * 1024)
 int result = 0;
-int i;
+uint32_t i;
 
 if (argc  1)
 {
@@ -890,15 +890,22 @@ main (int argc, char **argv)
}
 }
 
+uint32_t seed;
+
+if (getenv (PIXMAN_RANDOMIZE_TESTS))
+   seed = get_random_seed();
+else
+   seed = 1;
+
 #ifdef USE_OPENMP
-#   pragma omp parallel for default(none) shared(result) shared(argv) 
+#   pragma omp parallel for default(none) shared(result, argv, seed)
 #endif
-for (i = 1; i = N_TESTS; ++i)
+for (i = seed; i = N_TESTS; ++i)
 {
if (!result  !run_test (i))
{
-   printf (Test %d failed.\n, i);
-
+   printf (Test 0x%08X failed.\n, i);
+   
result = i;
}
 }
diff --git a/test/stress-test.c b/test/stress-test.c
index 166dc6d..d496f93 100644
--- a/test/stress-test.c
+++ b/test/stress-test.c
@@ -1,4 +1,6 @@
+#include stdio.h
 #include utils.h
+#include sys/types.h
 
 #if 0
 #define fence_malloc malloc
@@ -730,11 +732,17 @@ static const pixman_op_t op_list[] =
 };
 
 static void
-run_test (uint32_t seed)
+run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod)
 {
 pixman_image_t *source, *mask, *dest;
 pixman_op_t op;
 
+if (verbose)
+{
+   if (mod == 0 || (seed % mod) == 0)
+   printf (Seed 0x%08x\n, seed);
+}
+   
 lcg_srand (seed);
 
 source = create_random_image ();
@@ -787,6 +795,7 @@ main (int argc, char **argv)
 uint32_t seed = 1;
 uint32_t n_tests = 0x;
 uint32_t mod = 0;
+pixman_bool_t use_threads = TRUE;
 uint32_t i;
 
 pixman_disable_out_of_bounds_workaround ();
@@ -811,6 +820,7 @@ main (int argc, char **argv)
else if (strcmp (argv[i], -s) == 0  i + 1  argc)
{
get_int (argv[i + 1], seed);
+   use_threads = FALSE;
i++;
}
else if (strcmp (argv[i], -n) == 0  i + 1  argc)
@@ -825,7 +835,7 @@ main (int argc, char **argv)
 
printf (Options:\n\n
-n numberNumber of tests to run\n
-   -s seed  Seed of first test\n
+   -s seed  Seed of first test (ignored if 
PIXMAN_RANDOMIZE_TESTS is set)\n
-v Print out seeds\n
-v n Print out every n'th seed\n\n);
 
@@ -836,19 +846,24 @@ main (int argc, char **argv)
 if (n_tests == 0x)
n_tests = 8000;
 
-/* FIXME: seed 2005763 fails in set_lum() with divide by zero */
+if (getenv (PIXMAN_RANDOMIZE_TESTS))
+{
+   seed = get_random_seed();
+   printf (First seed: 0x%08x\n, seed);
+}
+
+if (use_threads)
+{
 #ifdef USE_OPENMP
 #   pragma omp parallel for default(none) shared(verbose, n_tests, mod, seed)
 #endif
-for (i = seed; i  seed + n_tests; ++i)
+   for (i = seed; i  seed + n_tests; ++i)
+   run_test (i, verbose, mod);
+}
+else
 {
-   if (verbose)
-   {
-   if (mod == 0 || (i % mod) == 0)
-   printf (Seed %d\n, i);
-   }
-
-   run_test (i);
+   for (i = seed; i  seed + n_tests; ++i)
+   run_test (i, verbose, mod);
 }
 
 return 0;
diff --git a/test/utils.c b/test/utils.c
index 4bf02e1..56701c4 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -455,6 +455,16 @@ gettime (void)
 #endif
 }
 
+uint32_t
+get_random_seed (void)
+{
+double d = gettime();
+
+lcg_srand (*(uint32_t *)d);
+
+return lcg_rand_u32 ();
+}
+
 static const char *global_msg;
 
 static void
diff --git a/test/utils.h b/test/utils.h
index a5183f7..615ad78 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -79,6 +79,9 @@ make_random_bytes (int n_bytes);
 double
 gettime (void);
 
+uint32_t
+get_random_seed (void);
+
 /* main body of the fuzzer test */
 int
 fuzzer_test_main (const char *test_name,
-- 
1.7.4

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


[Pixman] [PATCH 1/3] mmx: Delete some unused variables

2011-05-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen ssp@hp-sandybridge.(none)

---
 pixman/pixman-mmx.c |   17 +++--
 1 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 0272347..62a73d6 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -1267,7 +1267,7 @@ mmx_composite_over_n___ca 
(pixman_implementation_t *imp,
int32_t  width,
int32_t  height)
 {
-uint32_t src, srca;
+uint32_t src;
 uint32_t*dst_line;
 uint32_t*mask_line;
 int dst_stride, mask_stride;
@@ -1277,7 +1277,6 @@ mmx_composite_over_n___ca 
(pixman_implementation_t *imp,
 
 src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
-srca = src  24;
 if (src == 0)
return;
 
@@ -1377,7 +1376,6 @@ mmx_composite_over__n_ (pixman_implementation_t 
*imp,
 __m64 vmask;
 int dst_stride, src_stride;
 int32_t w;
-__m64 srca;
 
 CHECKPOINT ();
 
@@ -1388,7 +1386,6 @@ mmx_composite_over__n_ (pixman_implementation_t 
*imp,
 mask = 0xff00;
 mask = mask | mask  8 | mask  16 | mask  24;
 vmask = load (mask);
-srca = MC (4x00ff);
 
 while (height--)
 {
@@ -2033,7 +2030,7 @@ mmx_composite_src_n_8_ (pixman_implementation_t *imp,
 uint8_t *mask_line, *mask;
 int dst_stride, mask_stride;
 int32_t w;
-__m64 vsrc, vsrca;
+__m64 vsrc;
 uint64_t srcsrc;
 
 CHECKPOINT ();
@@ -2055,7 +2052,6 @@ mmx_composite_src_n_8_ (pixman_implementation_t *imp,
 PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, 
mask_line, 1);
 
 vsrc = load (src);
-vsrca = expand_alpha (vsrc);
 
 while (height--)
 {
@@ -2101,11 +2097,8 @@ mmx_composite_src_n_8_ (pixman_implementation_t *imp,
}
else if (m0 | m1)
{
-   __m64 vdest;
__m64 dest0, dest1;
 
-   vdest = *(__m64 *)dst;
-
dest0 = in (vsrc, expand_alpha_rev (to_m64 (m0)));
dest1 = in (vsrc, expand_alpha_rev (to_m64 (m1)));
 
@@ -2524,7 +2517,7 @@ mmx_composite_over_n__0565_ca 
(pixman_implementation_t *imp,
int32_t  width,
int32_t  height)
 {
-uint32_t src, srca;
+uint32_t src;
 uint16_t*dst_line;
 uint32_t*mask_line;
 int dst_stride, mask_stride;
@@ -2534,7 +2527,6 @@ mmx_composite_over_n__0565_ca 
(pixman_implementation_t *imp,
 
 src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
-srca = src  24;
 if (src == 0)
return;
 
@@ -2663,12 +2655,9 @@ mmx_composite_in_n_8_8 (pixman_implementation_t *imp,
{
while (w = 4)
{
-   uint32_t m;
__m64 vmask;
__m64 vdest;
 
-   m = 0;
-
vmask = load (*(uint32_t *)mask);
vdest = load (*(uint32_t *)dst);
 
-- 
1.7.4

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


[Pixman] [PATCH 2/3] sse2: Delete some unused variables

2011-05-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen ssp@hp-sandybridge.(none)

---
 pixman/pixman-mmx.c  |2 +-
 pixman/pixman-sse2.c |   18 --
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 62a73d6..0185df6 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -2660,7 +2660,7 @@ mmx_composite_in_n_8_8 (pixman_implementation_t *imp,
 
vmask = load (*(uint32_t *)mask);
vdest = load (*(uint32_t *)dst);
-
+   
*(uint32_t *)dst = store (in (in (vsrca, vmask), vdest));
 
dst += 4;
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 533b858..1fd66bf 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -2537,20 +2537,19 @@ sse2_composite_add_n___ca 
(pixman_implementation_t *imp,
   int32_t  width,
   int32_t  height)
 {
-uint32_t src, srca;
+uint32_t src;
 uint32_t*dst_line, d;
 uint32_t*mask_line, m;
 uint32_t pack_cmp;
 int dst_stride, mask_stride;
 
-__m128i xmm_src, xmm_alpha;
+__m128i xmm_src;
 __m128i xmm_dst;
 __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi;
 
-__m128i mmx_src, mmx_alpha, mmx_mask, mmx_dest;
+__m128i mmx_src, mmx_mask, mmx_dest;
 
 src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
-srca = src  24;
 
 if (src == 0)
return;
@@ -2562,9 +2561,7 @@ sse2_composite_add_n___ca 
(pixman_implementation_t *imp,
 
 xmm_src = _mm_unpacklo_epi8 (
create_mask_2x32_128 (src, src), _mm_setzero_si128 ());
-xmm_alpha = expand_alpha_1x128 (xmm_src);
 mmx_src   = xmm_src;
-mmx_alpha = xmm_alpha;
 
 while (height--)
 {
@@ -3628,7 +3625,7 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t 
*imp,
   int32_t  width,
   int32_t  height)
 {
-uint32_t src, srca;
+uint32_t src;
 uint16_t*dst_line, *dst, d;
 uint8_t *mask_line, *mask;
 int dst_stride, mask_stride;
@@ -3642,7 +3639,6 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t 
*imp,
 
 src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
-srca = src  24;
 if (src == 0)
return;
 
@@ -4143,7 +4139,6 @@ sse2_composite_in_n_8_8 (pixman_implementation_t *imp,
 int dst_stride, mask_stride;
 uint32_t d, m;
 uint32_t src;
-uint8_t sa;
 int32_t w;
 
 __m128i xmm_alpha;
@@ -4157,8 +4152,6 @@ sse2_composite_in_n_8_8 (pixman_implementation_t *imp,
 
 src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
-sa = src  24;
-
 xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src));
 
 while (height--)
@@ -4415,7 +4408,6 @@ sse2_composite_add_n_8_8 (pixman_implementation_t *imp,
 int dst_stride, mask_stride;
 int32_t w;
 uint32_t src;
-uint8_t sa;
 uint32_t m, d;
 
 __m128i xmm_alpha;
@@ -4429,8 +4421,6 @@ sse2_composite_add_n_8_8 (pixman_implementation_t *imp,
 
 src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format);
 
-sa = src  24;
-
 xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src));
 
 while (height--)
-- 
1.7.4

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


[Pixman] [PATCH 3/3] demos: Comment out some unused variables

2011-05-28 Thread Søren Sandmann
From: Søren Sandmann Pedersen ssp@hp-sandybridge.(none)

---
 demos/alpha-test.c|4 +++-
 demos/gradient-test.c |4 
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/demos/alpha-test.c b/demos/alpha-test.c
index 92c2081..54e30fa 100644
--- a/demos/alpha-test.c
+++ b/demos/alpha-test.c
@@ -40,10 +40,12 @@ main (int argc, char **argv)
 };
 #endif
 
+#if 0
 pixman_point_fixed_t c_inner;
 pixman_point_fixed_t c_outer;
 pixman_fixed_t r_inner;
 pixman_fixed_t r_outer;
+#endif
 
 for (i = 0; i  WIDTH * HEIGHT; ++i)
alpha[i] = 0x4f4f; /* pale blue */
@@ -69,6 +71,7 @@ main (int argc, char **argv)
src,
WIDTH * 4);
 
+#if 0
 c_inner.x = pixman_double_to_fixed (50.0);
 c_inner.y = pixman_double_to_fixed (50.0);
 c_outer.x = pixman_double_to_fixed (50.0);
@@ -76,7 +79,6 @@ main (int argc, char **argv)
 r_inner = 0;
 r_outer = pixman_double_to_fixed (50.0);
 
-#if 0
 grad_img = pixman_image_create_conical_gradient (c_inner, r_inner,
stops, 2);
 #endif
diff --git a/demos/gradient-test.c b/demos/gradient-test.c
index fc84844..20f78a6 100644
--- a/demos/gradient-test.c
+++ b/demos/gradient-test.c
@@ -36,10 +36,12 @@ main (int argc, char **argv)
 };
 #endif
 
+#if 0
 pixman_point_fixed_t c_inner;
 pixman_point_fixed_t c_outer;
 pixman_fixed_t r_inner;
 pixman_fixed_t r_outer;
+#endif
 
 for (i = 0; i  WIDTH * HEIGHT; ++i)
dest[i] = 0x4f4f; /* pale blue */
@@ -49,6 +51,7 @@ main (int argc, char **argv)
 dest,
 WIDTH * 4);
 
+#if 0
 c_inner.x = pixman_double_to_fixed (50.0);
 c_inner.y = pixman_double_to_fixed (50.0);
 c_outer.x = pixman_double_to_fixed (50.0);
@@ -58,6 +61,7 @@ main (int argc, char **argv)
 
 src_img = pixman_image_create_conical_gradient (c_inner, r_inner,
stops, 2);
+#endif
 #if 0
 src_img = pixman_image_create_conical_gradient (c_inner, r_inner,
stops, 2);
-- 
1.7.4

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


[Pixman] [PATCH 2/2] ARM: Fix two bugs in neon_composite_over_n_8888_0565_ca().

2011-06-20 Thread Søren Sandmann
The first bug is that a vmull.u8 instruction would store its result in
the q1 register, clobbering the d2 register used later on. The second
is that a vraddhn instruction would overwrite d25, corrupting the q12
register used later.

Fixing the second bug caused a pipeline bubble where the d18 register
would be unavailable for a clock cycle. This is fixed by swapping the
instruction with its successor.
---
 pixman/pixman-arm-neon-asm.S |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/pixman/pixman-arm-neon-asm.S b/pixman/pixman-arm-neon-asm.S
index 833f18c..7cddf7e 100644
--- a/pixman/pixman-arm-neon-asm.S
+++ b/pixman/pixman-arm-neon-asm.S
@@ -1514,11 +1514,11 @@ generate_composite_function \
  * output: updated src in   {d0,  d1,  d2 }   [B, G, R]
  * updated mask in  {d24, d25, d26}   [B, G, R]
  */
-vmull.u8q1,  d25, d9
+vmull.u8q6,  d26, d10
 vqadd.u8q8,  q0, q8
 vmull.u8q0,  d24, d8
 vqadd.u8d22, d2, d22
-vmull.u8q6,  d26, d10
+vmull.u8q1,  d25, d9
 /*
  * convert the result in d16, d17, d22 to r5g6b5 and store
  * it into {d28, d29}
@@ -1541,6 +1541,7 @@ generate_composite_function \
 vrshr.u16   q11, q12, #8
 vrshr.u16   q8,  q9,  #8
 vrshr.u16   q6,  q13, #8
+vraddhn.u16 d24, q12, q11
 vraddhn.u16 d25, q9,  q8
 /*
  * convert 8 r5g6b5 pixel data from {d4, d5} to planar
@@ -1549,11 +1550,10 @@ generate_composite_function \
  */
 vshrn.u16   d17, q2,  #3
 vshrn.u16   d18, q2,  #8
-vraddhn.u16 d24, q12, q11
 vraddhn.u16 d26, q13, q6
 vsli.u16q2,  q2,  #5
-vsri.u8 d18, d18, #5
 vsri.u8 d17, d17, #6
+vsri.u8 d18, d18, #5
 /*
  * 'combine_over_ca' replacement
  *
-- 
1.6.0.6

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


[Pixman] [PATCH 1/2] blitters-test: Make common formats more likely to be tested.

2011-06-20 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Move the eight most common formats to the top of the list of image
formats and make create_random_image() much more likely to select one
of those eight formats.

This should help catch more bugs in SIMD optimized operations.
---
 test/blitters-test.c |   22 ++
 1 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/test/blitters-test.c b/test/blitters-test.c
index 3ecfb09..594ec54 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -14,6 +14,11 @@
 static pixman_indexed_t rgb_palette[9];
 static pixman_indexed_t y_palette[9];
 
+/* The first eight format in the list are by far the most widely
+ * used formats, so we test those more than the others
+ */
+#define N_MOST_LIKELY_FORMATS 8
+
 /* Create random image for testing purposes */
 static pixman_image_t *
 create_random_image (pixman_format_code_t *allowed_formats,
@@ -29,6 +34,9 @@ create_random_image (pixman_format_code_t *allowed_formats,
 
 while (allowed_formats[n] != PIXMAN_null)
n++;
+
+if (n  N_MOST_LIKELY_FORMATS  lcg_rand_n (4) != 0)
+   n = N_MOST_LIKELY_FORMATS;
 fmt = allowed_formats[lcg_rand_n (n)];
 
 width = lcg_rand_n (max_width) + 1;
@@ -177,12 +185,14 @@ static pixman_op_t op_list[] = {
 
 static pixman_format_code_t img_fmt_list[] = {
 PIXMAN_a8r8g8b8,
+PIXMAN_a8b8g8r8,
 PIXMAN_x8r8g8b8,
+PIXMAN_x8b8g8r8,
 PIXMAN_r5g6b5,
-PIXMAN_r3g3b2,
+PIXMAN_b5g6r5,
 PIXMAN_a8,
-PIXMAN_a8b8g8r8,
-PIXMAN_x8b8g8r8,
+PIXMAN_a1,
+PIXMAN_r3g3b2,
 PIXMAN_b8g8r8a8,
 PIXMAN_b8g8r8x8,
 PIXMAN_r8g8b8a8,
@@ -190,8 +200,6 @@ static pixman_format_code_t img_fmt_list[] = {
 PIXMAN_x14r6g6b6,
 PIXMAN_r8g8b8,
 PIXMAN_b8g8r8,
-PIXMAN_r5g6b5,
-PIXMAN_b5g6r5,
 PIXMAN_x2r10g10b10,
 PIXMAN_a2r10g10b10,
 PIXMAN_x2b10g10r10,
@@ -204,7 +212,6 @@ static pixman_format_code_t img_fmt_list[] = {
 PIXMAN_x4r4g4b4,
 PIXMAN_a4b4g4r4,
 PIXMAN_x4b4g4r4,
-PIXMAN_a8,
 PIXMAN_r3g3b2,
 PIXMAN_b2g3r3,
 PIXMAN_a2r2g2b2,
@@ -222,7 +229,6 @@ static pixman_format_code_t img_fmt_list[] = {
 PIXMAN_b1g2r1,
 PIXMAN_a1r1g1b1,
 PIXMAN_a1b1g1r1,
-PIXMAN_a1,
 PIXMAN_null
 };
 
@@ -417,6 +423,6 @@ main (int argc, const char *argv[])
 }
 
 return fuzzer_test_main(blitters, 200,
-   0x265CDFEB,
+   0xB610300B,
test_composite, argc, argv);
 }
-- 
1.6.0.6

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


[Pixman] Speed up pixman_region_contains_{rectangle,point}

2011-08-03 Thread Søren Sandmann
This patch series contains a speed-up for the two functions
pixman_region_contains_rectangle() and pixman_region_contains_point().

The main usecase is when you select some text in Firefox and drag it,
a shaped window with a complicated shape will be created, and the X
server will call pixman_region_contains_rectangle() a bunch of times
on each mouse movement.

The speed up is to use a binary search to look for the first rectangle
in the region that could possible intersect the searched-for rectangle.

There is also a regression test to verify that nothing broke, and a
bug fix for lcg_rand_u32() which only generated 30 random bits, not
32.

Soren

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


[Pixman] [PATCH 4/4] Use find_box_for_y in pixman_region_contains_point() too

2011-08-03 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

The same binary search from the previous commit can be used in this
function too.
---
 pixman/pixman-region.c |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index a199405..35fefc4 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -2376,9 +2376,12 @@ PREFIX (_contains_point) (region_type_t * region,
 return(TRUE);
 }
 
-for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
-pbox != pbox_end;
-pbox++)
+pbox = PIXREGION_BOXPTR (region);
+pbox_end = pbox + numRects;
+
+pbox = find_box_for_y (pbox, pbox_end, y);
+
+for (;pbox != pbox_end; pbox++)
 {
 if (y = pbox-y2)
continue;   /* not there yet */
-- 
1.7.4

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


[Pixman] [PATCH 2/4] New test of pixman_region_contains_{rectangle, point}

2011-08-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

This test generates random regions and checks whether random boxes and
points are contained within them. The results are combined and a CRC32
value is computed and compared to a known-correct one.
---
 test/Makefile.am|2 +
 test/region-contains-test.c |  169 +++
 test/utils.c|   11 +++-
 test/utils.h|4 +
 4 files changed, 184 insertions(+), 2 deletions(-)
 create mode 100644 test/region-contains-test.c

diff --git a/test/Makefile.am b/test/Makefile.am
index 9dc7219..9f61fc9 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -15,6 +15,7 @@ TESTPROGRAMS =\
scaling-crash-test  \
scaling-helpers-test\
gradient-crash-test \
+   region-contains-test\
alphamap\
stress-test \
composite-traps-test\
@@ -26,6 +27,7 @@ TESTPROGRAMS =\
 pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h
 region_test_SOURCES = region-test.c utils.c utils.h
 blitters_test_SOURCES = blitters-test.c utils.c utils.h
+region_contains_test_SOURCES = region-contains-test.c utils.c utils.h
 composite_traps_test_SOURCES = composite-traps-test.c utils.c utils.h
 scaling_test_SOURCES = scaling-test.c utils.c utils.h
 affine_test_SOURCES = affine-test.c utils.c utils.h
diff --git a/test/region-contains-test.c b/test/region-contains-test.c
new file mode 100644
index 000..d1cb1d8
--- /dev/null
+++ b/test/region-contains-test.c
@@ -0,0 +1,169 @@
+#include assert.h
+#include stdlib.h
+#include stdio.h
+#include utils.h
+
+static void
+make_random_region (pixman_region32_t *region)
+{
+int n_boxes;
+
+pixman_region32_init (region);
+
+n_boxes = lcg_rand_n (64);
+while (n_boxes--)
+{
+   int32_t x1, y1, x2, y2;
+
+   x1 = (int32_t)lcg_rand_u32();
+   y1 = (int32_t)lcg_rand_u32();
+   x2 = (int32_t)lcg_rand_u32();
+   y2 = (int32_t)lcg_rand_u32();
+
+   pixman_region32_union_rect (region, region, x1, y1, x2, y2);
+}
+}
+
+static void
+print_box (pixman_box32_t *box)
+{
+printf (%d %d %d %d\n, box-x1, box-y1, box-x2, box-y2);
+}
+
+static int32_t
+random_coord (pixman_region32_t *region, pixman_bool_t x)
+{
+pixman_box32_t *b, *bb;
+int n_boxes;
+int begin, end;
+
+if (lcg_rand_n (14))
+{
+   bb = pixman_region32_rectangles (region, n_boxes);
+   if (n_boxes == 0)
+   goto use_extent;
+   b = bb + lcg_rand_n (n_boxes);
+}
+else
+{
+use_extent:
+   b = pixman_region32_extents (region);
+   n_boxes = 1;
+}
+
+if (x)
+{
+   begin = b-x1;
+   end = b-x2;
+}
+else
+{
+   begin = b-y1;
+   end = b-y2;
+}
+
+switch (lcg_rand_n (5))
+{
+case 0:
+   return begin - lcg_rand_u32();
+case 1:
+   return end + lcg_rand_u32 ();
+case 2:
+   return end;
+case 3:
+   return begin;
+default:
+   return (begin + end) / 2;
+}
+return 0;
+}
+
+static uint32_t
+compute_crc32_u32 (uint32_t crc32, uint32_t v)
+{
+if (!is_little_endian())
+{
+   v = ((v  0xff00)  24)|
+   ((v  0x00ff)  8) |
+   ((v  0xff00)  8) |
+   ((v  0x00ff)  24);
+}
+
+return compute_crc32 (crc32, v, sizeof (int32_t));
+}
+
+static uint32_t
+crc32_box32 (uint32_t crc32, pixman_box32_t *box)
+{
+crc32 = compute_crc32_u32 (crc32, box-x1);
+crc32 = compute_crc32_u32 (crc32, box-y1);
+crc32 = compute_crc32_u32 (crc32, box-x2);
+crc32 = compute_crc32_u32 (crc32, box-y2);
+
+return crc32;
+}
+
+static uint32_t
+test_region_contains_rectangle (int i, int verbose)
+{
+pixman_box32_t box;
+pixman_box32_t rbox = { 0, 0, 0, 0 };
+pixman_region32_t region;
+uint32_t r, r1, r2, r3, r4, crc32;
+
+lcg_srand (i);
+
+make_random_region (region);
+
+box.x1 = random_coord (region, TRUE);
+box.x2 = box.x1 + lcg_rand_u32 ();
+box.y1 = random_coord (region, FALSE);
+box.y2 = box.y1 + lcg_rand_u32 ();
+
+if (verbose)
+{
+   int n_rects;
+   pixman_box32_t *boxes;
+
+   boxes = pixman_region32_rectangles (region, n_rects);
+   
+   printf (region:\n);
+   while (n_rects--)
+   print_box (boxes++);
+   printf (box:\n);
+   print_box (box);
+}
+
+crc32 = 0;
+
+r1 = pixman_region32_contains_point (region, box.x1, box.y1, rbox);
+crc32 = crc32_box32 (crc32, rbox);
+r2 = pixman_region32_contains_point (region, box.x1, box.y2, rbox);
+crc32 = crc32_box32 (crc32, rbox);
+r3 = pixman_region32_contains_point (region, box.x2, box.y1, rbox);
+crc32 = crc32_box32 (crc32, rbox);
+r4 = pixman_region32_contains_point (region, box.x2, box.y2, rbox);
+crc32 = crc32_box32 (crc32, rbox);
+
+r

[Pixman] [PATCH 4/4] Use find_box_for_y() in pixman_region_contains_point() too

2011-08-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

The same binary search from the previous commit can be used in this
function too.

V2: Remove check from loop that is not needed anymore, pointed out by
Andrea Canciani.
---
 pixman/pixman-region.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 71995fd..9ff5157 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -2378,13 +2378,13 @@ PREFIX (_contains_point) (region_type_t * region,
 return(TRUE);
 }
 
-for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
-pbox != pbox_end;
-pbox++)
-{
-if (y = pbox-y2)
-   continue;   /* not there yet */
+pbox = PIXREGION_BOXPTR (region);
+pbox_end = pbox + numRects;
+
+pbox = find_box_for_y (pbox, pbox_end, y);
 
+for (;pbox != pbox_end; pbox++)
+{
 if ((y  pbox-y1) || (x  pbox-x1))
break;  /* missed it */
 
-- 
1.7.4

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


[Pixman] [PATCH] In pixman_image_create_bits() allow images larger than 2GB

2011-08-11 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

There is no reason for pixman_image_create_bits() to check that the
image size fits in int32_t. The correct check is against size_t since
that is what the argument to calloc() is.

This patch fixes this by adding a new
_pixman_multiply_overflows_size() and using it in create_bits(). Also
prepend an underscore to the names of other similar functions since
they are internal to pixman.
---
 pixman/pixman-bits-image.c |   14 +++---
 pixman/pixman-private.h|7 +--
 pixman/pixman-utils.c  |   12 
 3 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 4e9ed14..d8abeac 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1488,12 +1488,12 @@ _pixman_bits_image_dest_iter_init (pixman_image_t 
*image, pixman_iter_t *iter)
 
 static uint32_t *
 create_bits (pixman_format_code_t format,
- int  width,
- int  height,
- int *rowstride_bytes)
+ ssize_t  width,
+ ssize_t  height,
+ int *   rowstride_bytes)
 {
 int stride;
-int buf_size;
+size_t buf_size;
 int bpp;
 
 /* what follows is a long-winded way, avoiding any possibility of integer
@@ -1502,11 +1502,11 @@ create_bits (pixman_format_code_t format,
  */
 
 bpp = PIXMAN_FORMAT_BPP (format);
-if (pixman_multiply_overflows_int (width, bpp))
+if (_pixman_multiply_overflows_int (width, bpp))
return NULL;
 
 stride = width * bpp;
-if (pixman_addition_overflows_int (stride, 0x1f))
+if (_pixman_addition_overflows_int (stride, 0x1f))
return NULL;
 
 stride += 0x1f;
@@ -1514,7 +1514,7 @@ create_bits (pixman_format_code_t format,
 
 stride *= sizeof (uint32_t);
 
-if (pixman_multiply_overflows_int (height, stride))
+if (_pixman_multiply_overflows_size (height, stride))
return NULL;
 
 buf_size = height * stride;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 6a3935e..a25897d 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -691,10 +691,13 @@ void *
 pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
 
 pixman_bool_t
-pixman_multiply_overflows_int (unsigned int a, unsigned int b);
+_pixman_multiply_overflows_size (size_t a, size_t b);
 
 pixman_bool_t
-pixman_addition_overflows_int (unsigned int a, unsigned int b);
+_pixman_multiply_overflows_int (unsigned int a, unsigned int b);
+
+pixman_bool_t
+_pixman_addition_overflows_int (unsigned int a, unsigned int b);
 
 /* Compositing utilities */
 void
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index cb4e621..49e3488 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -31,15 +31,19 @@
 #include pixman-private.h
 
 pixman_bool_t
-pixman_multiply_overflows_int (unsigned int a,
-   unsigned int b)
+_pixman_multiply_overflows_size (size_t a, size_t b)
+{
+return a = SIZE_MAX / b;
+}
+
+pixman_bool_t
+_pixman_multiply_overflows_int (unsigned int a, unsigned int b)
 {
 return a = INT32_MAX / b;
 }
 
 pixman_bool_t
-pixman_addition_overflows_int (unsigned int a,
-   unsigned int b)
+_pixman_addition_overflows_int (unsigned int a, unsigned int b)
 {
 return a  INT32_MAX - b;
 }
-- 
1.7.4

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


[Pixman] Consolidate some inlined functions

2011-08-15 Thread Søren Sandmann
These three patches rename pixman-fast-path.h to pixman-inlines.h,
since this file is not really specific to the fast path
implementation, and then it moves some code from the general
implementation into that file: the repeat functionality, which was
duplicated, and the bilinear interpolation code.


Soren

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


[Pixman] [PATCH 0/11] Use macros to generate fetchers

2011-09-02 Thread Søren Sandmann
This patch series change pixman-access.c to generate most accessors
with macros and inline functions instead of writing out the code for
all the functions. This is a fairly significant saving in terms of
lines of code:

 pixman-access.c  | 3159 +++
 pixman-private.h |   43 
 pixman-utils.c   |   34 
 3 files changed, 724 insertions(+), 2512 deletions(-)

but the main motivation is that will eventually make it easier to add
floating point fetchers so that we can add a floating point pipeline.

Comments welcome.

Soren


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


[Pixman] [PATCH 01/11] Add a generic unorm_to_unorm() conversion utility

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

This function can convert between normalized numbers of different
depths. When converting to higher bit depths, it will replicate the
existing bits, when converting to lower bit depths, it will simply
truncate.

This function replaces the expand16() function in pixman-utils.c
---
 pixman/pixman-private.h |   43 +++
 pixman/pixman-utils.c   |   34 +-
 2 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index a25897d..90d9011 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -783,6 +783,49 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
 #   define SCREEN_SHIFT_RIGHT(x,n) ((x)  (n))
 #endif
 
+static force_inline uint32_t
+unorm_to_unorm (uint32_t val, int from_bits, int to_bits)
+{
+uint32_t result;
+
+if (from_bits == 0)
+   return 0;
+
+/* Delete any extra bits */
+val = ((1  from_bits) - 1);
+
+if (from_bits = to_bits)
+   return val  (from_bits - to_bits);
+
+/* Start out with the high bit of val in the high bit of result. */
+result = val  (to_bits - from_bits);
+
+/* Copy the bits in result, doubling the number of bits each time, until
+ * we fill all to_bits. Unrolled manually because from_bits and to_bits
+ * are usually known statically, so the compiler can turn all of this
+ * into a few shifts.
+ */
+#define REPLICATE()\
+do \
+{  \
+   if (from_bits  to_bits)\
+   {   \
+   result |= result  from_bits;  \
+   \
+   from_bits *= 2; \
+   }   \
+}  \
+while (0)
+
+REPLICATE();
+REPLICATE();
+REPLICATE();
+REPLICATE();
+REPLICATE();
+
+return result;
+}
+
 /*
  * Various debugging code
  */
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 49e3488..768ca1b 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -72,31 +72,6 @@ pixman_malloc_abc (unsigned int a,
 }
 
 /*
- * Helper routine to expand a color component from 0  n = 8 bits to 16
- * bits by replication.
- */
-static inline uint64_t
-expand16 (const uint8_t val, int nbits)
-{
-/* Start out with the high bit of val in the high bit of result. */
-uint16_t result = (uint16_t)val  (16 - nbits);
-
-if (nbits == 0)
-   return 0;
-
-/* Copy the bits in result, doubling the number of bits each time, until
- * we fill all 16 bits.
- */
-while (nbits  16)
-{
-   result |= result  nbits;
-   nbits *= 2;
-}
-
-return result;
-}
-
-/*
  * This function expands images from ARGB8 format to ARGB16.  To preserve
  * precision, it needs to know the original source format.  For example, if the
  * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
@@ -137,10 +112,11 @@ pixman_expand (uint64_t *   dst,
  r = (pixel  r_shift)  r_mask,
  g = (pixel  g_shift)  g_mask,
  b = (pixel  b_shift)  b_mask;
-   const uint64_t a16 = a_size ? expand16 (a, a_size) : 0x,
-  r16 = expand16 (r, r_size),
-  g16 = expand16 (g, g_size),
-  b16 = expand16 (b, b_size);
+   const uint64_t
+   a16 = a_size ? unorm_to_unorm (a, a_size, 16) : 0x,
+   r16 = unorm_to_unorm (r, r_size, 16),
+   g16 = unorm_to_unorm (g, g_size, 16),
+   b16 = unorm_to_unorm (b, b_size, 16);
 
dst[i] = a16  48 | r16  32 | g16  16 | b16;
 }
-- 
1.7.4

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


[Pixman] [PATCH 02/11] Add general pixel converter

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

This function can convert between any = 32 bpp formats. Nothing uses
it yet.
---
 pixman/pixman-access.c |  100 
 1 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 32c4d8b..2e9e536 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -86,6 +86,106 @@
 ((uint8_t *) ((bits) + offset0 +\
   ((stride)  1) * ((line)  1)))
 
+/* Misc. helpers */
+
+static force_inline void
+get_shifts (pixman_format_code_t  format,
+   int  *a,
+   int  *r,
+   int  *g,
+   int  *b)
+{
+switch (PIXMAN_FORMAT_TYPE (format))
+{
+case PIXMAN_TYPE_A:
+   *b = 0;
+   *g = 0;
+   *r = 0;
+   *a = 0;
+   break;
+
+case PIXMAN_TYPE_ARGB:
+   *b = 0;
+   *g = *b + PIXMAN_FORMAT_B (format);
+   *r = *g + PIXMAN_FORMAT_G (format);
+   *a = *r + PIXMAN_FORMAT_R (format);
+   break;
+
+case PIXMAN_TYPE_ABGR:
+   *r = 0;
+   *g = *r + PIXMAN_FORMAT_R (format);
+   *b = *g + PIXMAN_FORMAT_G (format);
+   *a = *b + PIXMAN_FORMAT_B (format);
+   break;
+
+case PIXMAN_TYPE_BGRA:
+   /* With BGRA formats we start counting at the high end of the pixel */
+   *b = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format);
+   *g = *b - PIXMAN_FORMAT_B (format);
+   *r = *g - PIXMAN_FORMAT_G (format);
+   *a = *r - PIXMAN_FORMAT_R (format);
+   break;
+
+case PIXMAN_TYPE_RGBA:
+   /* With BGRA formats we start counting at the high end of the pixel */
+   *r = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format);
+   *g = *r - PIXMAN_FORMAT_R (format);
+   *b = *g - PIXMAN_FORMAT_G (format);
+   *a = *b - PIXMAN_FORMAT_B (format);
+   break;
+
+default:
+   assert (0);
+   break;
+}
+}
+
+static force_inline uint32_t
+convert_channel (uint32_t pixel, uint32_t def_value,
+int n_from_bits, int from_shift,
+int n_to_bits, int to_shift)
+{
+uint32_t v;
+
+if (n_from_bits  n_to_bits)
+   v  = unorm_to_unorm (pixel  from_shift, n_from_bits, n_to_bits);
+else if (n_to_bits)
+   v = def_value;
+else
+   v = 0;
+
+return (v  ((1  n_to_bits) - 1))  to_shift;
+}
+
+static force_inline uint32_t
+convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t 
pixel)
+{
+int a_from_shift, r_from_shift, g_from_shift, b_from_shift;
+int a_to_shift, r_to_shift, g_to_shift, b_to_shift;
+uint32_t a, r, g, b;
+
+get_shifts (from, a_from_shift, r_from_shift, g_from_shift, 
b_from_shift);
+get_shifts (to, a_to_shift, r_to_shift, g_to_shift, b_to_shift);
+
+a = convert_channel (pixel, ~0,
+PIXMAN_FORMAT_A (from), a_from_shift,
+PIXMAN_FORMAT_A (to), a_to_shift);
+
+r = convert_channel (pixel, 0,
+PIXMAN_FORMAT_R (from), r_from_shift,
+PIXMAN_FORMAT_R (to), r_to_shift);
+
+g = convert_channel (pixel, 0,
+PIXMAN_FORMAT_G (from), g_from_shift,
+PIXMAN_FORMAT_G (to), g_to_shift);
+
+b = convert_channel (pixel, 0,
+PIXMAN_FORMAT_B (from), b_from_shift,
+PIXMAN_FORMAT_B (to), b_to_shift);
+
+return a | r | g | b;
+}
+
 /** Fetch /
 
 static void
-- 
1.7.4

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


[Pixman] [PATCH 04/11] Use MAKE_ACCESSORS() to generate all the 32 bit accessors

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Add support for 32bpp formats in fetch_and_convert_pixel() and
convert_and_store_pixel(), then use MAKE_ACCESSORS() to generate
accessors for all the 32 bpp formats:

a8r8g8b8
x8r8g8b8
a8b8g8r8
x8b8g8r8
x14r6g6b6
b8g8r8a8
b8g8r8x8
r8g8b8x8
r8g8b8a8
---
 pixman/pixman-access.c |  483 ++--
 1 files changed, 17 insertions(+), 466 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index e8356e9..f8d6082 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -207,6 +207,10 @@ fetch_and_convert_pixel (pixman_image_t*   image,
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
+case 32:
+   pixel = READ (image, (uint32_t *)bits);
+   break;
+
 default:
pixel = 0x00ff; /* As ugly as possible to detect the bug */
break;
@@ -225,6 +229,10 @@ convert_and_store_pixel (bits_image_t *image,
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
+case 32:
+   WRITE (image, (uint32_t *)dest, converted);
+   break;
+
 default:
*dest = 0x0;
break;
@@ -299,196 +307,18 @@ convert_and_store_pixel (bits_image_t *  image,
\
 static const void *const __dummy__ ## format
 
+MAKE_ACCESSORS(a8r8g8b8);
+MAKE_ACCESSORS(x8r8g8b8);
+MAKE_ACCESSORS(a8b8g8r8);
+MAKE_ACCESSORS(x8b8g8r8);
+MAKE_ACCESSORS(x14r6g6b6);
+MAKE_ACCESSORS(b8g8r8a8);
+MAKE_ACCESSORS(b8g8r8x8);
+MAKE_ACCESSORS(r8g8b8x8);
+MAKE_ACCESSORS(r8g8b8a8);
 
 /** Fetch /
 
-static void
-fetch_scanline_a8r8g8b8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-
-MEMCPY_WRAPPED (image,
-buffer, (const uint32_t *)bits + x,
-width * sizeof(uint32_t));
-}
-
-static void
-fetch_scanline_x8r8g8b8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint32_t *pixel = (const uint32_t *)bits + x;
-const uint32_t *end = pixel + width;
-
-while (pixel  end)
-   *buffer++ = READ (image, pixel++) | 0xff00;
-}
-
-static void
-fetch_scanline_a8b8g8r8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint32_t *pixel = (uint32_t *)bits + x;
-const uint32_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   
-   *buffer++ = (p  0xff00ff00)|
-   ((p  16)  0xff)  |
-   ((p  0xff)  16);
-}
-}
-
-static void
-fetch_scanline_x8b8g8r8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint32_t *pixel = (uint32_t *)bits + x;
-const uint32_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   
-   *buffer++ = 0xff00  |
-   (p  0xff00)|
-   ((p  16)  0xff)  |
-   ((p  0xff)  16);
-}
-}
-
-static void
-fetch_scanline_b8g8r8a8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint32_t *pixel = (uint32_t *)bits + x;
-const uint32_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-
-   *buffer++ = (((p  0xff00)  24)   |
-((p  0x00ff)  8)|
-((p  0xff00)  8)|
-((p  0x00ff)  24));
-}
-}
-
-static void
-fetch_scanline_b8g8r8x8

[Pixman] [PATCH 05/11] Use MAKE_ACCESSORS() to generate accessors for all the 16bpp formats

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Add support for 16bpp pixels to fetch_and_convert_pixel() and
convert_and_store_pixel(), then use MAKE_ACCESSORS() to generate
accessors for all the 16bpp formats:

r5g6b5
b5g6r5
a1r5g5b5
x1r5g5b5
a1b5g5r5
x1b5g5r5
a4r4g4b4
x4r4g4b4
a4b4g4r4
x4b4g4r4
---
 pixman/pixman-access.c |  658 ++--
 1 files changed, 18 insertions(+), 640 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index f8d6082..7295a22 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -207,6 +207,10 @@ fetch_and_convert_pixel (pixman_image_t*   image,
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
+case 16:
+   pixel = READ (image, (uint16_t *)bits);
+   break;
+
 case 32:
pixel = READ (image, (uint32_t *)bits);
break;
@@ -229,6 +233,10 @@ convert_and_store_pixel (bits_image_t *image,
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
+case 16:
+   WRITE (image, (uint16_t *)dest, converted  0x);
+   break;
+
 case 32:
WRITE (image, (uint32_t *)dest, converted);
break;
@@ -316,6 +324,16 @@ MAKE_ACCESSORS(b8g8r8a8);
 MAKE_ACCESSORS(b8g8r8x8);
 MAKE_ACCESSORS(r8g8b8x8);
 MAKE_ACCESSORS(r8g8b8a8);
+MAKE_ACCESSORS(r5g6b5);
+MAKE_ACCESSORS(b5g6r5);
+MAKE_ACCESSORS(a1r5g5b5);
+MAKE_ACCESSORS(x1r5g5b5);
+MAKE_ACCESSORS(a1b5g5r5);
+MAKE_ACCESSORS(x1b5g5r5);
+MAKE_ACCESSORS(a4r4g4b4);
+MAKE_ACCESSORS(x4r4g4b4);
+MAKE_ACCESSORS(a4b4g4r4);
+MAKE_ACCESSORS(x4b4g4r4);
 
 /** Fetch /
 
@@ -506,261 +524,6 @@ fetch_scanline_b8g8r8 (pixman_image_t *image,
 }
 
 static void
-fetch_scanline_r5g6b5 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint16_t *pixel = (const uint16_t *)bits + x;
-const uint16_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   uint32_t r = (((p)  3)  0xf8) |
-   (((p)  5)  0xfc00) |
-   (((p)  8)  0xf8);
-   
-   r |= (r  5)  0x70007;
-   r |= (r  6)  0x300;
-   
-   *buffer++ = 0xff00 | r;
-}
-}
-
-static void
-fetch_scanline_b5g6r5 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint16_t *pixel = (const uint16_t *)bits + x;
-const uint16_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   uint32_t r, g, b;
-   
-   b = ((p  0xf800) | ((p  0xe000)  5))  8;
-   g = ((p  0x07e0) | ((p  0x0600)  6))  5;
-   r = ((p  0x001c) | ((p  0x001f)  5))  14;
-   
-   *buffer++ = 0xff00 | r | g | b;
-}
-}
-
-static void
-fetch_scanline_a1r5g5b5 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint16_t *pixel = (const uint16_t *)bits + x;
-const uint16_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   uint32_t r, g, b, a;
-   
-   a = (uint32_t) ((uint8_t) (0 - ((p  0x8000)  15)))  24;
-   r = ((p  0x7c00) | ((p  0x7000)  5))  9;
-   g = ((p  0x03e0) | ((p  0x0380)  5))  6;
-   b = ((p  0x001c) | ((p  0x001f)  5))  2;
-   
-   *buffer++ = a | r | g | b;
-}
-}
-
-static void
-fetch_scanline_x1r5g5b5 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint16_t *pixel = (const uint16_t *)bits + x;
-const uint16_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   uint32_t r, g, b;
-   
-   r = ((p  0x7c00) | ((p  0x7000)  5))  9;
-   g = ((p  0x03e0) | ((p  0x0380)  5))  6;
-   b = ((p  0x001c) | ((p  0x001f)  5))  2;
-   
-   *buffer++ = 0xff00 | r | g | b;
-}
-}
-
-static void

[Pixman] [PATCH 06/11] Use MAKE_ACCESSORS() to generate accessors for 8bpp RGB formats

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Add support for 8 bpp formats to fetch_and_convert_pixel() and
convert_and_store_pixel(), then use MAKE_ACCESSORS() to generate the
accessors for all the 8 bpp formats, except g8 and c8, which are
indexed:

a8
r3g3b2
b2g3r3
a2r2g2b2
a2b2g2r2
x4a4
---
 pixman/pixman-access.c |  396 ++--
 1 files changed, 14 insertions(+), 382 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 7295a22..b0e27ee 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -207,6 +207,10 @@ fetch_and_convert_pixel (pixman_image_t*   image,
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
+case 8:
+   pixel = READ (image, bits);
+   break;
+
 case 16:
pixel = READ (image, (uint16_t *)bits);
break;
@@ -233,6 +237,10 @@ convert_and_store_pixel (bits_image_t *image,
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
+case 8:
+   WRITE (image, dest, converted  0xff);
+   break;
+
 case 16:
WRITE (image, (uint16_t *)dest, converted  0x);
break;
@@ -334,6 +342,12 @@ MAKE_ACCESSORS(a4r4g4b4);
 MAKE_ACCESSORS(x4r4g4b4);
 MAKE_ACCESSORS(a4b4g4r4);
 MAKE_ACCESSORS(x4b4g4r4);
+MAKE_ACCESSORS(a8);
+MAKE_ACCESSORS(r3g3b2);
+MAKE_ACCESSORS(b2g3r3);
+MAKE_ACCESSORS(a2r2g2b2);
+MAKE_ACCESSORS(a2b2g2r2);
+MAKE_ACCESSORS(x4a4);
 
 /** Fetch /
 
@@ -524,138 +538,6 @@ fetch_scanline_b8g8r8 (pixman_image_t *image,
 }
 
 static void
-fetch_scanline_a8 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint8_t *pixel = (const uint8_t *)bits + x;
-const uint8_t *end = pixel + width;
-
-while (pixel  end)
-   *buffer++ = READ (image, pixel++)  24;
-}
-
-static void
-fetch_scanline_r3g3b2 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint8_t *pixel = (const uint8_t *)bits + x;
-const uint8_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   uint32_t r, g, b;
-   
-   r = ((p  0xe0) | ((p  0xe0)  3) | ((p  0xc0)  6))  16;
-   g = ((p  0x1c) | ((p  0x18)  3) | ((p  0x1c)  3))  8;
-   b = (((p  0x03) ) |
-((p  0x03)  2) |
-((p  0x03)  4) |
-((p  0x03)  6));
-   
-   *buffer++ = 0xff00 | r | g | b;
-}
-}
-
-static void
-fetch_scanline_b2g3r3 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint8_t *pixel = (const uint8_t *)bits + x;
-const uint8_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   uint32_t r, g, b;
-
-   b  = p  0xc0;
-   b |= b  2;
-   b |= b  4;
-   b = 0xff;
-
-   g  = (p  0x38)  10;
-   g |= g  3;
-   g |= g  6;
-   g = 0xff00;
-
-   r  = (p  0x7)  21;
-   r |= r  3;
-   r |= r  6;
-   r = 0xff;
-
-   *buffer++ = 0xff00 | r | g | b;
-}
-}
-
-static void
-fetch_scanline_a2r2g2b2 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint8_t *pixel = (const uint8_t *)bits + x;
-const uint8_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   uint32_t a, r, g, b;
-   
-   a = ((p  0xc0) * 0x55)  18;
-   r = ((p  0x30) * 0x55)  12;
-   g = ((p  0x0c) * 0x55)  6;
-   b = ((p  0x03) * 0x55);
-   
-   *buffer++ = a | r | g | b;
-}
-}
-
-static void
-fetch_scanline_a2b2g2r2 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *  buffer,
- const uint32_t *mask)
-{
-const uint32_t *bits

[Pixman] [PATCH 08/11] Use MAKE_ACCESSORS() to generate accessors for 24bpp formats

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Add FETCH_24 and STORE_24 macros and use them to add support for 24bpp
pixels in fetch_and_convert_pixel() and
convert_and_store_pixel(). Then use MAKE_ACCESSORS() to generate
accessors for the 24 bpp formats:

r8g8b8
b8g8r8
---
 pixman/pixman-access.c |  199 +++-
 1 files changed, 46 insertions(+), 153 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index b107d3b..30544e4 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -66,6 +66,18 @@
 (((4 * (o))  4) ? (FETCH_8 (img, l, 4 * (o))  4) : (FETCH_8 (img, l, (4 
* (o)))  0xf))
 #endif
 
+#ifdef WORDS_BIGENDIAN
+#define FETCH_24(img,l,o)  \
+((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0))  16)|   \
+ (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1))  8) |   \
+ (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2))  0))
+#else
+#define FETCH_24(img,l,o)  \
+((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0))  0) |   \
+ (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1))  8) |   \
+ (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2))  16))
+#endif
+
 /* Store macros */
 
 #define STORE_8(img,l,o,v)  (WRITE (img, (uint8_t *)(l) + ((o)  3), (v)))
@@ -96,6 +108,30 @@
 } while (0)
 #endif
 
+#ifdef WORDS_BIGENDIAN
+#define STORE_24(img,l,o,v)\
+do \
+{  \
+   uint8_t *__tmp = (l) + 3 * (o);\
+  \
+   WRITE ((img), __tmp++, ((v)  0x00ff)  16);  \
+   WRITE ((img), __tmp++, ((v)  0xff00)   8);  \
+   WRITE ((img), __tmp++, ((v)  0x00ff)   0);  \
+}  \
+while (0)
+#else
+#define STORE_24(img,l,o,v)\
+do \
+{  \
+   uint8_t *__tmp = (l) + 3 * (o);\
+  \
+   WRITE ((img), __tmp++, ((v)  0x00ff)   0);  \
+   WRITE ((img), __tmp++, ((v)  0xff00)   8);  \
+   WRITE ((img), __tmp++, ((v)  0x00ff)  16);  \
+}  \
+while (0)
+#endif
+
 /*
  * YV12 setup and access macros
  */
@@ -262,6 +298,10 @@ fetch_and_convert_pixel (pixman_image_t*   image,
pixel = READ (image, ((uint16_t *)bits + offset));
break;
 
+case 24:
+   pixel = FETCH_24 (image, bits, offset);
+   break;
+
 case 32:
pixel = READ (image, ((uint32_t *)bits + offset));
break;
@@ -297,6 +337,10 @@ convert_and_store_pixel (bits_image_t *image,
WRITE (image, ((uint16_t *)dest + offset), converted  0x);
break;
 
+case 24:
+   STORE_24 (image, dest, offset, converted);
+   break;
+
 case 32:
WRITE (image, ((uint32_t *)dest + offset), converted);
break;
@@ -368,6 +412,8 @@ MAKE_ACCESSORS(b8g8r8a8);
 MAKE_ACCESSORS(b8g8r8x8);
 MAKE_ACCESSORS(r8g8b8x8);
 MAKE_ACCESSORS(r8g8b8a8);
+MAKE_ACCESSORS(r8g8b8);
+MAKE_ACCESSORS(b8g8r8);
 MAKE_ACCESSORS(r5g6b5);
 MAKE_ACCESSORS(b5g6r5);
 MAKE_ACCESSORS(a1r5g5b5);
@@ -521,64 +567,6 @@ fetch_scanline_x2b10g10r10 (pixman_image_t *image,
 }
 
 static void
-fetch_scanline_r8g8b8 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const uint8_t *pixel = (const uint8_t *)bits + 3 * x;
-const uint8_t *end = pixel + 3 * width;
-
-while (pixel  end)
-{
-   uint32_t b = 0xff00;
-   
-#ifdef WORDS_BIGENDIAN
-   b |= (READ (image, pixel++)  16);
-   b |= (READ (image, pixel++)  8);
-   b |= (READ (image, pixel++));
-#else
-   b |= (READ (image, pixel++));
-   b |= (READ (image, pixel++)  8);
-   b |= (READ (image, pixel++)  16);
-#endif
-   
-   *buffer++ = b;
-}
-}
-
-static void
-fetch_scanline_b8g8r8 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask

[Pixman] [PATCH 09/11] Use MAKE_ACCESSORS() to generate accessors for the a1 format.

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Add FETCH_1 and STORE_1 macros and use them to add support for 1bpp
pixels to fetch_and_convert_pixel() and convert_and_store_pixel(),
then use MAKE_ACCESSORS() to generate the accessors for the a1
format. (Not the g1 format as it is indexed).
---
 pixman/pixman-access.c |  125 ++--
 1 files changed, 46 insertions(+), 79 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 30544e4..d7e0d08 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -56,6 +56,14 @@
 
 /* Fetch macros */
 
+#ifdef WORDS_BIGENDIAN
+#define FETCH_1(img,l,o)   \
+(((READ ((img), ((uint32_t *)(l)) + ((o)  5)))  (0x1f - ((o)  0x1f))) 
 0x1)
+#else
+#define FETCH_1(img,l,o)   \
+READ ((img), ((uint32_t *)(l)) + ((o)  5)))  ((o)  0x1f)))  0x1)
+#endif
+
 #define FETCH_8(img,l,o)(READ (img, (((uint8_t *)(l)) + ((o)  3
 
 #ifdef WORDS_BIGENDIAN
@@ -80,6 +88,34 @@
 
 /* Store macros */
 
+#ifdef WORDS_BIGENDIAN
+#define STORE_1(img,l,o,v) \
+do \
+{  \
+   uint32_t  *__d = ((uint32_t *)(l)) + ((o)  5);\
+   uint32_t __m, __v;  \
+   \
+   __m = 1  (0x1f - ((o)  0x1f));   \
+   __v = (v)? __m : 0; \
+   \
+   WRITE((img), __d, (READ((img), __d)  ~__m) | __v); \
+}  \
+while (0)
+#else
+#define STORE_1(img,l,o,v) \
+do \
+{  \
+   uint32_t  *__d = ((uint32_t *)(l)) + ((o)  5);\
+   uint32_t __m, __v;  \
+   \
+   __m = 1  ((o)  0x1f);\
+   __v = (v)? __m : 0; \
+   \
+   WRITE((img), __d, (READ((img), __d)  ~__m) | __v); \
+}  \
+while (0)
+#endif
+
 #define STORE_8(img,l,o,v)  (WRITE (img, (uint8_t *)(l) + ((o)  3), (v)))
 
 #ifdef WORDS_BIGENDIAN
@@ -128,7 +164,7 @@
WRITE ((img), __tmp++, ((v)  0x00ff)   0);  \
WRITE ((img), __tmp++, ((v)  0xff00)   8);  \
WRITE ((img), __tmp++, ((v)  0x00ff)  16);  \
-}  \
+} \
 while (0)
 #endif
 
@@ -286,6 +322,10 @@ fetch_and_convert_pixel (pixman_image_t*   image,
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
+case 1:
+   pixel = FETCH_1 (image, bits, offset);
+   break;
+
 case 4:
pixel = FETCH_4 (image, bits, offset);
break;
@@ -325,6 +365,10 @@ convert_and_store_pixel (bits_image_t *image,
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
+case 1:
+   STORE_1 (image, dest, offset, converted  0x01);
+   break;
+
 case 4:
STORE_4 (image, dest, offset, converted  0xf);
break;
@@ -435,6 +479,7 @@ MAKE_ACCESSORS(r1g2b1);
 MAKE_ACCESSORS(b1g2r1);
 MAKE_ACCESSORS(a1r1g1b1);
 MAKE_ACCESSORS(a1b1g1r1);
+MAKE_ACCESSORS(a1);
 
 /** Fetch /
 
@@ -608,36 +653,6 @@ fetch_scanline_c4 (pixman_image_t *image,
 }
 
 static void
-fetch_scanline_a1 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-int i;
-
-for (i = 0; i  width; ++i)
-{
-   uint32_t p = READ (image, bits + ((i + x)  5));
-   uint32_t a;
-   
-#ifdef WORDS_BIGENDIAN
-   a = p  (0x1f - ((i + x)  0x1f));
-#else
-   a = p  ((i + x)  0x1f);
-#endif
-   a = a  1;
-   a |= a  1;
-   a |= a  2;
-   a |= a  4;
-   
-   *buffer++ = a  24;
-}
-}
-
-static void
 fetch_scanline_g1 (pixman_image_t *image,
int x

[Pixman] [PATCH 10/11] Use MAKE_ACCESSORS() to generate accessors for paletted formats

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Add support in convert_pixel_from_a8r8g8b8() and
convert_pixel_to_a8r8g8b8() for conversion to/from paletted formats,
then use MAKE_ACCESSORS() to generate accessors for the indexed
formats: c8, g8, g4, c4, g1
---
 pixman/pixman-access.c |  276 
 1 files changed, 46 insertions(+), 230 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index d7e0d08..189b191 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -301,15 +301,41 @@ convert_pixel (pixman_format_code_t from, 
pixman_format_code_t to, uint32_t pixe
 }
 
 static force_inline uint32_t
-convert_pixel_from_a8r8g8b8 (pixman_format_code_t format, uint32_t pixel)
+convert_pixel_to_a8r8g8b8 (pixman_image_t *image,
+  pixman_format_code_t format,
+  uint32_t pixel)
 {
-return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
+if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY||
+   PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
+{
+   return image-bits.indexed-rgba[pixel];
+}
+else
+{
+   return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
+}
 }
 
 static force_inline uint32_t
-convert_pixel_to_a8r8g8b8 (pixman_format_code_t format, uint32_t pixel)
+convert_pixel_from_a8r8g8b8 (pixman_image_t *image,
+pixman_format_code_t format, uint32_t pixel)
 {
-return convert_pixel (format, PIXMAN_a8r8g8b8, pixel);
+if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
+{
+   pixel = CONVERT_RGB24_TO_Y15 (pixel);
+
+   return image-bits.indexed-ent[pixel  0x7fff];
+}
+else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
+{
+   pixel = convert_pixel (PIXMAN_a8r8g8b8, PIXMAN_x1r5g5b5, pixel);
+
+   return image-bits.indexed-ent[pixel  0x7fff];
+}
+else
+{
+   return convert_pixel (PIXMAN_a8r8g8b8, format, pixel);
+}
 }
 
 static force_inline uint32_t
@@ -351,7 +377,7 @@ fetch_and_convert_pixel (pixman_image_t *   image,
break;
 }
 
-return convert_pixel_to_a8r8g8b8 (format, pixel);
+return convert_pixel_to_a8r8g8b8 (image, format, pixel);
 }
 
 static force_inline void
@@ -361,7 +387,8 @@ convert_and_store_pixel (bits_image_t * image,
 pixman_format_code_t   format,
 uint32_t   pixel)
 {
-uint32_t converted = convert_pixel_from_a8r8g8b8 (format, pixel);
+uint32_t converted = convert_pixel_from_a8r8g8b8 (
+   (pixman_image_t *)image, format, pixel);
 
 switch (PIXMAN_FORMAT_BPP (format))
 {
@@ -469,17 +496,22 @@ MAKE_ACCESSORS(x4r4g4b4);
 MAKE_ACCESSORS(a4b4g4r4);
 MAKE_ACCESSORS(x4b4g4r4);
 MAKE_ACCESSORS(a8);
+MAKE_ACCESSORS(c8);
+MAKE_ACCESSORS(g8);
 MAKE_ACCESSORS(r3g3b2);
 MAKE_ACCESSORS(b2g3r3);
 MAKE_ACCESSORS(a2r2g2b2);
 MAKE_ACCESSORS(a2b2g2r2);
 MAKE_ACCESSORS(x4a4);
 MAKE_ACCESSORS(a4);
+MAKE_ACCESSORS(g4);
+MAKE_ACCESSORS(c4);
 MAKE_ACCESSORS(r1g2b1);
 MAKE_ACCESSORS(b1g2r1);
 MAKE_ACCESSORS(a1r1g1b1);
 MAKE_ACCESSORS(a1b1g1r1);
 MAKE_ACCESSORS(a1);
+MAKE_ACCESSORS(g1);
 
 /** Fetch /
 
@@ -612,75 +644,6 @@ fetch_scanline_x2b10g10r10 (pixman_image_t *image,
 }
 
 static void
-fetch_scanline_c8 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const pixman_indexed_t * indexed = image-bits.indexed;
-const uint8_t *pixel = (const uint8_t *)bits + x;
-const uint8_t *end = pixel + width;
-
-while (pixel  end)
-{
-   uint32_t p = READ (image, pixel++);
-   
-   *buffer++ = indexed-rgba[p];
-}
-}
-
-static void
-fetch_scanline_c4 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const pixman_indexed_t * indexed = image-bits.indexed;
-int i;
-
-for (i = 0; i  width; ++i)
-{
-   uint32_t p = FETCH_4 (image, bits, i + x);
-   
-   *buffer++ = indexed-rgba[p];
-}
-}
-
-static void
-fetch_scanline_g1 (pixman_image_t *image,
-   int x,
-   int y,
-   int width,
-   uint32_t *  buffer,
-   const uint32_t *mask)
-{
-const uint32_t *bits = image-bits.bits + y * image-bits.rowstride;
-const pixman_indexed_t * indexed = image-bits.indexed;
-int i

[Pixman] [PATCH 11/11] Add some fast paths to convert_pixel()

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

All the inlining going on makes gcc generate slightly suboptimal code,
so add some special cases for the common formats a8r8g8b8, x8r8g8b8,
a8, and r5g6b5.
---
 pixman/pixman-access.c |   53 
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 189b191..9ebcc1f 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -271,6 +271,56 @@ convert_channel (uint32_t pixel, uint32_t def_value,
 return (v  ((1  n_to_bits) - 1))  to_shift;
 }
 
+static force_inline pixman_bool_t
+convert_special_cases (pixman_format_code_t from, pixman_format_code_t to, 
uint32_t *pixel)
+{
+/* A couple of special cases for performance */
+if ((from == to) || (from == PIXMAN_a8r8g8b8  to == PIXMAN_x8r8g8b8))
+{
+   return TRUE;
+}
+else if (from == PIXMAN_x8r8g8b8  to == PIXMAN_a8r8g8b8)
+{
+   *pixel |= 0xff00;
+   return TRUE;
+}
+else if (from == PIXMAN_a8  to == PIXMAN_a8r8g8b8)
+{
+   *pixel = 24;
+   return TRUE;
+}
+else if (from == PIXMAN_r5g6b5  to == PIXMAN_a8r8g8b8)
+{
+   uint32_t r;
+   
+   r = ((*pixel  3)  0xf8) |
+   ((*pixel  5)  0xfc00) |
+   ((*pixel  8)  0xf8);
+   
+   r |= (r  5)  0x70007;
+   r |= (r  6)  0x300;
+   
+   *pixel = r | 0xff00;
+   return TRUE;
+}
+else if (from == PIXMAN_a8r8g8b8  to == PIXMAN_a8)
+{
+   *pixel = 24;
+   return TRUE;
+}
+else if (from == PIXMAN_a8r8g8b8  to == PIXMAN_r5g6b5)
+{
+   *pixel =
+   ((*pixel  3)  0x001f) |
+   ((*pixel  5)  0x07e0) |
+   ((*pixel  8)  0xf800);
+   
+   return TRUE;
+}
+
+return FALSE;
+}
+
 static force_inline uint32_t
 convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t 
pixel)
 {
@@ -278,6 +328,9 @@ convert_pixel (pixman_format_code_t from, 
pixman_format_code_t to, uint32_t pixe
 int a_to_shift, r_to_shift, g_to_shift, b_to_shift;
 uint32_t a, r, g, b;
 
+if (convert_special_cases (from, to, pixel))
+   return pixel;
+
 get_shifts (from, a_from_shift, r_from_shift, g_from_shift, 
b_from_shift);
 get_shifts (to, a_to_shift, r_to_shift, g_to_shift, b_to_shift);
 
-- 
1.7.4

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


[Pixman] [PATCH] test: New function to save a pixman image to .png

2011-09-02 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

When debugging it is often very useful to be able to save an image as
a png file. This commit adds a function write_png() that does that.

If libpng is not available, then the function becomes a noop.
---
 configure.ac |   11 +
 test/Makefile.am |2 +-
 test/utils.c |  112 ++
 test/utils.h |3 +
 4 files changed, 127 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index 4c62102..a936a6d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -801,6 +801,17 @@ fi
 AC_MSG_RESULT($support_for_attribute_constructor)
 AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR)
 
+dnl ==
+dnl libpng
+
+AC_CHECK_LIB([png], [png_write_info], [have_libpng=yes], [have_libpng=no])
+
+if test x$have_libpng = xyes; then
+AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng])
+fi
+
+AC_SUBST(HAVE_LIBPNG)
+
 AC_OUTPUT([pixman-1.pc
pixman-1-uninstalled.pc
Makefile
diff --git a/test/Makefile.am b/test/Makefile.am
index 9f61fc9..52ef8ad 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,6 +1,6 @@
 AM_CFLAGS = @OPENMP_CFLAGS@
 AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
-LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
+LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
 
 TESTPROGRAMS = \
diff --git a/test/utils.c b/test/utils.c
index 44188ea..adabd75 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -21,6 +21,10 @@
 #include fenv.h
 #endif
 
+#ifdef HAVE_LIBPNG
+#include png.h
+#endif
+
 /* Random number seed
  */
 
@@ -335,6 +339,114 @@ make_random_bytes (int n_bytes)
 return bytes;
 }
 
+#ifdef HAVE_LIBPNG
+
+static void
+pngify_pixels (uint32_t *pixels, int n_pixels)
+{
+int i;
+
+for (i = 0; i  n_pixels; ++i)
+{
+   uint32_t p = pixels[i];
+   uint8_t *out = (uint8_t *)(pixels[i]);
+   uint8_t a, r, g, b;
+
+   a = (p  0xff00)  24;
+   r = (p  0x00ff)  16;
+   g = (p  0xff00)  8;
+   b = (p  0x00ff)  0;
+
+   if (a != 0)
+   {
+   r = (r * 255) / a;
+   g = (g * 255) / a;
+   b = (b * 255) / a;
+   }
+
+   *out++ = r;
+   *out++ = g;
+   *out++ = b;
+   *out++ = a;
+}
+}
+
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename)
+{
+int width = pixman_image_get_width (image);
+int height = pixman_image_get_height (image);
+int stride = width * 4;
+uint32_t *data = malloc (height * stride);
+pixman_image_t *copy;
+png_struct *write_struct;
+png_info *info_struct;
+pixman_bool_t result = FALSE;
+FILE *f = fopen (filename, wb);
+png_bytep *row_pointers;
+int i;
+
+if (!f)
+   return FALSE;
+
+row_pointers = malloc (height * sizeof (png_bytep));
+
+copy = pixman_image_create_bits (
+   PIXMAN_a8r8g8b8, width, height, data, stride);
+
+pixman_image_composite32 (
+   PIXMAN_OP_SRC, image, NULL, copy, 0, 0, 0, 0, 0, 0, width, height);
+
+pngify_pixels (data, height * width);
+
+for (i = 0; i  height; ++i)
+   row_pointers[i] = (png_bytep)(data + i * width);
+
+if (!(write_struct = png_create_write_struct (
+ PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
+   goto out1;
+
+if (!(info_struct = png_create_info_struct (write_struct)))
+   goto out2;
+
+png_init_io (write_struct, f);
+
+png_set_IHDR (write_struct, info_struct, width, height,
+ 8, PNG_COLOR_TYPE_RGB_ALPHA,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
+ PNG_FILTER_TYPE_BASE);
+
+png_write_info (write_struct, info_struct);
+
+png_write_image (write_struct, row_pointers);
+
+png_write_end (write_struct, NULL);
+
+result = TRUE;
+
+out2:
+png_destroy_write_struct (write_struct, info_struct);
+
+out1:
+if (fclose (f) != 0)
+   result = FALSE;
+
+pixman_image_unref (copy);
+free (row_pointers);
+free (data);
+return result;
+}
+
+#else /* no libpng */
+
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename)
+{
+return FALSE;
+}
+
+#endif
+
 /*
  * A function, which can be used as a core part of the test programs,
  * intended to detect various problems with the help of fuzzing input
diff --git a/test/utils.h b/test/utils.h
index f0c9c30..3790483 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -105,6 +105,9 @@ fail_after (int seconds, const char *msg);
 /* If possible, enable traps for floating point exceptions */
 void enable_fp_exceptions(void);
 
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename);
+
 /* 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] [PATCH] Eliminate compute_sample_extents() function

2011-09-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

In analyze_extents(), instead of calling compute_sample_extents()
twice, just call compute_transformed_extents() once.

Instead of calling compute_sample_extents() for the destination
rectangle expanded by one, just call compute_transformed_extents() and
expand the returned rectangle by adding the absolute values of the 00
and 10 entries in the transformation, then check if the results fit in
16 bits. This is a little bit more conservative than necessary, but
only corner cases where we are already close to the limit of the 16
bit coordinate space are affected.

The rest of the compute_sample_extents() function can now just be
inlined into analyze_extents(), and compute_sample_extents() can be
deleted.
---
 pixman/pixman.c |   94 +--
 1 files changed, 36 insertions(+), 58 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index 264a56b..3ecd311 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -514,45 +514,9 @@ compute_transformed_extents (pixman_transform_t *transform,
 return TRUE;
 }
 
-static pixman_bool_t
-compute_sample_extents (pixman_transform_t *transform,
-   pixman_box32_t *extents,
-   pixman_fixed_t x_off, pixman_fixed_t y_off,
-   pixman_fixed_t width, pixman_fixed_t height)
-{
-box_48_16_t transformed;
-
-if (!compute_transformed_extents (transform, extents, transformed))
-   return FALSE;
-
-/* Expand the source area by a tiny bit so account of different rounding 
that
- * may happen during sampling. Note that (8 * pixman_fixed_e) is very far 
from
- * 0.5 so this won't cause the area computed to be overly pessimistic.
- */
-transformed.x1 += x_off - 8 * pixman_fixed_e;
-transformed.y1 += y_off - 8 * pixman_fixed_e;
-transformed.x2 += x_off + width + 8 * pixman_fixed_e;
-transformed.y2 += y_off + height + 8 * pixman_fixed_e;
-
-if (transformed.x1  pixman_min_fixed_48_16 || transformed.x1  
pixman_max_fixed_48_16 ||
-   transformed.y1  pixman_min_fixed_48_16 || transformed.y1  
pixman_max_fixed_48_16 ||
-   transformed.x2  pixman_min_fixed_48_16 || transformed.x2  
pixman_max_fixed_48_16 ||
-   transformed.y2  pixman_min_fixed_48_16 || transformed.y2  
pixman_max_fixed_48_16)
-{
-   return FALSE;
-}
-else
-{
-   extents-x1 = pixman_fixed_to_int (transformed.x1);
-   extents-y1 = pixman_fixed_to_int (transformed.y1);
-   extents-x2 = pixman_fixed_to_int (transformed.x2) + 1;
-   extents-y2 = pixman_fixed_to_int (transformed.y2) + 1;
-
-   return TRUE;
-}
-}
-
 #define IS_16BIT(x) (((x) = INT16_MIN)  ((x) = INT16_MAX))
+#define ABS(f)  (((f)  0)?  (-(f)) : (f))
+#define IS_16_16(f) (((f) = pixman_min_fixed_48_16  ((f) = 
pixman_max_fixed_48_16)))
 
 static pixman_bool_t
 analyze_extent (pixman_image_t   *image,
@@ -563,7 +527,8 @@ analyze_extent (pixman_image_t   *image,
 pixman_fixed_t *params;
 pixman_fixed_t x_off, y_off;
 pixman_fixed_t width, height;
-pixman_box32_t ex;
+pixman_fixed_t m00, m10;
+box_48_16_t transformed;
 
 if (!image)
return TRUE;
@@ -633,17 +598,6 @@ analyze_extent (pixman_image_t   *image,
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_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;
-   }
 }
 else
 {
@@ -653,17 +607,41 @@ analyze_extent (pixman_image_t   *image,
height = 0;
 }
 
-/* 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.
+if (!compute_transformed_extents (transform, extents, transformed))
+   return FALSE;
+
+/* Expand the source area by a tiny bit so account of different rounding 
that
+ * may happen during sampling. Note that (8 * pixman_fixed_e) is very far 
from
+ * 0.5 so this won't cause the area computed to be overly pessimistic.
+ */
+transformed.x1 += x_off - 8 * pixman_fixed_e;
+transformed.y1 += y_off - 8 * pixman_fixed_e;
+transformed.x2 += x_off + width + 8 * pixman_fixed_e;
+transformed.y2 += y_off + height + 8 * pixman_fixed_e;
+
+/* Check we don't overflow when the destination extents are expanded by 
one.
+ * This ensures that compositing functions can simply walk the source space
+ * using 16.16 variables without worrying about overflow.
  */
-ex.x1 = extents-x1 - 1;
-ex.y1

[Pixman] [PATCH] Split computation of sample area into own function

2011-09-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

compute_sample_extents() have two parts: one that computes the
transformed extents, and one that checks whether the computed extents
fit within the 16.16 coordinate space.

Split the first part into its own function
compute_transformed_extents().
---
 pixman/pixman.c |  138 ++-
 1 files changed, 76 insertions(+), 62 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index 9af6e2f..264a56b 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -446,93 +446,107 @@ update_cache:
 return TRUE;
 }
 
+typedef struct
+{
+pixman_fixed_48_16_t   x1;
+pixman_fixed_48_16_t   y1;
+pixman_fixed_48_16_t   x2;
+pixman_fixed_48_16_t   y2;
+} box_48_16_t;
+
 static pixman_bool_t
-compute_sample_extents (pixman_transform_t *transform,
-   pixman_box32_t *extents,
-   pixman_fixed_t x_off, pixman_fixed_t y_off,
-   pixman_fixed_t width, pixman_fixed_t height)
+compute_transformed_extents (pixman_transform_t *transform,
+const pixman_box32_t *extents,
+box_48_16_t *transformed)
 {
-pixman_fixed_t x1, y1, x2, y2;
 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
+pixman_fixed_t x1, y1, x2, y2;
+int i;
 
-/* We have checked earlier that (extents-x1 - x) etc. fit in a 
pixman_fixed_t */
-x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents-x1) + 
pixman_fixed_1 / 2;
-y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents-y1) + 
pixman_fixed_1 / 2;
-x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents-x2) - 
pixman_fixed_1 / 2;
-y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents-y2) - 
pixman_fixed_1 / 2;
+x1 = pixman_int_to_fixed (extents-x1) + pixman_fixed_1 / 2;
+y1 = pixman_int_to_fixed (extents-y1) + pixman_fixed_1 / 2;
+x2 = pixman_int_to_fixed (extents-x2) - pixman_fixed_1 / 2;
+y2 = pixman_int_to_fixed (extents-y2) - pixman_fixed_1 / 2;
 
 if (!transform)
 {
-   tx1 = (pixman_fixed_48_16_t)x1;
-   ty1 = (pixman_fixed_48_16_t)y1;
-   tx2 = (pixman_fixed_48_16_t)x2;
-   ty2 = (pixman_fixed_48_16_t)y2;
+   transformed-x1 = x1;
+   transformed-y1 = y1;
+   transformed-x2 = x2;
+   transformed-y2 = y2;
+
+   return TRUE;
 }
-else
+
+tx1 = ty1 = INT64_MAX;
+tx2 = ty2 = INT64_MIN;
+
+for (i = 0; i  4; ++i)
 {
-   int i;
+   pixman_fixed_48_16_t tx, ty;
+   pixman_vector_t v;
 
-   /* Silence GCC */
-   tx1 = ty1 = tx2 = ty2 = 0;
+   v.vector[0] = (i  0x01)? x1 : x2;
+   v.vector[1] = (i  0x02)? y1 : y2;
+   v.vector[2] = pixman_fixed_1;
 
-   for (i = 0; i  4; ++i)
-   {
-   pixman_fixed_48_16_t tx, ty;
-   pixman_vector_t v;
+   if (!pixman_transform_point (transform, v))
+   return FALSE;
 
-   v.vector[0] = (i  0x01)? x1 : x2;
-   v.vector[1] = (i  0x02)? y1 : y2;
-   v.vector[2] = pixman_fixed_1;
+   tx = (pixman_fixed_48_16_t)v.vector[0];
+   ty = (pixman_fixed_48_16_t)v.vector[1];
+
+   if (tx  tx1)
+   tx1 = tx;
+   if (ty  ty1)
+   ty1 = ty;
+   if (tx  tx2)
+   tx2 = tx;
+   if (ty  ty2)
+   ty2 = ty;
+}
 
-   if (!pixman_transform_point (transform, v))
-   return FALSE;
+transformed-x1 = tx1;
+transformed-y1 = ty1;
+transformed-x2 = tx2;
+transformed-y2 = ty2;
 
-   tx = (pixman_fixed_48_16_t)v.vector[0];
-   ty = (pixman_fixed_48_16_t)v.vector[1];
+return TRUE;
+}
 
-   if (i == 0)
-   {
-   tx1 = tx;
-   ty1 = ty;
-   tx2 = tx;
-   ty2 = ty;
-   }
-   else
-   {
-   if (tx  tx1)
-   tx1 = tx;
-   if (ty  ty1)
-   ty1 = ty;
-   if (tx  tx2)
-   tx2 = tx;
-   if (ty  ty2)
-   ty2 = ty;
-   }
-   }
-}
+static pixman_bool_t
+compute_sample_extents (pixman_transform_t *transform,
+   pixman_box32_t *extents,
+   pixman_fixed_t x_off, pixman_fixed_t y_off,
+   pixman_fixed_t width, pixman_fixed_t height)
+{
+box_48_16_t transformed;
+
+if (!compute_transformed_extents (transform, extents, transformed))
+   return FALSE;
 
 /* Expand the source area by a tiny bit so account of different rounding 
that
  * may happen during sampling. Note that (8 * pixman_fixed_e) is very far 
from
  * 0.5 so this won't cause the area computed to be overly pessimistic.
  */
-tx1 += x_off - 8 * pixman_fixed_e;
-ty1 += y_off - 8 * pixman_fixed_e;
-tx2 += x_off + width + 8 * pixman_fixed_e;
-ty2 += y_off + height + 8 * pixman_fixed_e;
-
-if (tx1

[Pixman] [PATCH] test: better coverage for BILINEAR-NEAREST filter optimization

2011-09-05 Thread Søren Sandmann
From: Siarhei Siamashka siarhei.siamas...@nokia.com

The upcoming optimization which is going to be able to replace BILINEAR filter
with NEAREST where appropriate needs to analyze the transformation matrix
and not to make any mistakes.

The changes to affine-test include:
1. Higher chance of using the same scale factor for x and y axes. This can help
   to stress some special cases (for example the case when both x and y scale
   factors are integer). The same applies to x/y translation.
2. Introduced a small chance for corrupting transformation matrix by flipping
   random bits. This supposedly can help to identify the cases when some of the
   fast paths or other code logic is wrongly activated due to insufficient 
checks.
---
 test/affine-test.c |   36 ++--
 1 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/test/affine-test.c b/test/affine-test.c
index ed8000c..ddeca56 100644
--- a/test/affine-test.c
+++ b/test/affine-test.c
@@ -100,13 +100,22 @@ test_composite (int  testnum,
 
 pixman_transform_init_identity (transform);
 
-if (lcg_rand_n (8)  0)
+if (lcg_rand_n (3)  0)
 {
-   scale_x = -32768 * 3 + lcg_rand_N (65536 * 5);
-   scale_y = -32768 * 3 + lcg_rand_N (65536 * 5);
-   translate_x = lcg_rand_N (65536);
-   translate_y = lcg_rand_N (65536);
+   scale_x = -65536 * 3 + lcg_rand_N (65536 * 6);
+   if (lcg_rand_n (2))
+   scale_y = -65536 * 3 + lcg_rand_N (65536 * 6);
+   else
+   scale_y = scale_x;
pixman_transform_init_scale (transform, scale_x, scale_y);
+}
+if (lcg_rand_n (3)  0)
+{
+   translate_x = -65536 * 3 + lcg_rand_N (6 * 65536);
+   if (lcg_rand_n (2))
+   translate_y = -65536 * 3 + lcg_rand_N (6 * 65536);
+   else
+   translate_y = translate_x;
pixman_transform_translate (transform, NULL, translate_x, translate_y);
 }
 
@@ -144,6 +153,21 @@ test_composite (int  testnum,
pixman_transform_translate (transform, NULL, tx, ty);
 }
 
+if (lcg_rand_n (8) == 0)
+{
+   /* Flip random bits */
+   int maxflipcount = 8;
+   while (maxflipcount--)
+   {
+   int i = lcg_rand_n (2);
+   int j = lcg_rand_n (3);
+   int bitnum = lcg_rand_n (32);
+   transform.matrix[i][j] ^= 1  bitnum;
+   if (lcg_rand_n (2))
+   break;
+   }
+}
+
 pixman_image_set_transform (src_img, transform);
 
 switch (lcg_rand_n (4))
@@ -282,6 +306,6 @@ main (int argc, const char *argv[])
 {
 pixman_disable_out_of_bounds_workaround ();
 
-return fuzzer_test_main (affine, 800, 0x4B5D1852,
+return fuzzer_test_main (affine, 800, 0x02A33034,
 test_composite, argc, argv);
 }
-- 
1.6.0.6

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


[Pixman] [PATCH] BILINEAR-NEAREST filter optimization for simple rotation and translation

2011-09-05 Thread Søren Sandmann
From: Siarhei Siamashka siarhei.siamas...@nokia.com

Simple rotation and translation are the additional cases when BILINEAR
filter can be safely reduced to NEAREST.
---
 pixman/pixman-image.c |   39 ++-
 1 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 88262f7..a3bb9b6 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -251,9 +251,46 @@ compute_image_info (pixman_image_t *image)
 case PIXMAN_FILTER_BEST:
flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
 
-   /* Reduce BILINEAR to NEAREST for identity transforms */
+   /* Here we have a chance to optimize BILINEAR filter to NEAREST if
+* they are equivalent for the currently used transformation matrix.
+*/
if (flags  FAST_PATH_ID_TRANSFORM)
+   {
flags |= FAST_PATH_NEAREST_FILTER;
+   }
+   else if (
+   /* affine and integer translation components in matrix ... */
+   ((flags  FAST_PATH_AFFINE_TRANSFORM) 
+!pixman_fixed_frac (image-common.transform-matrix[0][2] |
+image-common.transform-matrix[1][2])) 
+   (
+   /* ... combined with a simple rotation */
+   (flags  (FAST_PATH_ROTATE_90_TRANSFORM |
+ FAST_PATH_ROTATE_180_TRANSFORM |
+ FAST_PATH_ROTATE_270_TRANSFORM)) ||
+   /* ... or combined with a simple non-rotated translation */
+   (image-common.transform-matrix[0][0] == pixman_fixed_1 
+image-common.transform-matrix[1][1] == pixman_fixed_1 
+image-common.transform-matrix[0][1] == 0 
+image-common.transform-matrix[1][0] == 0)
+   )
+   )
+   {
+   /* FIXME: there are some affine-test failures, showing that
+* handling of BILINEAR and NEAREST filter is not quite
+* equivalent when getting close to 32K for the translation
+* components of the matrix. That's likely some bug, but for
+* now just skip BILINEAR-NEAREST optimization in this case.
+*/
+   pixman_fixed_t magic_limit = pixman_int_to_fixed (3);
+   if (image-common.transform-matrix[0][2] = magic_limit  
+   image-common.transform-matrix[1][2] = magic_limit  
+   image-common.transform-matrix[0][2] = -magic_limit 
+   image-common.transform-matrix[1][2] = -magic_limit)
+   {
+   flags |= FAST_PATH_NEAREST_FILTER;
+   }
+   }
break;
 
 case PIXMAN_FILTER_CONVOLUTION:
-- 
1.6.0.6

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


[Pixman] [PATCH] Strength-reduce BILINEAR filter to NEAREST filter for identity transforms

2011-09-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

An image with a bilinear filter and an identity transform is
equivalent to one with a nearest filter, so there is no reason the
standard fast paths shouldn't be usable.

But because a BILINEAR filter samples a 2x2 pixel block in the source
image, FAST_PATH_SAMPLES_COVER_CLIP can't be set in the case where the
source area is the entire image, because some compositing operations
might then read pixels outside the image.

This patch fixes the problem by splitting the
FAST_PATH_SAMPLES_COVER_CLIP flag into two separate flags
FAST_PATH_SAMPLES_COVER_CLIP_NEAREST and
FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR that indicate that the clip
covers the samples taking into account NEAREST/BILINEAR filters
respectively.

All the existing compositing operations that require
FAST_PATH_SAMPLES_COVER_CLIP then have their flags modified to pick
either COVER_CLIP_NEAREST or COVER_CLIP_BILINEAR depending on which
filter they depend on.

In compute_image_info() both COVER_CILP_NEAREST and
COVER_CLIP_BILINEAR can be set depending on how much room there is
around the clip rectangle.

Finally, images with an identity transform and a bilinear filter get
FAST_PATH_NEAREST_FILTER set as well as FAST_PATH_BILINEAR_FILTER.

Performance measurementas with render_bench against Xephyr:

Before

*** ROUND 1 ***
---
Test: Test Xrender doing non-scaled Over blends
Time: 5.720 sec.
---
Test: Test Xrender (offscreen) doing non-scaled Over blends
Time: 5.149 sec.
---
Test: Test Imlib2 doing non-scaled Over blends
Time: 6.237 sec.

After:

*** ROUND 1 ***
---
Test: Test Xrender doing non-scaled Over blends
Time: 4.947 sec.
---
Test: Test Xrender (offscreen) doing non-scaled Over blends
Time: 4.487 sec.
---
Test: Test Imlib2 doing non-scaled Over blends
Time: 6.235 sec.
---
 pixman/pixman-fast-path.c |2 +-
 pixman/pixman-image.c |4 ++
 pixman/pixman-inlines.h   |   12 
 pixman/pixman-private.h   |   19 ++--
 pixman/pixman.c   |   69 
 5 files changed, 65 insertions(+), 41 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index bbdc8e8..033efd7 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1764,7 +1764,7 @@ static const pixman_fast_path_t c_fast_paths[] =
 #define SIMPLE_ROTATE_FLAGS(angle)   \
 (FAST_PATH_ROTATE_ ## angle ## _TRANSFORM  | \
  FAST_PATH_NEAREST_FILTER  | \
- FAST_PATH_SAMPLES_COVER_CLIP  | \
+ FAST_PATH_SAMPLES_COVER_CLIP_NEAREST  | \
  FAST_PATH_STANDARD_FLAGS)
 
 #define SIMPLE_ROTATE_FAST_PATH(op,s,d,suffix)   \
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 84bacf8..88262f7 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -250,6 +250,10 @@ compute_image_info (pixman_image_t *image)
 case PIXMAN_FILTER_GOOD:
 case PIXMAN_FILTER_BEST:
flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
+
+   /* Reduce BILINEAR to NEAREST for identity transforms */
+   if (flags  FAST_PATH_ID_TRANSFORM)
+   flags |= FAST_PATH_NEAREST_FILTER;
break;
 
 case PIXMAN_FILTER_CONVOLUTION:
diff --git a/pixman/pixman-inlines.h b/pixman/pixman-inlines.h
index f1e0cbd..3532867 100644
--- a/pixman/pixman-inlines.h
+++ b/pixman/pixman-inlines.h
@@ -585,7 +585,7 @@ fast_composite_scaled_nearest  ## scale_func_name 
(pixman_implementation_t *imp,
 #define SIMPLE_NEAREST_FAST_PATH_COVER(op,s,d,func)\
 {   PIXMAN_OP_ ## op,  \
PIXMAN_ ## s,   \
-   SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP,\
+   SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST,\
PIXMAN_null, 0, \
PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op,\
@@ -627,7 +627,7 @@ fast_composite_scaled_nearest  ## scale_func_name 
(pixman_implementation_t *imp,
 #define SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER(op,s,d,func)\
 {   PIXMAN_OP_ ## op,  \
PIXMAN_ ## s,   \
-   SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP

[Pixman] [PATCH] Only link with -lpng when libpng is actually available

2011-09-11 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Fixes build on systems that don't have libpng
---
 configure.ac |1 +
 test/Makefile.am |5 -
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index 21613e1..fdb2521 100644
--- a/configure.ac
+++ b/configure.ac
@@ -811,6 +811,7 @@ if test x$have_libpng = xyes; then
 fi
 
 AC_SUBST(HAVE_LIBPNG)
+AM_CONDITIONAL(HAVE_LIBPNG, test $have_libpng = yes)
 
 AC_OUTPUT([pixman-1.pc
pixman-1-uninstalled.pc
diff --git a/test/Makefile.am b/test/Makefile.am
index 52ef8ad..7bd826e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,6 +1,9 @@
 AM_CFLAGS = @OPENMP_CFLAGS@
 AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
-LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng
+LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
+if HAVE_LIBPNG
+LDADD += -lpng
+endif
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
 
 TESTPROGRAMS = \
-- 
1.6.0.6

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


Re: [Pixman] [PATCH] Only link with -lpng when libpng is actually available

2011-09-11 Thread Søren Sandmann

 How about using pkg-config to detect the availability of libpng and
 the flags required to use it?

Good idea. New patch to follow.

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


[Pixman] [PATCH] Use pkg-config to determine the flags to use with libpng

2011-09-11 Thread Søren Sandmann
From: Søren Sandmann Pedersen s...@redhat.com

Previously we would unconditionally link with -lpng leading to build
failures on systems without libpng.
---
 configure.ac |2 +-
 test/Makefile.am |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index 21613e1..dc523df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -804,7 +804,7 @@ AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR)
 dnl ==
 dnl libpng
 
-AC_CHECK_LIB([png], [png_write_info], [have_libpng=yes], [have_libpng=no])
+PKG_CHECK_MODULES(PNG, [libpng], have_libpng=yes, have_libpng=no)
 
 if test x$have_libpng = xyes; then
 AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng])
diff --git a/test/Makefile.am b/test/Makefile.am
index 52ef8ad..6687bed 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,7 @@
 AM_CFLAGS = @OPENMP_CFLAGS@
 AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
-LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng
-INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
+LDADD = $(top_builddir)/pixman/libpixman-1.la -lm  @PNG_LIBS@
+INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman @PNG_CFLAGS@
 
 TESTPROGRAMS = \
a1-trap-test\
-- 
1.6.0.6

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


Re: [Pixman] [PATCH 1/3] Add CLEAR and SRC linear interpolation operators

2011-09-15 Thread Søren Sandmann
Chris Wilson ch...@chris-wilson.co.uk writes:

 Cairo, for instance, has a subtly different interpretation of how to use
 the mask in combination with the Porter-Duff operators. In particular,
 it has the notion of a clip mask, for which pixman has no parallel.

 Quoting Soeren:

   Another aspect is that cairo uses a different rendering equation in some
   cases. The two equations used are:

   unbounded:   [(src IN shape) OP dest  ] LERP_clip dest

   bounded: [(src OP dest) LERP_shape dest   ] LERP_clip dest

   With shaped clips, the LERP_clip part is taken care of, and the first
   equation is already directly supported by pixman. The second one could
   be supported by adding new op_LERP operators that would use the

   (src OP dest) LERP_shape dest

   equation. For cairo's purposes, all we need is CLEAR_LERP and SRC_LERP,
   but I think it could be useful to have the full set of LERP operators.

Did you see Taekyun Kim's reply to this? He proposes this API:

 pixman_image_composite_xrender(op, src, shape, clip, dst)
 pixman_image_composite_bounded(op, src, shape, clip, dst)
 pixman_image_composite_simple(op, src, shape, clip, dst)

instead, which would add direct one-pass support for all of cairo's
compositing schemes, including clip masks. See:

http://lists.freedesktop.org/archives/pixman/2011-August/001420.html


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


Re: [Pixman] [PATCH 1/3] Add CLEAR and SRC linear interpolation operators

2011-09-15 Thread Søren Sandmann
Chris Wilson ch...@chris-wilson.co.uk writes:

 Did you see Taekyun Kim's reply to this? He proposes this API:
 
  pixman_image_composite_xrender(op, src, shape, clip, dst)
  pixman_image_composite_bounded(op, src, shape, clip, dst)
  pixman_image_composite_simple(op, src, shape, clip, dst)
 
 instead, which would add direct one-pass support for all of cairo's
 compositing schemes, including clip masks.

 You're encoding operator semantics into the function call and adding
 parameters for the rest? 

Yes, basically. It's more or less a direct translation of the three
compositing equations that cairo uses into function calls.

 Although pixman could benefit from faster
 methods of rendering polygons, I do not see this as actually reducing
 the amount of code inside Cairo as GL is effectively the lowest common
 demoniator. (Though we desparately need a change in the Render protocol
 so that we can feed polygons to the server more cheaply and that in turn
 merits similar changes in pixman.)

 My gut feeling is that interface is too restrictive. You may as well
 skip polygon images and go to paths and boolean geometry. In the
 meantime providing an interface that matches what Cairo uses today is
 also going to be useful for when you replicate Cairo inside pixman.

The proposed interface is basically orthogonal to the question of
polygons in pixman. Even without polygons or spans in pixman, the
proposed interface is a superset of what cairo needs today in order to
implement fill() and stroke() in one pass (after rasterizing the
polygons).

The polygon question is just about how the shape and clip images could
be given in a more efficient manner. The three compositing equations
that cairo uses are still the same in either case.


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


Re: [Pixman] [PATCH 1/3] Add CLEAR and SRC linear interpolation operators

2011-09-16 Thread Søren Sandmann
Chris Wilson ch...@chris-wilson.co.uk writes:

 On Thu, 15 Sep 2011 13:26:09 +0200, sandm...@cs.au.dk (=?utf-8?Q?S=C3=B8ren?= 
 Sandmann) wrote:
 Chris Wilson ch...@chris-wilson.co.uk writes:
 
  Did you see Taekyun Kim's reply to this? He proposes this API:
  
   pixman_image_composite_xrender(op, src, shape, clip, dst)
   pixman_image_composite_bounded(op, src, shape, clip, dst)
   pixman_image_composite_simple(op, src, shape, clip, dst)
  
  instead, which would add direct one-pass support for all of cairo's
  compositing schemes, including clip masks.
 
  You're encoding operator semantics into the function call and adding
  parameters for the rest? 
 
 Yes, basically. It's more or less a direct translation of the three
 compositing equations that cairo uses into function calls.

 But why three functions when the difference is the semantics of the
 operator. Just allow Cairo to pick the operator that corresponds to Cairo's
 interpretation of op + mask + clip.

I guess that makes sense. I'll take a look at the patch sometime next
week.


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


Re: [Pixman] [PATCH] Fix build on cygwin after commit efdf65c0c4fff551fb3cd9104deda9adb6261e22

2011-09-19 Thread Søren Sandmann
Jon TURNEY jon.tur...@dronecode.org.uk writes:

 libutils depends on pixman and so needs to preceed it in the link order

 Found by tinderbox, see [1]

 [1] http://tinderbox.freedesktop.org/builds/2011-09-15-0005/logs/pixman/#build

Pushed.


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


Re: [Pixman] [PATCH 5/5] Simple repeat: Extend too short source scanlines into temporary buffer

2011-09-21 Thread Søren Sandmann
Hi,

 From: Taekyun Kim tkq@samsung.com

 Too short scanlines can cause repeat handling overhead and optimized
 pixman composite functions usually process a bunch of pixels in a
 single loop iteration it might be beneficial to pre-extend source
 scanlines. The temporary buffers will usually reside in cache, so
 accessing them should be quite efficient.

Generally, this looks good, and it's certainly a big performance
improvement. I do have some comments though.

The main thing I dislike is that it allocates an image on the stack and
then only fills out some of the fields. The problem is if a fast path
some day starts making use of say the flags in the image, then this code
will start to siliently fail.

A solution might be to refactor the image allocation code such that we
can support stack allocated images internally. This could be done by
changing adding _pixman_image_init () and _pixman_bits_image_init()
functions, and then changing _pixman_image_allocate() and
_pixman_bits_image_create() to call those functions. We would need the
corresponding _fini() functions also.

Another possibility might be to call the combiner functions instead of
calling the fast path. Ie., calling

   _pixman_implementation_combine_32 (pixman_implementation_t *imp,
  pixman_op_t  op,
  uint32_t *   dest,
  const uint32_t * src,
  const uint32_t * mask,
  int  width);

instead of the fast path. If we are going to composite scanline by
scanline anyway, then it doesn't seem like there should be any advantage
to the fast paths over the combiners. The important architectures have
SIMD variations of the combiners already.

The potential issue, as Siarhei has pointed out several times, is that
there is currently a bit of overhead from going through all the
implementation-implementation-implementation indirections. Maybe its
time to fix that. A simple fix would be to change the
_pixman_implementation_combine_* functions into
_pixman_implementation_lookup_combine_* functions that would return the
desired combiner instead of calling it. 

This would speed up the general path as well.

Also, a few formatting nit-picks:

  static void
  fast_composite_tiled_repeat (pixman_implementation_t *imp,
pixman_composite_info_t *info)
 @@ -1223,27 +1225,114 @@ fast_composite_tiled_repeat (pixman_implementation_t 
 *imp,
   int32_t sx, sy;
   int32_t width_remain;
   int32_t num_pixels;
 + int32_t src_width;
 + int32_t i, j;
 + pixman_image_t extended_src_image;
 + uint32_t extended_src[REPEAT_MIN_WIDTH*2];

We generally put spaces around * when it is used as a binary operator.

 + if (need_src_extension)
 + {
 + if (src_bpp == 32)
 + {
 + PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint32_t, 
 src_stride, src_line, 1);
 +
 + for (i=0; isrc_width; )
 + {
 + for (j=0; jsrc_image-bits.width; j++, i++)

There are some missing spaces here as well (i=0, j=0, isrc_width etc.)

 + {
 + extended_src[i] = src_line[j];
 + }

Generally braces should only be used when the body is more than one
line, or if the other branch of an if statement has them. They should
not be used if the body is only one line.


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


Re: [Pixman] [PATCH] fill: Special-case single pixel wide lines

2011-09-23 Thread Søren Sandmann
Chris Wilson ch...@chris-wilson.co.uk writes:

 A common condition (in benchmarks at least) are single pixel wide
 vertical lines. This is the worst-cast behaviour for the fast-paths like
 SSE2 which require long runs in order to offset the ramp up cost of
 aligning and using the SIMD registers.

 For example, box-outline consists of drawing a single aligned box with a
 hairline outline:

 before: 2327 (stroke), 2509 (fill)
 after: 674 (stroke), 843 (fill)

 [measured in *ns* on an i7-640]

 (Double-pixel wide lines, such as a stroke-width 1 outline of a
 misaligned box are also very common, but cannot hit pixman_fill(), so
 rapidly diminishing returns for optimising other widths.)

Looks good to me.

Generally, if nobody has said anything for some reasonable length of
time, feel free to push.


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


Re: [Pixman] [PATCH] mmx: fix formats in commented code

2011-09-26 Thread Søren Sandmann
Matt Turner matts...@gmail.com writes:

 b8r8g8 is apparently no longer supported sometime since this code was
 commented.

All three patches look good to me.

If you were benchmarking the over_x888_8_() operation, is it still
slower than the general code?


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


  1   2   3   4   5   6   >