[Pixman] [PATCH] Remove pointless declaration of _pixman_image_get_scanline_generic_64()

2012-08-19 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This declaration used to be necessary when
_pixman_image_get_scanline_generic_64() referred to a structure that
itself referred back to _pixman_image_get_scanline_generic_64().
---
 pixman/pixman-bits-image.c |4 
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index b6c8630..c69e151 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1123,10 +1123,6 @@ bits_image_fetch_untransformed_64 (pixman_iter_t * iter,
 return buffer;
 }
 
-static uint32_t *
-_pixman_image_get_scanline_generic_64 (pixman_iter_t   *iter,
-  const uint32_t * mask);
-
 typedef struct
 {
 pixman_format_code_t   format;
-- 
1.7.4

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


[Pixman] [PATCH] Remove TODO file

2012-08-24 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

It's obsolete and irrelevant.
---
 TODO |  271 --
 1 files changed, 0 insertions(+), 271 deletions(-)
 delete mode 100644 TODO

diff --git a/TODO b/TODO
deleted file mode 100644
index 4434ec7..000
--- a/TODO
+++ /dev/null
@@ -1,271 +0,0 @@
-  - Testing
-- Test implementations against each other
-- Test both with and without the operator strength reduction.
-  They shold be identical.
-
-  - SSE 2 issues:
-
-  - Use MM_HINT_NTA instead of MM_HINT_T0
-
-  - Use of fbCompositeOver_x888x8xsse2()
-
-  - Update the RLEASING file
-
-  - Things to keep in mind if breaking ABI:
-
-  - There should be a guard #ifndef I_AM_EITHER_CAIRO_OR_THE_X_SERVER
-
-  - X server will require 16.16 essentially forever. Can we get
-the required precision by simply adding offset_x/y to the
-relevant rendering API?
-
-  - Get rid of workaround for X server bug.
-
-  - pixman_image_set_indexed() should copy its argument, and X
-should be ported over to use a pixman_image as the
-representation of a Picture, rather than creating one on each
-operation.
-
-  - We should get rid of pixman_set_static_pointers()
-
-  - We should get rid of the various trapezoid helper functions().
-(They only exist because they are theoretically available to
-drivers).
-
-  - 16 bit regions should be deleted
-
-  - There should only be one trap rasterization API.
-
-  - The PIXMAN_g8/c8/etc formats should use the A channel
-to indicate the actual depth. That way PIXMAN_x4c4 and PIXMAN_c8
-   won't collide.
-
-  - Maybe bite the bullet and make configure.ac generate a pixman-types.h
-file that can be included from pixman.h to avoid the #ifdef magic
-in pixman.h
-
-  - Make pixman_region_point_in() survive a NULL box, then fix up
-pixman-compose.c
-
-  - Possibly look into inlining the fetch functions
-
-  - There is a bug with source clipping demonstrated by clip-test in the
-test directory. If we interprete source clipping as given in
-destination coordinates, which is probably the only sane choice,
-then the result should have two red bars down the sides.
-
-  - Test suite
-
-  - Add a general way of dealing with architecture specific
-fast-paths.  The current idea is to have each operation that can
-be optimized is called through a function pointer that is
-initially set to an initialization function that is responsible for
-setting the function pointer to the appropriate fast-path.
-
-  - Go through things marked FIXME
-
-  - Add calls to prepare and finish access where necessary.  grep for
-ACCESS_MEM, and make sure they are correctly wrapped in prepare
-and finish.
-
-  - restore READ/WRITE in the fbcompose combiners since they sometimes
-store directly to destination drawables.
-
-  - It probably makes sense to move the more strange X region API
-into pixman as well, but guarded with PIXMAN_XORG_COMPATIBILITY
-
-  - Reinstate the FbBits typedef? At the moment we don't
-even have the FbBits type; we just use uint32_t everywhere.
-
-Keith says in bug 2335:
-
-The 64-bit code in fb (pixman) is probably broken; it hasn't been
-used in quite some time as PCI (and AGP) is 32-bits wide, so
-doing things 64-bits at a time is a net loss.  To quickly fix
-this, I suggest just using 32-bit datatypes by setting
-IC_SHIFT to 5 for all machines.
-
-  - Consider optimizing the 8/16 bit solid fills in pixman-util.c by
-storing more than one value at a time.
-
-  - Add an image cache to prevent excessive malloc/free. Note that pixman
-needs to be thread safe when used from cairo.
-
-  - Moving to 24.8 coordinates. This is tricky because X is still
-defined as 16.16 and will be basically forever. It's possible we
-could do this by adding extra offset_x/y parameters to the
-trapezoid calls. The X server could then just call the API with
-(0, 0). Cairo would have to make sure that the delta *within* a
-batch of trapezoids does not exceed 16 bit.
-
-  - Consider adding actual backends. Brain dump:
-
-A backend is something that knows how to
-
-  - Create images
-  - Composite three images
-  - Rasterize trapezoids
-  - Do solid fills and blits
-
-These operations are provided by a vtable that the backend will
-create when it is initialized. Initial backends:
-
-  - VMX
-  - SSE2
-  - MMX
-  - Plain Old C
-
-When the SIMD backends are initialized, they will be passed a
-pointer to the Plain Old C backend that they can use for fallback
-purposes.
-
-Images would gain a vtable as well that would contain things like
-
-  - Read scanline
-  - Write scanline
-
-(Or even read_patch/write_patch as suggested b

[Pixman] [PATCH] pixel_checker: Move sRGB conversion into get_limits()

2012-08-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The sRGB conversion has to be done every time the limits are being
computed. Without this fix, pixel_checker_get_min/max() will produce
the wrong results when called from somewhere other than
pixel_checker_check().
---
 test/utils.c |   28 +---
 1 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/test/utils.c b/test/utils.c
index 85b58d0..df16ef5 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -962,6 +962,18 @@ get_limits (const pixel_checker_t *checker, double limit,
color_t *color,
int *ao, int *ro, int *go, int *bo)
 {
+color_t tmp;
+
+if (PIXMAN_FORMAT_TYPE (checker->format) == PIXMAN_TYPE_ARGB_SRGB)
+{
+   tmp.a = color->a;
+   tmp.r = convert_linear_to_srgb (color->r);
+   tmp.g = convert_linear_to_srgb (color->g);
+   tmp.b = convert_linear_to_srgb (color->b);
+
+   color = &tmp;
+}
+
 *ao = convert (color->a + limit, checker->aw, checker->am, checker->as, 
1.0);
 *ro = convert (color->r + limit, checker->rw, checker->rm, checker->rs, 
0.0);
 *go = convert (color->g + limit, checker->gw, checker->gm, checker->gs, 
0.0);
@@ -988,25 +1000,11 @@ pixel_checker_get_min (const pixel_checker_t *checker, 
color_t *color,
 
 pixman_bool_t
 pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel,
-color_t *color_in)
+color_t *color)
 {
 int32_t a_lo, a_hi, r_lo, r_hi, g_lo, g_hi, b_lo, b_hi;
 int32_t ai, ri, gi, bi;
 pixman_bool_t result;
-color_t tmp, *color;
-
-if (PIXMAN_FORMAT_TYPE (checker->format) == PIXMAN_TYPE_ARGB_SRGB)
-{
-   tmp.a = color_in->a;
-   tmp.r = convert_linear_to_srgb (color_in->r);
-   tmp.g = convert_linear_to_srgb (color_in->g);
-   tmp.b = convert_linear_to_srgb (color_in->b);
-   color = &tmp;
-}
-else
-{
-   color = color_in;
-}
 
 pixel_checker_get_min (checker, color, &a_lo, &r_lo, &g_lo, &b_lo);
 pixel_checker_get_max (checker, color, &a_hi, &r_hi, &g_hi, &b_hi);
-- 
1.7.4

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


[Pixman] [PATCH] test/utils.c: Use pow(), not powf() in sRGB conversion routines

2012-08-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

These functions are operating on double precision, so use pow()
instead of powf().
---
 test/utils.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/utils.c b/test/utils.c
index df16ef5..c922ae5 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -772,7 +772,7 @@ convert_srgb_to_linear (double c)
 if (c <= 0.04045)
 return c / 12.92;
 else
-return powf ((c + 0.055) / 1.055, 2.4);
+return pow ((c + 0.055) / 1.055, 2.4);
 }
 
 double
@@ -781,7 +781,7 @@ convert_linear_to_srgb (double c)
 if (c <= 0.0031308)
 return c * 12.92;
 else
-return 1.055 * powf (c, 1.0/2.4) - 0.055;
+return 1.055 * pow (c, 1.0/2.4) - 0.055;
 }
 
 void
-- 
1.7.4

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


Re: [Pixman] [cairo] help building cairo on windows

2012-09-11 Thread Søren Sandmann
Andrea Canciani  writes:

> This reminds me that I have some patches to improve building pixman on win32:
> http://cgit.freedesktop.org/~ranma42/pixman/commit/?h=wip/simpleops-to-master
>
> Soren, is it ok if I push the attached patches?

No objections from me if the test suite still passes with
PIXMAN_DISABLE=sse2 set.


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


Re: [Pixman] pixman hangs in affine-test

2012-09-13 Thread Søren Sandmann
Siarhei Siamashka  writes:

> Hello,
>
> $ test/affine-test 212944861
> src_fmt=2002, dst_fmt=2002
> op=3, scale_x=-6077, scale_y=-148221, repeat=1
> translate_x=105371, translate_y=105371
> src_width=16, src_height=12, dst_width=7, dst_height=2
> src_x=-3, src_y=-3, dst_x=0, dst_y=0
> w=6, h=2
>
> This still needs a separate testcase for the test suite and a bugfix.

Good catch. This branch:

http://cgit.freedesktop.org/~sandmann/pixman/log/?h=infinite-loop

adds a test case. I haven't tried tracking down the bug at all.


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


Re: [Pixman] pixman hangs in affine-test

2012-09-15 Thread Søren Sandmann
Søren Sandmann  writes:

> Good catch. This branch:
>
> http://cgit.freedesktop.org/~sandmann/pixman/log/?h=infinite-loop
>
> adds a test case. I haven't tried tracking down the bug at all.

The infinite loop is caused by an overflow in this expression from
FAST_BILINEAR_MAINLOOP_INT in pixman-inlines.h:

pixman_int_to_fixed (vx + (width - 1) * unit_x) + 1; 

where unit_x is 0x200017bd and width - 1 is 5 so the multiplication
result doesn't fit in a signed 32 bit integer. A simple fix is to just
cast unit_x to int64_t, which is what the following patch does.

However, I don't know this code very well and I'm not convinced that
just casting is the right fix, so review and better suggestions are
welcome.


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


[Pixman] [PATCH 1/3] affine-test: Print out the transformation matrix when verbose

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Printing out the translation and scale is a bit misleading because the
actual transformation matrix can be modified in various other ways.

Instead simply print the whole transformation matrix that is actually
used.
---
 test/affine-test.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/test/affine-test.c b/test/affine-test.c
index 6827cc3..7bc28b4 100644
--- a/test/affine-test.c
+++ b/test/affine-test.c
@@ -200,11 +200,19 @@ test_composite (int  testnum,
 
 if (verbose)
 {
+#define M(r,c) \
+   transform.matrix[r][c]
+
printf ("src_fmt=%08X, dst_fmt=%08X\n", src_fmt, dst_fmt);
-   printf ("op=%d, scale_x=%d, scale_y=%d, repeat=%d\n",
-   op, scale_x, scale_y, repeat);
-   printf ("translate_x=%d, translate_y=%d\n",
-   translate_x, translate_y);
+   printf ("op=%d, repeat=%d, transform=\n",
+   op, repeat);
+   printf (" { { { 0x%08x, 0x%08x, 0x%08x },\n"
+   " { 0x%08x, 0x%08x, 0x%08x },\n"
+   " { 0x%08x, 0x%08x, 0x%08x },\n"
+   " } };\n",
+   M(0,0), M(0,1), M(0,2),
+   M(1,0), M(1,1), M(1,2),
+   M(2,0), M(2,1), M(2,2));
printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
src_width, src_height, dst_width, dst_height);
printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
-- 
1.7.11.4

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


[Pixman] [PATCH 2/3] test: Add inifinite-loop test

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This test demonstrates a bug where a certain transformation matrix can
result in an infinite loop. It was extracted as a standalone version
of "affine-test 212944861".

If given the option -nf, the test program will not call fail_after()
and therefore potentially run forever.
---
 test/Makefile.sources |  1 +
 test/infinite-loop.c  | 39 +++
 2 files changed, 40 insertions(+)
 create mode 100644 test/infinite-loop.c

diff --git a/test/Makefile.sources b/test/Makefile.sources
index fad8c6f..1ecface 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -6,6 +6,7 @@ TESTPROGRAMS =  \
region-translate-test   \
fetch-test  \
oob-test\
+   infinite-loop   \
trap-crasher\
alpha-loop  \
scaling-crash-test  \
diff --git a/test/infinite-loop.c b/test/infinite-loop.c
new file mode 100644
index 000..8a7a2ab
--- /dev/null
+++ b/test/infinite-loop.c
@@ -0,0 +1,39 @@
+#include 
+#include 
+#include 
+#include 
+#include "utils.h"
+
+int
+main (int argc, char **argv)
+{
+#define SRC_WIDTH 16
+#define SRC_HEIGHT 12
+#define DST_WIDTH 7
+#define DST_HEIGHT 2
+
+static const pixman_transform_t transform = {
+   { { 0x200017bd, 0x, 0x000e6465 },
+ { 0x, 0x000a42fd, 0x000e6465 },
+ { 0x, 0x, 0x0001 },
+   }
+};
+pixman_image_t *src, *dest;
+
+src = pixman_image_create_bits (
+   PIXMAN_a8r8g8b8, SRC_WIDTH, SRC_HEIGHT, NULL, -1);
+dest = pixman_image_create_bits (
+   PIXMAN_a8r8g8b8, DST_WIDTH, DST_HEIGHT, NULL, -1);
+
+pixman_image_set_transform (src, &transform);
+pixman_image_set_repeat (src, PIXMAN_REPEAT_NORMAL);
+pixman_image_set_filter (src, PIXMAN_FILTER_BILINEAR, NULL, 0);
+
+if (argc == 1 || strcmp (argv[1], "-nf") != 0)
+   fail_after (1, "infinite loop detected");
+
+pixman_image_composite (
+   PIXMAN_OP_OVER, src, NULL, dest, -3, -3, 0, 0, 0, 0, 6, 2);
+
+return 0;
+}
-- 
1.7.11.4

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


[Pixman] [PATCH 3/3] Possible fix for infinite loop

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The infinite loop detected by "affine-test 212944861" is caused by an
overflow in this expression:

max_x = pixman_fixed_to_int (vx + (width - 1) * unit_x) + 1;

where (width - 1) * unit_x doesn't fit in a signed int.

By casting unit_x to int64_t, the expression no longer overflows and
affine-test 212944861 no longer loops forever.
---
 pixman/pixman-inlines.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pixman/pixman-inlines.h b/pixman/pixman-inlines.h
index 5517de5..3a3c658 100644
--- a/pixman/pixman-inlines.h
+++ b/pixman/pixman-inlines.h
@@ -859,7 +859,7 @@ fast_composite_scaled_bilinear ## scale_func_name 
(pixman_implementation_t *imp,
 {  
\
vx = v.vector[0];   
\
repeat (PIXMAN_REPEAT_NORMAL, &vx, 
pixman_int_to_fixed(src_image->bits.width)); \
-   max_x = pixman_fixed_to_int (vx + (width - 1) * unit_x) + 1;
\
+   max_x = pixman_fixed_to_int (vx + (width - 1) * (int64_t)unit_x) + 1;   
\

\
if (src_image->bits.width < REPEAT_NORMAL_MIN_WIDTH)
\
{   
\
-- 
1.7.11.4

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


[Pixman] [PATCH 1/7] implementation: Write lookup_combiner() in a less convoluted way.

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Instead of initializing an array on the stack, just use a simple
switch to select which set of combiners to look up in.
---
 pixman/pixman-implementation.c |   37 -
 1 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 77d0906..d2573ab 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -121,25 +121,36 @@ _pixman_implementation_lookup_combiner 
(pixman_implementation_t *imp,
pixman_bool_t
component_alpha,
pixman_bool_tnarrow)
 {
-pixman_combine_32_func_t f;
-
-do
+while (imp)
 {
-   pixman_combine_32_func_t (*combiners[]) =
+   pixman_combine_32_func_t f = NULL;
+
+   switch ((narrow << 1) | component_alpha)
{
-   (pixman_combine_32_func_t *)imp->combine_64,
-   (pixman_combine_32_func_t *)imp->combine_64_ca,
-   imp->combine_32,
-   imp->combine_32_ca,
-   };
+   case 0: /* not narrow, not component alpha */
+   f = (pixman_combine_32_func_t)imp->combine_64[op];
+   break;
+   
+   case 1: /* not narrow, component_alpha */
+   f = (pixman_combine_32_func_t)imp->combine_64_ca[op];
+   break;
+
+   case 2: /* narrow, not component alpha */
+   f = imp->combine_32[op];
+   break;
+
+   case 3: /* narrow, component_alpha */
+   f = imp->combine_32_ca[op];
+   break;
+   }
 
-   f = combiners[component_alpha | (narrow << 1)][op];
+   if (f)
+   return f;
 
imp = imp->delegate;
 }
-while (!f);
 
-return f;
+return NULL;
 }
 
 pixman_bool_t
-- 
1.7.4

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


[Pixman] [PATCH 0/7] Clean up delegation logic

2012-09-15 Thread Søren Sandmann
Hi,

The following patches move all the delegation logic into
pixman-implementation.c and then, since the chain of implementations
no longer has anything to do with the delegation design pattern,
rename "delegate" to "fallback".

It's a net win of 227 lines of code, and makes pixman-implementation.c
look a lot nicer because all the trivial "delegate_blah()" functions
go away.

There are some changes to the NEON and DSPr2 backends that I haven't
tried to compile. If there are any problems there, please let me know.

Thanks,
Soren

 pixman-arm-neon.c   |   89 +++
 pixman-fast-path.c  |6 -
 pixman-general.c|   46 +---
 pixman-glyph.c  |4 
 pixman-implementation.c |  276 
 pixman-mips-dspr2.c |   89 +++
 pixman-mmx.c|  119 ++--
 pixman-noop.c   |   14 +-
 pixman-private.h|   36 +++---
 pixman-sse2.c   |  146 -
 pixman-utils.c  |  112 ---
 pixman.c|2 
 12 files changed, 356 insertions(+), 583 deletions(-)

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


[Pixman] [PATCH 2/7] Move blt delegation into pixman-implementation.c

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Rather than require each individual implementation to do the
delegation for blt, just do it in pixman-implementation.c whenever the
implementation blt returns FALSE.

With this change, there is no longer any reason for the
implementations to have one blt function that delegates and one that
actually blits, so consolidate those in the NEON, DSPr2, SSE2, and MMX
implementations.
---
 pixman/pixman-arm-neon.c   |   54 +++---
 pixman/pixman-general.c|   21 
 pixman/pixman-implementation.c |   40 +--
 pixman/pixman-mips-dspr2.c |   54 +++---
 pixman/pixman-mmx.c|   68 +++---
 pixman/pixman-sse2.c   |   69 +++
 6 files changed, 81 insertions(+), 225 deletions(-)

diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index ca139de..f4cc0ba 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -227,18 +227,19 @@ pixman_fill_neon (uint32_t *bits,
 }
 
 static pixman_bool_t
-pixman_blt_neon (uint32_t *src_bits,
- uint32_t *dst_bits,
- int   src_stride,
- int   dst_stride,
- int   src_bpp,
- int   dst_bpp,
- int   src_x,
- int   src_y,
- int   dest_x,
- int   dest_y,
- int   width,
- int   height)
+arm_neon_blt (pixman_implementation_t *imp,
+  uint32_t *   src_bits,
+  uint32_t *   dst_bits,
+  int  src_stride,
+  int  dst_stride,
+  int  src_bpp,
+  int  dst_bpp,
+  int  src_x,
+  int  src_y,
+  int  dest_x,
+  int  dest_y,
+  int  width,
+  int  height)
 {
 if (src_bpp != dst_bpp)
return FALSE;
@@ -423,35 +424,6 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
 };
 
 static pixman_bool_t
-arm_neon_blt (pixman_implementation_t *imp,
-  uint32_t *   src_bits,
-  uint32_t *   dst_bits,
-  int  src_stride,
-  int  dst_stride,
-  int  src_bpp,
-  int  dst_bpp,
-  int  src_x,
-  int  src_y,
-  int  dest_x,
-  int  dest_y,
-  int  width,
-  int  height)
-{
-if (!pixman_blt_neon (
-src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-src_x, src_y, dest_x, dest_y, width, height))
-
-{
-   return _pixman_implementation_blt (
-   imp->delegate,
-   src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-   src_x, src_y, dest_x, dest_y, width, height);
-}
-
-return TRUE;
-}
-
-static pixman_bool_t
 arm_neon_fill (pixman_implementation_t *imp,
uint32_t *   bits,
int  stride,
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index d4b2daa..dcf9bfc 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -201,26 +201,6 @@ static const pixman_fast_path_t general_fast_path[] =
 };
 
 static pixman_bool_t
-general_blt (pixman_implementation_t *imp,
- uint32_t *   src_bits,
- uint32_t *   dst_bits,
- int  src_stride,
- int  dst_stride,
- int  src_bpp,
- int  dst_bpp,
- int  src_x,
- int  src_y,
- int  dest_x,
- int  dest_y,
- int  width,
- int  height)
-{
-/* We can't blit unless we have sse2 or mmx */
-
-return FALSE;
-}
-
-static pixman_bool_t
 general_fill (pixman_implementation_t *imp,
   uint32_t *   bits,
   int  stride,
@@ -242,7 +222,6 @@ _pixman_implementation_create_general (void)
 _pixman_setup_combiner_functions_32 (imp);
 _pixman_setup_combiner_functions_64 (imp);
 
-imp->blt = general_blt;
 imp->fill = general_fill;
 imp->src_iter_init = general_src_iter_init;
 im

[Pixman] [PATCH 3/7] Move fill delegation into pixman-implementation.c

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

As in the blt commit, do the delegation in pixman-implementation.c
whenever the implementation fill returns FALSE instead of relying on
each implementation to do it by itself.

With this change there is no longer any reason for the implementations
to have one fill function that delegates and one that actually blits,
so consolidate those in the NEON, DSPr2, SSE2, and MMX
implementations.
---
 pixman/pixman-arm-neon.c   |   35 +--
 pixman/pixman-fast-path.c  |4 +--
 pixman/pixman-general.c|   15 
 pixman/pixman-implementation.c |   30 +++-
 pixman/pixman-mips-dspr2.c |   35 +--
 pixman/pixman-mmx.c|   45 +++--
 pixman/pixman-sse2.c   |   71 ++-
 7 files changed, 71 insertions(+), 164 deletions(-)

diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index f4cc0ba..60e9c78 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -183,14 +183,15 @@ pixman_composite_src_n__asm_neon (int32_t   w,
   uint32_t  src);
 
 static pixman_bool_t
-pixman_fill_neon (uint32_t *bits,
-  int   stride,
-  int   bpp,
-  int   x,
-  int   y,
-  int   width,
-  int   height,
-  uint32_t  _xor)
+arm_neon_fill (pixman_implementation_t *imp,
+   uint32_t *   bits,
+   int  stride,
+   int  bpp,
+   int  x,
+   int  y,
+   int  width,
+   int  height,
+  uint32_t _xor)
 {
 /* stride is always multiple of 32bit units in pixman */
 uint32_t byte_stride = stride * sizeof(uint32_t);
@@ -423,24 +424,6 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
 { PIXMAN_OP_NONE },
 };
 
-static pixman_bool_t
-arm_neon_fill (pixman_implementation_t *imp,
-   uint32_t *   bits,
-   int  stride,
-   int  bpp,
-   int  x,
-   int  y,
-   int  width,
-   int  height,
-   uint32_t xor)
-{
-if (pixman_fill_neon (bits, stride, bpp, x, y, width, height, xor))
-   return TRUE;
-
-return _pixman_implementation_fill (
-   imp->delegate, bits, stride, bpp, x, y, width, height, xor);
-}
-
 #define BIND_COMBINE_U(name) \
 void \
 pixman_composite_scanline_##name##_mask_asm_neon (int32_t w, \
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 9778b0c..d26f6e7 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -2192,9 +2192,7 @@ fast_path_fill (pixman_implementation_t *imp,
break;
 
 default:
-   return _pixman_implementation_fill (
-   imp->delegate, bits, stride, bpp, x, y, width, height, xor);
-   break;
+   return FALSE;
 }
 
 return TRUE;
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index dcf9bfc..6c6bda0 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -200,20 +200,6 @@ static const pixman_fast_path_t general_fast_path[] =
 { PIXMAN_OP_NONE }
 };
 
-static pixman_bool_t
-general_fill (pixman_implementation_t *imp,
-  uint32_t *   bits,
-  int  stride,
-  int  bpp,
-  int  x,
-  int  y,
-  int  width,
-  int  height,
-  uint32_t xor)
-{
-return FALSE;
-}
-
 pixman_implementation_t *
 _pixman_implementation_create_general (void)
 {
@@ -222,7 +208,6 @@ _pixman_implementation_create_general (void)
 _pixman_setup_combiner_functions_32 (imp);
 _pixman_setup_combiner_functions_64 (imp);
 
-imp->fill = general_fill;
 imp->src_iter_init = general_src_iter_init;
 imp->dest_iter_init = general_dest_iter_init;
 
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 8b07848..5607f9d 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -27,21 +27,6 @@
 #include 
 #include "pixman-private.h"
 
-static pixman_bool_t
-delegate_fill (pixman_implementation_t *imp,
-   uint32_t *   bits,
-   int  stride,
-   int 

[Pixman] [PATCH 4/7] Move delegation of src/dest iter init into pixman-implementation.c

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Instead of relying on each implementation to delegate when an iterator
can't be initialized, change the type of iterator initializers to
boolean and make pixman-implementation.c do the delegation whenever an
iterator initializer returns FALSE.
---
 pixman/pixman-general.c|   10 +++-
 pixman/pixman-implementation.c |   42 ---
 pixman/pixman-mmx.c|6 ++--
 pixman/pixman-noop.c   |   14 
 pixman/pixman-private.h|8 +++---
 pixman/pixman-sse2.c   |6 ++--
 6 files changed, 49 insertions(+), 37 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 6c6bda0..42a84a0 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -37,7 +37,7 @@
 #include 
 #include "pixman-private.h"
 
-static void
+static pixman_bool_t
 general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
 pixman_image_t *image = iter->image;
@@ -54,18 +54,24 @@ general_src_iter_init (pixman_implementation_t *imp, 
pixman_iter_t *iter)
_pixman_bits_image_src_iter_init (image, iter);
 else
_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
+
+return TRUE;
 }
 
-static void
+static pixman_bool_t
 general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
 if (iter->image->type == BITS)
 {
_pixman_bits_image_dest_iter_init (iter->image, iter);
+
+   return TRUE;
 }
 else
 {
_pixman_log_error (FUNC, "Trying to write to a non-writable image");
+
+   return FALSE;
 }
 }
 
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 5607f9d..18da162 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -27,20 +27,6 @@
 #include 
 #include "pixman-private.h"
 
-static void
-delegate_src_iter_init (pixman_implementation_t *imp,
-   pixman_iter_t *  iter)
-{
-imp->delegate->src_iter_init (imp->delegate, iter);
-}
-
-static void
-delegate_dest_iter_init (pixman_implementation_t *imp,
-pixman_iter_t *  iter)
-{
-imp->delegate->dest_iter_init (imp->delegate, iter);
-}
-
 pixman_implementation_t *
 _pixman_implementation_create (pixman_implementation_t *delegate,
   const pixman_fast_path_t *fast_paths)
@@ -63,8 +49,8 @@ _pixman_implementation_create (pixman_implementation_t 
*delegate,
  */
 imp->blt = NULL;
 imp->fill = NULL;
-imp->src_iter_init = delegate_src_iter_init;
-imp->dest_iter_init = delegate_dest_iter_init;
+imp->src_iter_init = NULL;
+imp->dest_iter_init = NULL;
 
 imp->fast_paths = fast_paths;
 
@@ -173,7 +159,7 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
 return FALSE;
 }
 
-void
+pixman_bool_t
 _pixman_implementation_src_iter_init (pixman_implementation_t  *imp,
  pixman_iter_t *iter,
  pixman_image_t*image,
@@ -194,10 +180,18 @@ _pixman_implementation_src_iter_init 
(pixman_implementation_t *imp,
 iter->iter_flags = iter_flags;
 iter->image_flags = image_flags;
 
-(*imp->src_iter_init) (imp, iter);
+while (imp)
+{
+   if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
+   return TRUE;
+
+   imp = imp->delegate;
+}
+
+return FALSE;
 }
 
-void
+pixman_bool_t
 _pixman_implementation_dest_iter_init (pixman_implementation_t *imp,
   pixman_iter_t*iter,
   pixman_image_t   *image,
@@ -218,7 +212,15 @@ _pixman_implementation_dest_iter_init 
(pixman_implementation_t *imp,
 iter->iter_flags = iter_flags;
 iter->image_flags = image_flags;
 
-(*imp->dest_iter_init) (imp, iter);
+while (imp)
+{
+   if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
+   return TRUE;
+
+   imp = imp->delegate;
+}
+
+return FALSE;
 }
 
 pixman_bool_t
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 5deb9a4..c02595d 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -3914,7 +3914,7 @@ static const fetcher_info_t fetchers[] =
 { PIXMAN_null }
 };
 
-static void
+static pixman_bool_t
 mmx_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
 pixman_image_t *image = iter->image;
@@ -3939,12 +3939,12 @@ mmx_src_iter_init (pixman_implementation_t *imp, 
pixman_iter_t *iter)
iter->stride = s;
 
iter->get_scanline = f->get_scanline;
-   return;
+   return TRUE;
}
}
 }
 
-imp->delegate->src_iter_

[Pixman] [PATCH 5/7] Rename _pixman_lookup_composite_function() to _pixman_implementation_lookup_composite()

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

And move it into pixman-implementation.c which is where it belongs
logically.
---
 pixman/pixman-fast-path.c  |2 +-
 pixman/pixman-glyph.c  |4 +-
 pixman/pixman-implementation.c |  112 
 pixman/pixman-private.h|   24 
 pixman/pixman-utils.c  |  112 
 pixman/pixman.c|2 +-
 6 files changed, 128 insertions(+), 128 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index d26f6e7..83c317f 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1258,7 +1258,7 @@ fast_composite_tiled_repeat (pixman_implementation_t *imp,
mask_flags = FAST_PATH_IS_OPAQUE;
 }
 
-if (_pixman_lookup_composite_function (
+if (_pixman_implementation_lookup_composite (
imp->toplevel, info->op,
src_image->common.extended_format_code, src_flags,
mask_format, mask_flags,
diff --git a/pixman/pixman-glyph.c b/pixman/pixman-glyph.c
index cbc3637..30a4099 100644
--- a/pixman/pixman-glyph.c
+++ b/pixman/pixman-glyph.c
@@ -464,7 +464,7 @@ pixman_composite_glyphs_no_mask (pixman_op_top,
glyph_format = glyph_img->common.extended_format_code;
glyph_flags = glyph_img->common.flags;

-   _pixman_lookup_composite_function (
+   _pixman_implementation_lookup_composite (
get_implementation(), op,
src->common.extended_format_code, src->common.flags,
glyph_format, glyph_flags | extra,
@@ -576,7 +576,7 @@ add_glyphs (pixman_glyph_cache_t *cache,
white_src = TRUE;
}
 
-   _pixman_lookup_composite_function (
+   _pixman_implementation_lookup_composite (
get_implementation(), PIXMAN_OP_ADD,
src_format, info.src_flags,
mask_format, info.mask_flags,
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 18da162..1da9d82 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -65,6 +65,118 @@ _pixman_implementation_create (pixman_implementation_t 
*delegate,
 return imp;
 }
 
+#define N_CACHED_FAST_PATHS 8
+
+typedef struct
+{
+struct
+{
+   pixman_implementation_t *   imp;
+   pixman_fast_path_t  fast_path;
+} cache [N_CACHED_FAST_PATHS];
+} cache_t;
+
+PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
+
+pixman_bool_t
+_pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
+pixman_op_t   op,
+pixman_format_code_t  src_format,
+uint32_t  src_flags,
+pixman_format_code_t  mask_format,
+uint32_t  mask_flags,
+pixman_format_code_t  dest_format,
+uint32_t  dest_flags,
+pixman_implementation_t **out_imp,
+pixman_composite_func_t  *out_func)
+{
+pixman_implementation_t *imp;
+cache_t *cache;
+int i;
+
+/* Check cache for fast paths */
+cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
+
+for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
+{
+   const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
+
+   /* Note that we check for equality here, not whether
+* the cached fast path matches. This is to prevent
+* us from selecting an overly general fast path
+* when a more specific one would work.
+*/
+   if (info->op == op  &&
+   info->src_format == src_format  &&
+   info->mask_format == mask_format&&
+   info->dest_format == dest_format&&
+   info->src_flags == src_flags&&
+   info->mask_flags == mask_flags  &&
+   info->dest_flags == dest_flags  &&
+   info->func)
+   {
+   *out_imp = cache->cache[i].imp;
+   *out_func = cache->cache[i].fast_path.func;
+
+   goto update_cache;
+   }
+}
+
+for (imp = toplevel; imp != NULL; imp = imp->delegate)
+{
+   const pixman_fast_path_t *info = imp->fast_paths;
+
+   while (info->op != PIXMAN_OP_NONE)
+   {
+   if ((info->op == op || info->op == PIXMAN_OP_any)   &&
+   /* Formats */
+   ((info->src_format == src_format) ||
+

[Pixman] [PATCH 6/7] _pixman_implementation_create(): Initialize implementation with memset()

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

All the function pointers are NULL by default now, so we can just zero
the struct. Also write the function a little more compactly.
---
 pixman/pixman-implementation.c |   35 +++
 1 files changed, 11 insertions(+), 24 deletions(-)

diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 1da9d82..f371172 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -31,35 +31,22 @@ pixman_implementation_t *
 _pixman_implementation_create (pixman_implementation_t *delegate,
   const pixman_fast_path_t *fast_paths)
 {
-pixman_implementation_t *imp = malloc (sizeof (pixman_implementation_t));
-pixman_implementation_t *d;
-int i;
-
-if (!imp)
-   return NULL;
+pixman_implementation_t *imp;
 
 assert (fast_paths);
 
-/* Make sure the whole delegate chain has the right toplevel */
-imp->delegate = delegate;
-for (d = imp; d != NULL; d = d->delegate)
-   d->toplevel = imp;
-
-/* Fill out function pointers with ones that just delegate
- */
-imp->blt = NULL;
-imp->fill = NULL;
-imp->src_iter_init = NULL;
-imp->dest_iter_init = NULL;
+if ((imp = malloc (sizeof (pixman_implementation_t
+{
+   pixman_implementation_t *d;
 
-imp->fast_paths = fast_paths;
+   memset (imp, 0, sizeof *imp);
 
-for (i = 0; i < PIXMAN_N_OPERATORS; ++i)
-{
-   imp->combine_32[i] = NULL;
-   imp->combine_64[i] = NULL;
-   imp->combine_32_ca[i] = NULL;
-   imp->combine_64_ca[i] = NULL;
+   imp->delegate = delegate;
+   imp->fast_paths = fast_paths;
+   
+   /* Make sure the whole delegate chain has the right toplevel */
+   for (d = imp; d != NULL; d = d->delegate)
+   d->toplevel = imp;
 }
 
 return imp;
-- 
1.7.4

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


[Pixman] [PATCH 7/7] implementation: Rename delegate to fallback

2012-09-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

At this point the chain of implementations has nothing to do with the
delegation design pattern anymore, so rename the delegate pointer to
'fallback'.
---
 pixman/pixman-implementation.c |   20 ++--
 pixman/pixman-private.h|4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index f371172..5dd0501 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -28,7 +28,7 @@
 #include "pixman-private.h"
 
 pixman_implementation_t *
-_pixman_implementation_create (pixman_implementation_t *delegate,
+_pixman_implementation_create (pixman_implementation_t *fallback,
   const pixman_fast_path_t *fast_paths)
 {
 pixman_implementation_t *imp;
@@ -41,11 +41,11 @@ _pixman_implementation_create (pixman_implementation_t 
*delegate,
 
memset (imp, 0, sizeof *imp);
 
-   imp->delegate = delegate;
+   imp->fallback = fallback;
imp->fast_paths = fast_paths;

-   /* Make sure the whole delegate chain has the right toplevel */
-   for (d = imp; d != NULL; d = d->delegate)
+   /* Make sure the whole fallback chain has the right toplevel */
+   for (d = imp; d != NULL; d = d->fallback)
d->toplevel = imp;
 }
 
@@ -109,7 +109,7 @@ _pixman_implementation_lookup_composite 
(pixman_implementation_t  *toplevel,
}
 }
 
-for (imp = toplevel; imp != NULL; imp = imp->delegate)
+for (imp = toplevel; imp != NULL; imp = imp->fallback)
 {
const pixman_fast_path_t *info = imp->fast_paths;
 
@@ -196,7 +196,7 @@ _pixman_implementation_lookup_combiner 
(pixman_implementation_t *imp,
if (f)
return f;
 
-   imp = imp->delegate;
+   imp = imp->fallback;
 }
 
 return NULL;
@@ -227,7 +227,7 @@ _pixman_implementation_blt (pixman_implementation_t * imp,
return TRUE;
}
 
-   imp = imp->delegate;
+   imp = imp->fallback;
 }
 
 return FALSE;
@@ -252,7 +252,7 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
return TRUE;
}
 
-   imp = imp->delegate;
+   imp = imp->fallback;
 }
 
 return FALSE;
@@ -284,7 +284,7 @@ _pixman_implementation_src_iter_init 
(pixman_implementation_t   *imp,
if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
return TRUE;
 
-   imp = imp->delegate;
+   imp = imp->fallback;
 }
 
 return FALSE;
@@ -316,7 +316,7 @@ _pixman_implementation_dest_iter_init 
(pixman_implementation_t  *imp,
if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
return TRUE;
 
-   imp = imp->delegate;
+   imp = imp->fallback;
 }
 
 return FALSE;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index e671508..b9c8319 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -466,7 +466,7 @@ typedef struct
 struct pixman_implementation_t
 {
 pixman_implementation_t *  toplevel;
-pixman_implementation_t *  delegate;
+pixman_implementation_t *  fallback;
 const pixman_fast_path_t * fast_paths;
 
 pixman_blt_func_t  blt;
@@ -486,7 +486,7 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
  pixman_format_code_t format);
 
 pixman_implementation_t *
-_pixman_implementation_create (pixman_implementation_t *delegate,
+_pixman_implementation_create (pixman_implementation_t *fallback,
   const pixman_fast_path_t *fast_paths);
 
 pixman_bool_t
-- 
1.7.4

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


Re: [Pixman] [PATCH] build: Support building Loongson code for 2e, 2f, 3a

2012-09-19 Thread Søren Sandmann
Matt Turner  writes:

> pixman/Makefile.am contains a hack that allows pixman-mmx.c to
> be compiled with different overriding CFLAGS, since automake
> seriously doesn't have a way to do this. Seriously stupid.
>
> It works by defining a new rule and recursively calling make
> with modified CFLAGS set.
>
> Note the difference between the USE_LOONGSON* and HAVE_LOONGSON*
> preprocessor macros.
>
> Cc: Cyril Brulebois 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=51451
> ---

> This patch applies on top of the previous.

The DEP patch looks good to me. Apparently the "DEP" stuff was present
in the first check-in but never used.

> Although the build system works, linking unfortunately doesn't. gcc
> refuses to link object files that have been compiled with different
> -march=loongson* options together. This sucks.
>
> I'm not sure what to do. I guess I could make them separate shared
> objects or even dlopen them, but that really sucks, especially when
> I don't see a reason why gcc shouldn't be able to link this code
> together.
>
> Anyone have any other ideas?

If the shared library thing works, I'm fine with it.

Another idea is to use some objcopy or elfedit hack where the binary
files are edited to have the same architecture. That's not exactly
beautiful either, though.

> It's really obnoxious that there's not just a simple -mloongson-mmi
> flag irrespective of -march=...

This probably just have to be fixed in GCC or the linker.

We have a similar obnoxiousness in x86 where the -mmmx/-msse flags mean
two separate things at the same time: "the compiler may generate mmx/sse
instructions" and "the files may use mmx/sse intrinsics". But at least
the linker doesn't refuse to link files compiled with different such
flags.


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


[Pixman] [PATCH] Fix bugs in component alpha combiners for separable PDF operators

2012-09-19 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

In general, the component alpha version of an operator is supposed to
do this:

   - multiply source with mask in all channels
   - multiply mask with source alpha in all channels
   - compute the regular operator in all channels using the
 mask value whenever source alpha is called for

The first two steps are usually accomplished with the function
combine_mask_ca(), but for operators where source alpha is not used,
such as SRC, ADD and OUT, the simpler function
combine_mask_value_ca(), which doesn't compute the new mask values,
can be used.

However, the PDF blend modes generally *do* make use of source alpha,
so they can't use combine_mask_value_ca() as they do now. They have to
use combine_mask_ca().

This patch fixes this in combine_multiply_ca() and the CA combiners
generated by PDF_SEPARABLE_BLEND_MODE.
---
 pixman/pixman-combine.c.template |4 ++--
 test/blitters-test.c |2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template
index cd008d9..50d2b0a 100644
--- a/pixman/pixman-combine.c.template
+++ b/pixman/pixman-combine.c.template
@@ -489,7 +489,7 @@ combine_multiply_ca (pixman_implementation_t *imp,
comp4_t r = d;
comp4_t dest_ia = ALPHA_c (~d);
 
-   combine_mask_value_ca (&s, &m);
+   combine_mask_ca (&s, &m);
 
UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (r, ~m, s, dest_ia);
UNcx4_MUL_UNcx4 (d, s);
@@ -546,7 +546,7 @@ combine_multiply_ca (pixman_implementation_t *imp,
comp1_t ida = ~da;  \
comp4_t result; \
\
-   combine_mask_value_ca (&s, &m); \
+   combine_mask_ca (&s, &m);   \
\
result = d; \
UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 6a3cc86..8c46cef 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -395,6 +395,6 @@ main (int argc, const char *argv[])
 }
 
 return fuzzer_test_main("blitters", 200,
-   0xA364B5BF,
+   0x3E1DD2E8,
test_composite, argc, argv);
 }
-- 
1.7.4

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


[Pixman] [PATCH 2/2] Fix bug in fast_composite_scaled_nearest()

2012-09-19 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The fast_composite_scaled_nearest() function can be called when the
format is x8b8g8r8. In that case pixels fetched in fetch_nearest()
need to have their alpha channel set to 0xff.

Fixes test suite failure in scaling-test.
---
 pixman/pixman-fast-path.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 9778b0c..53fc784 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1458,7 +1458,7 @@ fetch_nearest (pixman_repeat_t src_repeat,
 {
 if (repeat (src_repeat, &x, src_width))
 {
-   if (format == PIXMAN_x8r8g8b8)
+   if (format == PIXMAN_x8r8g8b8 || format == PIXMAN_x8b8g8r8)
return *(src + x) | 0xff00;
else
return *(src + x);
-- 
1.7.4

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


[Pixman] [PATCH 1/2] Add PIXMAN_x8b8g8r8 and PIXMAN_a8b8g8r8 formats to scaling-test

2012-09-19 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Update the CRC values based on what the general implementation
reports. This reveals a bug in the fast implementation:

% env PIXMAN_DISABLE="mmx sse2" ./test/scaling-test
pixman: Disabled mmx implementation
pixman: Disabled sse2 implementation
scaling test failed! (checksum=AA722B06, expected 03A23E0C)

vs.

% env PIXMAN_DISABLE="mmx sse2 fast" ./test/scaling-test
pixman: Disabled fast implementation
pixman: Disabled mmx implementation
pixman: Disabled sse2 implementation
scaling test passed (checksum=03A23E0C)
---
 test/scaling-test.c |   40 +++-
 1 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/test/scaling-test.c b/test/scaling-test.c
index 44c4f3d..2736123 100644
--- a/test/scaling-test.c
+++ b/test/scaling-test.c
@@ -20,6 +20,31 @@
 /*
  * Composite operation with pseudorandom images
  */
+
+static pixman_format_code_t
+get_format (int bpp)
+{
+if (bpp == 4)
+{
+   switch (lcg_rand_n (4))
+   {
+   default:
+   case 0:
+   return PIXMAN_a8r8g8b8;
+   case 1:
+   return PIXMAN_x8r8g8b8;
+   case 2:
+   return PIXMAN_a8b8g8r8;
+   case 3:
+   return PIXMAN_x8b8g8r8;
+   }
+}
+else
+{
+   return PIXMAN_r5g6b5;
+}
+}
+
 uint32_t
 test_composite (int  testnum,
int  verbose)
@@ -124,11 +149,8 @@ test_composite (int  testnum,
 for (i = 0; i < dst_stride * dst_height; i++)
*((uint8_t *)dstbuf + i) = lcg_rand_n (256);
 
-src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ?
-  PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : 
PIXMAN_r5g6b5;
-
-dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ?
-  PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : 
PIXMAN_r5g6b5;
+src_fmt = get_format (src_bpp);
+dst_fmt = get_format (dst_bpp);
 
 src_img = pixman_image_create_bits (
 src_fmt, src_width, src_height, srcbuf, src_stride);
@@ -322,7 +344,7 @@ test_composite (int  testnum,
pixman_image_composite (op, src_img, mask_img, dst_img,
 src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);
 
-if (dst_fmt == PIXMAN_x8r8g8b8)
+if (dst_fmt == PIXMAN_x8r8g8b8 || dst_fmt == PIXMAN_x8b8g8r8)
 {
/* ignore unused part */
for (i = 0; i < dst_stride * dst_height / 4; i++)
@@ -358,11 +380,11 @@ test_composite (int  testnum,
 }
 
 #if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x80DF1CB2
+#define CHECKSUM 0x8D3A7539
 #elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x2818D5FB
+#define CHECKSUM 0x03A23E0C
 #elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0x387540A5
+#define CHECKSUM 0xE96D1A5E
 #else
 #define CHECKSUM 0x
 #endif
-- 
1.7.4

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


[Pixman] [PATCH 1/2] Add rotate-test.c test program

2012-09-20 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This program exercises a bug in pixman-image.c where "-1" and "1" were
used instead of the correct "- pixman_fixed_1" and "pixman_fixed_1".

With the fast implementation enabled:

 % ./rotate-test
 rotate test failed! (checksum=672ED720, expected 721947E4)

Without it:

 % env PIXMAN_DISABLE=fast ./rotate-test
 pixman: Disabled fast implementation
 rotate test passed (checksum=721947E4)
---
 test/Makefile.sources |1 +
 test/rotate-test.c|  112 +
 2 files changed, 113 insertions(+), 0 deletions(-)
 create mode 100644 test/rotate-test.c

diff --git a/test/Makefile.sources b/test/Makefile.sources
index fad8c6f..3e37e32 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -5,6 +5,7 @@ TESTPROGRAMS =  \
region-test \
region-translate-test   \
fetch-test  \
+   rotate-test \
oob-test\
trap-crasher\
alpha-loop  \
diff --git a/test/rotate-test.c b/test/rotate-test.c
new file mode 100644
index 000..dabdf8e
--- /dev/null
+++ b/test/rotate-test.c
@@ -0,0 +1,112 @@
+#include 
+#include "utils.h"
+
+#define WIDTH  32
+#define HEIGHT 32
+
+static const pixman_format_code_t formats[] =
+{
+PIXMAN_a8r8g8b8,
+PIXMAN_a8b8g8r8,
+PIXMAN_x8r8g8b8,
+PIXMAN_x8b8g8r8,
+PIXMAN_r5g6b5,
+PIXMAN_b5g6r5,
+PIXMAN_a8,
+PIXMAN_a1,
+};
+
+static const pixman_op_t ops[] =
+{
+PIXMAN_OP_OVER,
+PIXMAN_OP_SRC,
+PIXMAN_OP_ADD,
+};
+
+#define TRANSFORM(v00, v01, v10, v11)  \
+{ { { v00, v01, WIDTH * pixman_fixed_1 / 2 },  
\
+   { v10, v11, HEIGHT * pixman_fixed_1 / 2 },  
\
+   { 0, 0, pixman_fixed_1 } } } 
+
+#define F1 pixman_fixed_1
+
+static const pixman_transform_t transforms[] =
+{
+TRANSFORM (0, -1, 1, 0),   /* wrong 90 degree rotation */
+TRANSFORM (0, 1, -1, 0),   /* wrong 270 degree rotation */
+TRANSFORM (1, 0, 0, 1),/* wrong identity */
+TRANSFORM (-1, 0, 0, -1),  /* wrong 180 degree rotation */
+TRANSFORM (0, -F1, F1, 0), /* correct 90 degree rotation */
+TRANSFORM (0, F1, -F1, 0), /* correct 270 degree rotation */
+TRANSFORM (F1, 0, 0, F1),  /* correct identity */
+TRANSFORM (-F1, 0, 0, -F1),/* correct 180 degree rotation 
*/
+};
+
+#define RANDOM_FORMAT()
\
+(formats[lcg_rand_n (ARRAY_LENGTH (formats))])
+
+#define RANDOM_OP()\
+(ops[lcg_rand_n (ARRAY_LENGTH (ops))])
+
+#define RANDOM_TRANSFORM() \
+(&(transforms[lcg_rand_n (ARRAY_LENGTH (transforms))]))
+
+static void
+on_destroy (pixman_image_t *image, void *data)
+{
+free (data);
+}
+
+static pixman_image_t *
+make_image (void)
+{
+pixman_format_code_t format = RANDOM_FORMAT();
+uint32_t *bytes = malloc (WIDTH * HEIGHT * 4);
+pixman_image_t *image;
+int i;
+
+for (i = 0; i < WIDTH * HEIGHT * 4; ++i)
+   ((uint8_t *)bytes)[i] = lcg_rand_n (256);
+
+image = pixman_image_create_bits (
+   format, WIDTH, HEIGHT, bytes, WIDTH * 4);
+
+pixman_image_set_transform (image, RANDOM_TRANSFORM());
+pixman_image_set_destroy_function (image, on_destroy, bytes);
+pixman_image_set_repeat (image, PIXMAN_REPEAT_NORMAL);
+
+return image;
+}
+
+static uint32_t
+test_transform (int testnum, int verbose)
+{
+pixman_image_t *src, *dest, *mask;
+uint32_t crc;
+
+src = make_image ();
+mask = NULL; // lcg_rand_n (2) ? NULL : make_image();
+dest = make_image ();
+
+pixman_image_composite (RANDOM_OP(),
+   src, mask, dest,
+   0, 0, 0, 0, WIDTH / 2, HEIGHT / 2,
+   WIDTH, HEIGHT);
+
+crc = compute_crc32_for_image (0, dest);
+
+pixman_image_unref (src);
+if (mask)
+   pixman_image_unref (mask);
+pixman_image_unref (dest);
+
+return crc;
+}
+
+int
+main (int argc, const char *argv[])
+{
+return fuzzer_test_main ("rotate", 15000,
+0x721947E4,
+test_transform, argc, argv);
+}
-- 
1.7.4

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


[Pixman] [PATCH 2/2] Fix bugs in pixman-image.c

2012-09-20 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

In the checks for whether the transforms are rotation matrices "-1"
and "1" were used instead of the correct -pixman_fixed_1 and
pixman_fixed_1.

Fixes test suite failure for rotate-test.
---
 pixman/pixman-image.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 15597bd..d9c3034 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -301,9 +301,9 @@ compute_image_info (pixman_image_t *image)
pixman_fixed_t m01 = image->common.transform->matrix[0][1];
pixman_fixed_t m10 = image->common.transform->matrix[1][0];
 
-   if (m01 == -1 && m10 == 1)
+   if (m01 == -pixman_fixed_1 && m10 == pixman_fixed_1)
flags |= FAST_PATH_ROTATE_90_TRANSFORM;
-   else if (m01 == 1 && m10 == -1)
+   else if (m01 == pixman_fixed_1 && m10 == -pixman_fixed_1)
flags |= FAST_PATH_ROTATE_270_TRANSFORM;
}
}
-- 
1.7.4

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


[Pixman] [PATCH] pixman-combine.c.template: Formatting clean-ups

2012-09-21 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Various formatting fixes, and removal of some obsolete comments about
strength reduction of operators.
---
 pixman/pixman-combine.c.template |   38 +++---
 1 files changed, 7 insertions(+), 31 deletions(-)

diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template
index 50d2b0a..f405312 100644
--- a/pixman/pixman-combine.c.template
+++ b/pixman/pixman-combine.c.template
@@ -6,10 +6,9 @@
 #include 
 
 #include "pixman-private.h"
-
 #include "pixman-combine.h"
 
-/*** per channel helper functions ***/
+/* component alpha helper functions */
 
 static void
 combine_mask_ca (comp4_t *src, comp4_t *mask)
@@ -91,15 +90,11 @@ combine_mask_alpha_ca (const comp4_t *src, comp4_t *mask)
 /*
  * There are two ways of handling alpha -- either as a single unified value or
  * a separate value for each component, hence each macro must have two
- * versions.  The unified alpha version has a 'U' at the end of the name,
- * the component version has a 'C'.  Similarly, functions which deal with
+ * versions.  The unified alpha version has a 'u' at the end of the name,
+ * the component version has a 'ca'.  Similarly, functions which deal with
  * this difference will have two versions using the same convention.
  */
 
-/*
- * All of the composing functions
- */
-
 static force_inline comp4_t
 combine_mask (const comp4_t *src, const comp4_t *mask, int i)
 {
@@ -154,7 +149,9 @@ combine_src_u (pixman_implementation_t *imp,
 int i;
 
 if (!mask)
+{
memcpy (dest, src, width * sizeof (comp4_t));
+}
 else
 {
for (i = 0; i < width; ++i)
@@ -166,7 +163,6 @@ combine_src_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Src is opaque, call combine_src_u */
 static void
 combine_over_u (pixman_implementation_t *imp,
 pixman_op_t  op,
@@ -188,7 +184,6 @@ combine_over_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Dst is opaque, this is a noop */
 static void
 combine_over_reverse_u (pixman_implementation_t *imp,
 pixman_op_t  op,
@@ -209,7 +204,6 @@ combine_over_reverse_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Dst is opaque, call combine_src_u */
 static void
 combine_in_u (pixman_implementation_t *imp,
   pixman_op_t  op,
@@ -229,7 +223,6 @@ combine_in_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Src is opaque, this is a noop */
 static void
 combine_in_reverse_u (pixman_implementation_t *imp,
   pixman_op_t  op,
@@ -250,7 +243,6 @@ combine_in_reverse_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Dst is opaque, call combine_clear */
 static void
 combine_out_u (pixman_implementation_t *imp,
pixman_op_t  op,
@@ -270,7 +262,6 @@ combine_out_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Src is opaque, call combine_clear */
 static void
 combine_out_reverse_u (pixman_implementation_t *imp,
pixman_op_t  op,
@@ -291,9 +282,6 @@ combine_out_reverse_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Src is opaque, call combine_in_u */
-/* if the Dst is opaque, call combine_over_u */
-/* if both the Src and Dst are opaque, call combine_src_u */
 static void
 combine_atop_u (pixman_implementation_t *imp,
 pixman_op_t  op,
@@ -316,9 +304,6 @@ combine_atop_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Src is opaque, call combine_over_reverse_u */
-/* if the Dst is opaque, call combine_in_reverse_u */
-/* if both the Src and Dst are opaque, call combine_dst_u */
 static void
 combine_atop_reverse_u (pixman_implementation_t *imp,
 pixman_op_t  op,
@@ -341,9 +326,6 @@ combine_atop_reverse_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Src is opaque, call combine_over_u */
-/* if the Dst is opaque, call combine_over_reverse_u */
-/* if both the Src and Dst are opaque, call combine_clear */
 static void
 combine_xor_u (pixman_implementation_t *imp,
pixman_op_t  op,
@@ -385,9 +367,6 @@ combine_add_u (pixman_implementation_t *imp,
 }
 }
 
-/* if the Src is opaque, call combine_add_u */
-/* if the Dst is opaque, call combine_add_u */
-/* if both the Src and Dst are opaque, call combine_add_u */
 static void
 combine_saturate_u (pixman_implementation_t *imp,
 pixman_op_t  op,
@@ -444,7 +423,6 @@ combine_saturate_u (pixman_implementation_t *imp,
  * Multiply
  * B(Dca, ad, Sca, as) = Dca.Sca
  */
-
 static void
 combine_multiply_u (pixman_implementation_t *imp,
 pixman_op_t  op,
@@ -1579,9 +1557,8 @@ combine_conjoint_xor_u (pixman_implementation_t *imp,
 

Re: [Pixman] More MIPS OVER fast paths (over_8888_n_8888, over_8888_n_0565, over_0565_n_0565, over_8888_8_8888, over_8888_8_0565, over_0565_8_0565, over_8888_8888 and over_8888_8888_8888) including OV

2012-09-24 Thread Søren Sandmann
Nemanja Lukic  writes:

> Added optimizations for several OVER fast paths:
>  - over__n_
>  - over__n_0565
>  - over_0565_n_0565
>  - over__8_
>  - over__8_0565
>  - over_0565_8_0565
>  - over__
>  - over___
> Including OVER combiner.
> Per previous code review:
>  - Previously pushed single big commit is now divided into 4 smaller pieces.

Thanks for the patches. I have pushed them to master with a few
formatting fixes.

However, you should get a freedesktop account so that you can push
patches yourself, or at least, if you want me to merge them, provide a
public git repository that can be pulled from.

>  - Added OVER combiner.

Did you do any measurements of this one? As Siarhei said:

As for the performance numbers. I wonder how much faster would these
new specialized MIPS fast paths be if we had a DSPr2 optimized OVER
combiner? You can check "sse2_combine_over_u" and
"neon_combine_over_u" functions as examples of existing combiners.


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


[Pixman] [PATCH 0/10] Floating point pipeline again

2012-09-26 Thread Søren Sandmann
Hi,

Here is a new version of the floating point patches. The main changes
since last time are:

(a) It is now explicit that the only guarantee wrt. floating point
exceptions is that divide-by-zero is not generated. So if an
application enables for example FP_INVALID, it may crash. It can
safely enablE FP_DIVBYZERO though.

(b) pixman_expand_to_float() is faster. The first version was written
in a way that caused gcc to generate divisions in the inner
loop. The new version avoids that.

Below are the results of some benchmark runs. From top to bottom:

- Regular, unmodified pixman
- With all compositing going through the current 16 bpc wide path
- With all compositign going through the new floating point wide path

There is a performance hit for the wide path, but it's not that big,
especially not compared to the performance vs. unmodified pixman.


Soren

==
[  0]imageevolution3.8613.905   0.57%2/2
[  0]imageevolution   12.292   12.322   0.12%2/2
[  0]imageevolution   12.758   12.790   0.13%2/2
==
[  1]imagefirefox-asteroids   15.279   15.387   0.35%2/2
[  1]imagefirefox-asteroids  132.169  132.583   0.16%2/2
[  1]imagefirefox-asteroids  153.967  154.097   0.04%2/2
==
[  2]image firefox-canvas-alpha  117.215  117.576   0.15%2/2
[  2]image firefox-canvas-alpha  520.440  520.931   0.05%2/2
[  2]image firefox-canvas-alpha  612.296  613.220   0.08%2/2
==
[  3]image   firefox-canvas   70.088   70.348   0.18%2/2
[  3]image   firefox-canvas  195.548  195.887   0.09%2/2
[  3]image   firefox-canvas  214.703  214.998   0.07%2/2
==
[  4]image firefox-fishbowl  328.958  329.090   0.02%2/2
[  4]image firefox-fishbowl 1000.298 1000.555   0.01%2/2
[  4]image firefox-fishbowl 1133.374 1134.628   0.06%2/2
==
[  5]image firefox-fishtank  177.031  177.075   0.01%2/2
[  5]image firefox-fishtank 1285.495 1286.696   0.05%2/2
[  5]image firefox-fishtank 1416.589 1421.419   0.17%2/2
==
[  6]imagefirefox-paintball  244.934  245.251   0.06%2/2
[  6]imagefirefox-paintball 1906.528 1907.546   0.03%2/2
[  6]imagefirefox-paintball 2186.297 2187.079   0.02%2/2
==
[  7]imagefirefox-particles  147.026  147.423   0.13%2/2
[  0]imagefirefox-particles  560.488  560.974   0.04%2/2
[  7]imagefirefox-particles  634.497  635.891   0.11%2/2
==
[  8]image firefox-planet-gnome   21.534   21.562   0.06%2/2
[  1]image firefox-planet-gnome   91.861   92.053   0.10%2/2
[  8]image firefox-planet-gnome  112.708  112.852   0.06%2/2
==
[  9]imagefirefox-talos-gfx   18.107   18.171   0.18%2/2
[  2]imagefirefox-talos-gfx  104.107  104.116   0.00%2/2
[  9]imagefirefox-talos-gfx  113.000  113.301   0.13%2/2
==
[ 10]imagefirefox-talos-svg   90.002   90.067   0.04%2/2
[  3]imagefirefox-talos-svg  164.665  164.715   0.02%2/2
[ 10]imagefirefox-talos-svg  190.393  191.722   0.35%2/2
==
[ 11]image gnome-system-monitor6.9906.994   0.03%2/2
[  4]image gnome-system-monitor   38.850   38.880   0.04%2/2
[ 11]image gnome-system-monitor   63.256   63.275   0.02%2/2
==
[ 12]image   gnome-terminal-vim9.3599.512   0.81%2/2
[  5]image   gnome-terminal-vim   23.560   23.575   0.03%2/2
[ 12]image   gnome-terminal-vim   23.928   24.062   0.28%2/2
==
[ 13]image   grads-heat-map0.4490.456   0.80%2/2
[  6]image   grads-heat-map0.4550.463   0.88%2/2
[ 13]image   grads-heat-map0.4670.491   2.56%2/2
==
[ 14]image gvim5.49

[Pixman] [PATCH 01/10] glyph-test: Prepare for floating point

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

In preparation for an upcoming change of the wide pipe to use floating
point, comment out some formats in glyph-test that are going to be
using floating point, and update the CRC32 value to match.
---
 test/glyph-test.c |7 +--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/test/glyph-test.c b/test/glyph-test.c
index 84de5aa..9dd5b41 100644
--- a/test/glyph-test.c
+++ b/test/glyph-test.c
@@ -30,10 +30,13 @@ static const pixman_format_code_t formats[] =
 PIXMAN_x14r6g6b6,
 PIXMAN_r8g8b8,
 PIXMAN_b8g8r8,
+#if 0
+/* These use floating point */
 PIXMAN_x2r10g10b10,
 PIXMAN_a2r10g10b10,
 PIXMAN_x2b10g10r10,
 PIXMAN_a2b10g10r10,
+#endif
 PIXMAN_a1r5g5b5,
 PIXMAN_x1r5g5b5,
 PIXMAN_a1b5g5r5,
@@ -329,7 +332,7 @@ test_glyphs (int testnum, int verbose)
 int
 main (int argc, const char *argv[])
 {
-return fuzzer_test_main ("glyph", 3,
-0x741CB2DB,
+return fuzzer_test_main ("glyph", 3,   
+0x79E74996,
 test_glyphs, argc, argv);
 }
-- 
1.7.4

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


[Pixman] [PATCH 02/10] blitters-test: Prepare for floating point

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Comment out some formats in blitters-test that are going to rely on
floating point in the upcoming patches.
---
 test/blitters-test.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/test/blitters-test.c b/test/blitters-test.c
index 8c46cef..30d6912 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -172,10 +172,12 @@ static pixman_format_code_t img_fmt_list[] = {
 PIXMAN_x14r6g6b6,
 PIXMAN_r8g8b8,
 PIXMAN_b8g8r8,
+#if 0 /* These are going to use floating point in the near future */
 PIXMAN_x2r10g10b10,
 PIXMAN_a2r10g10b10,
 PIXMAN_x2b10g10r10,
 PIXMAN_a2b10g10r10,
+#endif
 PIXMAN_a1r5g5b5,
 PIXMAN_x1r5g5b5,
 PIXMAN_a1b5g5r5,
@@ -395,6 +397,6 @@ main (int argc, const char *argv[])
 }
 
 return fuzzer_test_main("blitters", 200,
-   0x3E1DD2E8,
+   0x46136E0A,
test_composite, argc, argv);
 }
-- 
1.7.4

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


[Pixman] [PATCH 03/10] Add pixman-combine-float.c

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This file contains floating point implementations of combiners for all
pixman operators. These combiners operate on buffers containing single
precision floating point pixels stored in (a, r, g, b) order in
memory.

The combiners are added to the pixman_implementation_t struct, but
nothing uses them yet.

This commit incorporates a number of bug fixes contributed by Andrea
Canciani.

Some notes:

- The combiners are making sure to never divide by zero regardless of
  input, so an application could enable divide-by-zero exceptions and
  pixman wouldn't generate any.

- The operators are implemented according to the Render spec. Ie.,

- If the input pixels are between 0 and 1, then so is the output.

- The source and destination coefficients for the conjoint and
  disjoint operators are clamped to [0, 1].

- The PDF operators are not described in the render spec, and the
  implementation here doesn't do any clamping except in the final
  conversion from floating point to destination format.

All of the above will need to be rethought if we add support for pixel
formats that can support negative and greater-than-one pixels. It is
in fact already the case in principle that convolution filters can
produce pixels with negative values, but since these go through the
broken "wide" path that narrows everything to 32 bits, these negative
values don't currently survive to the combiners.
---
 pixman/Makefile.sources   |1 +
 pixman/pixman-combine-float.c | 1003 +
 pixman/pixman-general.c   |1 +
 pixman/pixman-private.h   |   10 +
 4 files changed, 1015 insertions(+), 0 deletions(-)
 create mode 100644 pixman/pixman-combine-float.c

diff --git a/pixman/Makefile.sources b/pixman/Makefile.sources
index cf7040f..96540ec 100644
--- a/pixman/Makefile.sources
+++ b/pixman/Makefile.sources
@@ -5,6 +5,7 @@ libpixman_sources = \
pixman-bits-image.c \
pixman-combine32.c  \
pixman-combine64.c  \
+   pixman-combine-float.c  \
pixman-conical-gradient.c   \
pixman-x86.c\
pixman-mips.c   \
diff --git a/pixman/pixman-combine-float.c b/pixman/pixman-combine-float.c
new file mode 100644
index 000..7bf5b5a
--- /dev/null
+++ b/pixman/pixman-combine-float.c
@@ -0,0 +1,1003 @@
+/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
+/*
+ * Copyright © 2010, 2012 Soren Sandmann Pedersen
+ * Copyright © 2010, 2012 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Soren Sandmann Pedersen (sandm...@cs.au.dk)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+
+#include "pixman-private.h"
+
+typedef float (* combine_channel_t) (float sa, float s, float da, float d);
+
+static force_inline void
+combine_inner (pixman_bool_t component,
+  float *dest, const float *src, const float *mask, int n_pixels,
+  combine_channel_t combine_a, combine_channel_t combine_c)
+{
+int i;
+
+if (!mask)
+{
+   for (i = 0; i < 4 * n_pixels; i += 4)
+   {
+   float sa = src[i + 0];
+   float sr = src[i + 1];
+   float sg = src[i + 2];
+   float sb = src[i + 3];
+   
+   float da = dest[i + 0];
+   float dr = dest[i + 1];
+   float dg = dest[i + 2];
+   float db = dest[i + 3]; 
+   
+   dest[i + 0] = combine_a (sa, sa, da, da);
+   dest[i + 1] = combine_c (sa, sr, da, dr);
+   dest[i + 2] = combine_c (sa, sg, da, dg);
+   dest[i + 3] = combine_c (sa, sb, da, db);
+   }
+}
+else
+{
+   for (i = 0; i <

[Pixman] [PATCH 04/10] Add combiner test

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This test runs the new floating point combiners on random input with
divide-by-zero exceptions turned on.

With the floating point combiners the only thing we guarantee is that
divide-by-zero exceptions are not generated, so change
enable_fp_exceptions() to only enable those, and rename accordingly.
---
 demos/radial-test.c|2 +-
 pixman/pixman-private.h|6 ++
 pixman/pixman-utils.c  |9 +++
 test/Makefile.sources  |1 +
 test/combiner-test.c   |  151 
 test/gradient-crash-test.c |2 +-
 test/pdf-op-test.c |2 +-
 test/stress-test.c |2 +-
 test/utils.c   |   14 +
 test/utils.h   |2 +-
 10 files changed, 174 insertions(+), 17 deletions(-)
 create mode 100644 test/combiner-test.c

diff --git a/demos/radial-test.c b/demos/radial-test.c
index 35e90d7..e64f357 100644
--- a/demos/radial-test.c
+++ b/demos/radial-test.c
@@ -133,7 +133,7 @@ main (int argc, char **argv)
 pixman_image_t *src_img, *dest_img;
 int i, j;
 
-enable_fp_exceptions ();
+enable_divbyzero_exceptions ();
 
 dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
 WIDTH, HEIGHT,
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 949d384..c82316f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -764,6 +764,12 @@ get_implementation (void)
 return global_implementation;
 }
 
+/* This function is exported for the sake of the test suite and not part
+ * of the ABI.
+ */
+PIXMAN_EXPORT pixman_implementation_t *
+_pixman_internal_only_get_implementation (void);
+
 /* Memory allocation helpers */
 void *
 pixman_malloc_ab (unsigned int n, unsigned int b);
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 5633f8f..e4a9730 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -262,6 +262,15 @@ pixman_region32_copy_from_region16 (pixman_region32_t *dst,
 return retval;
 }
 
+/* This function is exported for the sake of the test suite and not part
+ * of the ABI.
+ */
+PIXMAN_EXPORT pixman_implementation_t *
+_pixman_internal_only_get_implementation (void)
+{
+return get_implementation ();
+}
+
 #ifdef DEBUG
 
 void
diff --git a/test/Makefile.sources b/test/Makefile.sources
index 0f34411..0778971 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -4,6 +4,7 @@ TESTPROGRAMS =  \
pdf-op-test \
region-test \
region-translate-test   \
+   combiner-test   \
fetch-test  \
rotate-test \
oob-test\
diff --git a/test/combiner-test.c b/test/combiner-test.c
new file mode 100644
index 000..c438ae6
--- /dev/null
+++ b/test/combiner-test.c
@@ -0,0 +1,151 @@
+#include 
+#include 
+#include "utils.h"
+#include 
+#include "pixman-private.h"
+
+static const pixman_op_t op_list[] =
+{
+PIXMAN_OP_SRC,
+PIXMAN_OP_OVER,
+PIXMAN_OP_ADD,
+PIXMAN_OP_CLEAR,
+PIXMAN_OP_SRC,
+PIXMAN_OP_DST,
+PIXMAN_OP_OVER,
+PIXMAN_OP_OVER_REVERSE,
+PIXMAN_OP_IN,
+PIXMAN_OP_IN_REVERSE,
+PIXMAN_OP_OUT,
+PIXMAN_OP_OUT_REVERSE,
+PIXMAN_OP_ATOP,
+PIXMAN_OP_ATOP_REVERSE,
+PIXMAN_OP_XOR,
+PIXMAN_OP_ADD,
+PIXMAN_OP_SATURATE,
+PIXMAN_OP_DISJOINT_CLEAR,
+PIXMAN_OP_DISJOINT_SRC,
+PIXMAN_OP_DISJOINT_DST,
+PIXMAN_OP_DISJOINT_OVER,
+PIXMAN_OP_DISJOINT_OVER_REVERSE,
+PIXMAN_OP_DISJOINT_IN,
+PIXMAN_OP_DISJOINT_IN_REVERSE,
+PIXMAN_OP_DISJOINT_OUT,
+PIXMAN_OP_DISJOINT_OUT_REVERSE,
+PIXMAN_OP_DISJOINT_ATOP,
+PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+PIXMAN_OP_DISJOINT_XOR,
+PIXMAN_OP_CONJOINT_CLEAR,
+PIXMAN_OP_CONJOINT_SRC,
+PIXMAN_OP_CONJOINT_DST,
+PIXMAN_OP_CONJOINT_OVER,
+PIXMAN_OP_CONJOINT_OVER_REVERSE,
+PIXMAN_OP_CONJOINT_IN,
+PIXMAN_OP_CONJOINT_IN_REVERSE,
+PIXMAN_OP_CONJOINT_OUT,
+PIXMAN_OP_CONJOINT_OUT_REVERSE,
+PIXMAN_OP_CONJOINT_ATOP,
+PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+PIXMAN_OP_CONJOINT_XOR,
+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_DIFFERENCE,
+PIXMAN_OP_EXCLUSION,
+PIXMAN_OP_SOFT_LIGHT,
+PIXMAN_OP_HSL_HUE,
+PIXMAN_OP_HSL_SATURATION,
+PIXMAN_OP_HSL_COLOR,
+PIXMAN_OP_HSL_LUMINOSITY,
+};
+
+static float
+rand_float (void)
+{
+uint32_t u = lcg_rand_u32();
+
+return *(float *)&u;
+}
+
+static void
+random_floats (argb_t *argb, int width)
+{
+int i;
+
+for (i = 0; i < width; ++i)
+{
+   argb_t *p = argb + i;
+
+   p->a = rand_float();
+   p->r = rand_float();
+   p->g = rand_float();
+   p->b = rand_float();
+ 

[Pixman] [PATCH 05/10] pixman-utils.c, pixman-private.h: Add floating point conversion routines

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

A new struct argb_t containing a floating point pixel is added to
pixman-private.h, and conversion routines are added to pixman-utils.c
to convert normalized integers to and from that struct.

New functions:

  - pixman_expand_to_float()
Expands a buffer of integer pixels to a buffer of argb_t pixels

  - pixman_contract_from_float()
Converts a buffer of argb_t pixels to a buffer integer pixels

  - pixman_float_to_unorm()
Converts a floating point number to an unsigned normalized integer

  - pixman_unorm_to_float()
Converts an unsigned normalized integer to a floating point number
---
 pixman/pixman-private.h |   35 +++
 pixman/pixman-utils.c   |  107 +++
 2 files changed, 142 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index c82316f..91f35ed 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -45,6 +45,16 @@ typedef struct radial_gradient radial_gradient_t;
 typedef struct bits_image bits_image_t;
 typedef struct circle circle_t;
 
+typedef struct argb_t argb_t;
+
+struct argb_t
+{
+float a;
+float r;
+float g;
+float b;
+};
+
 typedef void (*fetch_scanline_t) (pixman_image_t *image,
  int x,
  int y,
@@ -792,12 +802,34 @@ pixman_expand (uint64_t *   dst,
const uint32_t * src,
pixman_format_code_t format,
int  width);
+void
+pixman_expand_to_float (argb_t   *dst,
+   const uint32_t   *src,
+   pixman_format_code_t  format,
+   int   width);
 
 void
 pixman_contract (uint32_t *  dst,
  const uint64_t *src,
  int width);
 
+void
+pixman_contract_from_float (uint32_t *dst,
+   const argb_t *src,
+   int   width);
+
+pixman_bool_t
+_pixman_lookup_composite_function (pixman_implementation_t *toplevel,
+  pixman_op_t  op,
+  pixman_format_code_t src_format,
+  uint32_t src_flags,
+  pixman_format_code_t mask_format,
+  uint32_t mask_flags,
+  pixman_format_code_t dest_format,
+  uint32_t dest_flags,
+  pixman_implementation_t**out_imp,
+  pixman_composite_func_t *out_func);
+
 /* Region Helpers */
 pixman_bool_t
 pixman_region32_copy_from_region16 (pixman_region32_t *dst,
@@ -957,6 +989,9 @@ unorm_to_unorm (uint32_t val, int from_bits, int to_bits)
 return result;
 }
 
+uint16_t pixman_float_to_unorm (float f, int n_bits);
+float pixman_unorm_to_float (uint16_t u, int n_bits);
+
 /*
  * Various debugging code
  */
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index e4a9730..4f9db29 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -162,6 +162,113 @@ pixman_expand (uint64_t *   dst,
 }
 }
 
+static force_inline uint16_t
+float_to_unorm (float f, int n_bits)
+{
+uint32_t u;
+
+if (f > 1.0)
+   f = 1.0;
+if (f < 0.0)
+   f = 0.0;
+
+u = f * (1 << n_bits);
+u -= (u >> n_bits);
+
+return u;
+}
+
+static force_inline float
+unorm_to_float (uint16_t u, int n_bits)
+{
+uint32_t m = ((1 << n_bits) - 1);
+
+return (u & m) * (1.f / (float)m);
+}
+
+/*
+ * This function expands images from a8r8g8b8 to argb_t.  To preserve
+ * precision, it needs to know from which source format the a8r8g8b8 pixels
+ * originally came.
+ *
+ * For example, if the source was PIXMAN_x1r5g5b5 and the red component
+ * contained bits 12345, then the 8-bit value is 12345123.  To correctly
+ * expand this to floating point, it should be 12345 / 31.0 and not
+ * 12345123 / 255.0.
+ */
+void
+pixman_expand_to_float (argb_t   *dst,
+   const uint32_t   *src,
+   pixman_format_code_t  format,
+   int   width)
+{
+int a_size, r_size, g_size, b_size;
+int a_shift, r_shift, g_shift, b_shift;
+int i;
+
+if (!PIXMAN_FORMAT_VIS (format))
+   format = PIXMAN_a8r8g8b8;
+
+/*
+ * Determine the sizes of each component and the masks and shifts
+ * required to extract them from the source pixel.
+ */
+a_size = PIXMAN_FORMAT_A (format);
+r_size = PIXMAN_FORMAT_R (format);
+g_size = PIXMAN_FORMAT_G (format);
+b_size = PIXMAN_FORMAT_B (format);
+
+a_shift = 32 - a_size

[Pixman] [PATCH 06/10] pixman-access.c: Add floating point accessor functions

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Three new function pointer fields are added to bits_image_t:

  fetch_scanline_float
  fetch_pixel_float
  store_scanline_float

similar to the existing 32 and 64 bit accessors. The fetcher_info_t
struct in pixman_access similarly gets a new get_scanline_float field.

For most formats, the new get_scanline_float field is set to a new
function fetch_scanline_generic_float() that first calls the 32 bit
fetcher uses the 32 bit scanline fetcher and then expands these pixels
to floating point.

For the 10 bpc formats, new floating point accessors are added that
use pixman_unorm_to_float() and pixman_float_to_unorm() to convert
back and forth.

The PIXMAN_a8r8g8b8_sRGB format is handled with a 256-entry table that
maps 8 bit sRGB channels to linear single precision floating point
numbers. The sRGB->linear direction can then be done with a simple
table lookup.

The other direction is currently done with a 4096-entry table which
works fine for 16 bit integers, but not so great for floating
point. So instead this patch uses a binary search in the sRGB->linear
table. The existing 32 bit accessors for the sRGB format are also
converted to use this method.
---
 pixman/pixman-access.c |  619 +---
 pixman/pixman-bits-image.c |   40 +++-
 pixman/pixman-private.h|8 +
 3 files changed, 624 insertions(+), 43 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 9feafc4..1eef621 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "pixman-accessor.h"
 #include "pixman-private.h"
@@ -635,6 +636,231 @@ fetch_scanline_x2b10g10r10 (pixman_image_t *image,
 }
 }
 
+/* Table mapping sRGB-encoded 8 bit numbers to linearly encoded
+ * floating point numbers. We assume that single precision
+ * floating point follows the IEEE 754 format.
+ */
+static const uint32_t to_linear_u[256] =
+{
+0x, 0x399f22b4, 0x3a1f22b4, 0x3a6eb40e, 0x3a9f22b4, 0x3ac6eb61,
+0x3aeeb40e, 0x3b0b3e5d, 0x3b1f22b4, 0x3b33070b, 0x3b46eb61, 0x3b5b518a,
+0x3b70f18a, 0x3b83e1c5, 0x3b8fe614, 0x3b9c87fb, 0x3ba9c9b5, 0x3bb7ad6d,
+0x3bc63547, 0x3bd5635f, 0x3be539bd, 0x3bf5ba70, 0x3c0373b5, 0x3c0c6152,
+0x3c15a703, 0x3c1f45bc, 0x3c293e68, 0x3c3391f4, 0x3c3e4149, 0x3c494d43,
+0x3c54b6c7, 0x3c607eb1, 0x3c6ca5df, 0x3c792d22, 0x3c830aa8, 0x3c89af9e,
+0x3c9085db, 0x3c978dc5, 0x3c9ec7c0, 0x3ca63432, 0x3cadd37d, 0x3cb5a601,
+0x3cbdac20, 0x3cc5e639, 0x3cce54ab, 0x3cd6f7d2, 0x3cdfd00e, 0x3ce8ddb9,
+0x3cf2212c, 0x3cfb9ac1, 0x3d02a569, 0x3d0798dc, 0x3d0ca7e4, 0x3d11d2ae,
+0x3d171963, 0x3d1c7c2e, 0x3d21fb3a, 0x3d2796af, 0x3d2d4ebb, 0x3d332380,
+0x3d39152b, 0x3d3f23e3, 0x3d454fd0, 0x3d4b991c, 0x3d51ffeb, 0x3d588466,
+0x3d5f26b7, 0x3d65e6fe, 0x3d6cc564, 0x3d73c210, 0x3d7add25, 0x3d810b65,
+0x3d84b793, 0x3d88732e, 0x3d8c3e48, 0x3d9018f4, 0x3d940343, 0x3d97fd48,
+0x3d9c0714, 0x3da020b9, 0x3da44a48, 0x3da883d6, 0x3daccd70, 0x3db12728,
+0x3db59110, 0x3dba0b38, 0x3dbe95b2, 0x3dc3308f, 0x3dc7dbe0, 0x3dcc97b4,
+0x3dd1641c, 0x3dd6412a, 0x3ddb2eec, 0x3de02d75, 0x3de53cd3, 0x3dea5d16,
+0x3def8e52, 0x3df4d091, 0x3dfa23e5, 0x3dff885e, 0x3e027f06, 0x3e05427f,
+0x3e080ea2, 0x3e0ae376, 0x3e0dc104, 0x3e10a752, 0x3e139669, 0x3e168e50,
+0x3e198f0e, 0x3e1c98ab, 0x3e1fab2e, 0x3e22c6a0, 0x3e25eb08, 0x3e29186a,
+0x3e2c4ed0, 0x3e2f8e42, 0x3e32d6c4, 0x3e362861, 0x3e39831e, 0x3e3ce702,
+0x3e405416, 0x3e43ca5e, 0x3e4749e4, 0x3e4ad2ae, 0x3e4e64c2, 0x3e520027,
+0x3e55a4e6, 0x3e595303, 0x3e5d0a8a, 0x3e60cb7c, 0x3e6495e0, 0x3e6869bf,
+0x3e6c4720, 0x3e702e08, 0x3e741e7f, 0x3e78188c, 0x3e7c1c34, 0x3e8014c0,
+0x3e822039, 0x3e84308b, 0x3e8645b8, 0x3e885fc3, 0x3e8a7eb0, 0x3e8ca281,
+0x3e8ecb3a, 0x3e90f8df, 0x3e932b72, 0x3e9562f6, 0x3e979f6f, 0x3e99e0e0,
+0x3e9c274e, 0x3e9e72b8, 0x3ea0c322, 0x3ea31892, 0x3ea57308, 0x3ea7d28a,
+0x3eaa3718, 0x3eaca0b7, 0x3eaf0f69, 0x3eb18332, 0x3eb3fc16, 0x3eb67a15,
+0x3eb8fd34, 0x3ebb8576, 0x3ebe12de, 0x3ec0a56e, 0x3ec33d2a, 0x3ec5da14,
+0x3ec87c30, 0x3ecb2380, 0x3ecdd008, 0x3ed081ca, 0x3ed338c9, 0x3ed5f508,
+0x3ed8b68a, 0x3edb7d52, 0x3ede4962, 0x3ee11abe, 0x3ee3f168, 0x3ee6cd64,
+0x3ee9aeb6, 0x3eec955d, 0x3eef815d, 0x3ef272ba, 0x3ef56976, 0x3ef86594,
+0x3efb6717, 0x3efe6e02, 0x3f00bd2b, 0x3f02460c, 0x3f03d1a5, 0x3f055ff8,
+0x3f06f105, 0x3f0884ce, 0x3f0a1b54, 0x3f0bb499, 0x3f0d509f, 0x3f0eef65,
+0x3f1090ef, 0x3f12353c, 0x3f13dc50, 0x3f15862a, 0x3f1732cc, 0x3f18e237,
+0x3f1a946d, 0x3f1c4970, 0x3f1e013f, 0x3f1fbbde, 0x3f21794c, 0x3f23398c,
+0x3f24fca0, 0x3f26c286, 0x3f288b42, 0x3f2a56d3, 0x3f2c253d, 0x3f2df680,
+0x3f2fca9d, 0x3f31a195, 0x3f337b6a, 0x3f35581e, 0x3f3737b1, 0x3f391a24,
+0x3f3aff7a, 0x3f3ce7b2, 0x3f3ed2d0, 0x3f40c0d2, 0x3f42b1bc, 0x3f44a58e,
+0x3f469c49, 0x3f4895ee, 0x3f4a92

[Pixman] [PATCH 07/10] Switch the wide pipeline over to using floating point

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

In pixman-bits-image.c, remove bits_image_fetch_untransformed_64() and
add bits_image_fetch_untransformed_float(); change
dest_get_scanline_wide() to produce a floating point buffer,

In the gradients, change *_get_scanline_wide() to call
pixman_expand_to_float() instead of pixman_expand().

In pixman-general.c change the wide Bpp to 16 instead of 8, and
initialize the buffers to 0 to prevent NaNs from causing trouble.

In pixman-noop.c make the wide solid iterator generate floating point
pixels.

In pixman-solid-fill.c, cache a floating point pixel, and make the
wide iterator generate floating point pixels.
---
 pixman/pixman-bits-image.c   |   64 ++
 pixman/pixman-conical-gradient.c |3 +-
 pixman/pixman-general.c  |   10 +-
 pixman/pixman-implementation.c   |4 +-
 pixman/pixman-linear-gradient.c  |3 +-
 pixman/pixman-noop.c |6 ++--
 pixman/pixman-private.h  |3 +-
 pixman/pixman-radial-gradient.c  |3 +-
 pixman/pixman-solid-fill.c   |   10 --
 9 files changed, 59 insertions(+), 47 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 07353dc..81a5a6f 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -979,17 +979,17 @@ replicate_pixel_32 (bits_image_t *   bits,
 }
 
 static void
-replicate_pixel_64 (bits_image_t *   bits,
-   int  x,
-   int  y,
-   int  width,
-   uint32_t *   b)
+replicate_pixel_float (bits_image_t *   bits,
+  int  x,
+  int  y,
+  int  width,
+  uint32_t *   b)
 {
-uint64_t color;
-uint64_t *buffer = (uint64_t *)b;
-uint64_t *end;
+argb_t color;
+argb_t *buffer = (argb_t *)b;
+argb_t *end;
 
-color = bits->fetch_pixel_64 (bits, x, y);
+color = bits->fetch_pixel_float (bits, x, y);
 
 end = buffer + width;
 while (buffer < end)
@@ -1008,7 +1008,7 @@ bits_image_fetch_untransformed_repeat_none (bits_image_t 
*image,
 
 if (y < 0 || y >= image->height)
 {
-   memset (buffer, 0, width * (wide? 8 : 4));
+   memset (buffer, 0, width * (wide? sizeof (argb_t) : 4));
return;
 }
 
@@ -1016,10 +1016,10 @@ bits_image_fetch_untransformed_repeat_none 
(bits_image_t *image,
 {
w = MIN (width, -x);
 
-   memset (buffer, 0, w * (wide ? 8 : 4));
+   memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4));
 
width -= w;
-   buffer += w * (wide? 2 : 1);
+   buffer += w * (wide? 4 : 1);
x += w;
 }
 
@@ -1028,16 +1028,16 @@ bits_image_fetch_untransformed_repeat_none 
(bits_image_t *image,
w = MIN (width, image->width - x);
 
if (wide)
-   image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, 
NULL);
+   image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, 
buffer, NULL);
else
image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, 
NULL);
 
width -= w;
-   buffer += w * (wide? 2 : 1);
+   buffer += w * (wide? 4 : 1);
x += w;
 }
 
-memset (buffer, 0, width * (wide ? 8 : 4));
+memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4));
 }
 
 static void
@@ -1059,7 +1059,7 @@ bits_image_fetch_untransformed_repeat_normal 
(bits_image_t *image,
 if (image->width == 1)
 {
if (wide)
-   replicate_pixel_64 (image, 0, y, width, buffer);
+   replicate_pixel_float (image, 0, y, width, buffer);
else
replicate_pixel_32 (image, 0, y, width, buffer);
 
@@ -1076,7 +1076,7 @@ bits_image_fetch_untransformed_repeat_normal 
(bits_image_t *image,
w = MIN (width, image->width - x);
 
if (wide)
-   image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, 
NULL);
+   image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, 
buffer, NULL);
else
image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, 
NULL);
 
@@ -1112,9 +1112,8 @@ bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
 }
 
 static uint32_t *
-bits_image_fetch_untransformed_64 (pixman_iter_t * iter,
-   const uint32_t *mask)
-  
+bits_image_fetch_untransformed_float (pixman_iter_t * iter,
+ const uint32_t *mask)
 {
 pixman_image_t *image  = iter->image;
 int x  = iter->x;
@@ -1155,8 +1154,8 @@ static const fetcher_info_t fetcher_info[] =
FAST_PATH_NO_PAD_REPEAT |
FAST_PATH_NO_REFLECT_REPEAT),
   bits_image_fetch_untransformed_32,
-  bits_image_fetch_untransformed_64,
-  _

[Pixman] [PATCH 08/10] Remove 64 bit pipeline

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The 64 bit pipeline is not used anymore, so it can now be removed.

Don't generate pixman-combine64.[ch] anymore. Don't generate the
pixman-srgb.c anymore. Delete all the 64 bit fetchers in
pixman-access.c, all the 64 bit iterator functions in
pixman-bits-image.c and all the functions that expand from 8 to 16
bits.
---
 .gitignore |2 -
 pixman/Makefile.am |1 -
 pixman/Makefile.sources|   14 --
 pixman/pixman-access.c |  517 +++-
 pixman/pixman-bits-image.c |   49 +
 pixman/pixman-general.c|1 -
 pixman/pixman-private.h|   41 
 pixman/pixman-solid-fill.c |   23 +-
 pixman/pixman-utils.c  |  116 --
 9 files changed, 39 insertions(+), 725 deletions(-)

diff --git a/.gitignore b/.gitignore
index a4d9f99..a67da1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,8 +41,6 @@ demos/trap-test
 demos/tri-test
 pixman/pixman-combine32.c
 pixman/pixman-combine32.h
-pixman/pixman-combine64.c
-pixman/pixman-combine64.h
 pixman/pixman-srgb.c
 pixman/pixman-version.h
 test/a1-trap-test
diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 270d65e..3060569 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -13,7 +13,6 @@ noinst_LTLIBRARIES =
 EXTRA_DIST =   \
Makefile.win32  \
make-combine.pl \
-   make-srgb.pl\
pixman-combine.c.template   \
pixman-combine.h.template   \
pixman-region.c \
diff --git a/pixman/Makefile.sources b/pixman/Makefile.sources
index 96540ec..5be288d 100644
--- a/pixman/Makefile.sources
+++ b/pixman/Makefile.sources
@@ -4,7 +4,6 @@ libpixman_sources = \
pixman-access-accessors.c   \
pixman-bits-image.c \
pixman-combine32.c  \
-   pixman-combine64.c  \
pixman-combine-float.c  \
pixman-conical-gradient.c   \
pixman-x86.c\
@@ -26,7 +25,6 @@ libpixman_sources =   \
pixman-region16.c   \
pixman-region32.c   \
pixman-solid-fill.c \
-   pixman-srgb.c   \
pixman-timer.c  \
pixman-trap.c   \
pixman-utils.c  \
@@ -36,7 +34,6 @@ libpixman_headers =   \
pixman.h\
pixman-accessor.h   \
pixman-combine32.h  \
-   pixman-combine64.h  \
pixman-compiler.h   \
pixman-edge-imp.h   \
pixman-inlines.h\
@@ -46,20 +43,9 @@ libpixman_headers =  \
 BUILT_SOURCES =\
pixman-combine32.c  \
pixman-combine32.h  \
-   pixman-combine64.c  \
-   pixman-combine64.h  \
-   pixman-srgb.c   \
$(NULL)
 
-pixman-srgb.c: make-srgb.pl
-   $(PERL) $< > $@ || ($(RM) $@; exit 1)
-
 pixman-combine32.c: pixman-combine.c.template make-combine.pl
$(PERL) $(lastword $+) 8 < $< > $@ || ($(RM) $@; exit 1)
 pixman-combine32.h: pixman-combine.h.template make-combine.pl
$(PERL) $(lastword $+) 8 < $< > $@ || ($(RM) $@; exit 1)
-
-pixman-combine64.c: pixman-combine.c.template make-combine.pl
-   $(PERL) $(lastword $+) 16 < $< > $@ || ($(RM) $@; exit 1)
-pixman-combine64.h: pixman-combine.h.template make-combine.pl
-   $(PERL) $(lastword $+) 16 < $< > $@ || ($(RM) $@; exit 1)
diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 1eef621..b5c8e40 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -507,135 +507,6 @@ MAKE_ACCESSORS(a1);
 MAKE_ACCESSORS(g1);
 
 /** Fetch /
-
-/* Expects a uint64_t buffer */
-static void
-fetch_scanline_a2r10g10b10 (pixman_image_t *image,
-int x,
-int y,
-int width,
-uint32_t *  b,
-const uint32_t *mask)
-{
-const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
-const uint32_t *pixel = bits + x;
-const uint32_t *end = pixel + width;
-uint64_t *buffer = (uint64_t *)b;
-
-while (pixel < end)
-{
-   uint32_t p = READ (image, pixel++);
-   uint64_t a = p >> 30;
-   uint64_t r = (p >> 20) & 0x3ff;
-   uint64_t g = (p >> 10) & 0x3ff;
-   uint64_t b = p & 0x3ff;
-
-   r = r << 6 | r >> 4;
-   g = g << 6 | g >> 4;
-   b = b << 6 | b &

[Pixman] [PATCH 10/10] Speed up pixman_expand_to_float()

2012-09-26 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

GCC doesn't move the divisions out of the loop, so do it manually by
looking up the four (1.0f / mask) values in a table. Table lookups are
used under the theory that one L2 hit plus three L1 hits is preferable
to four floating point divisions.
---
 pixman/pixman-utils.c |   38 ++
 1 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 551f3f9..b1e9fb6 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -111,8 +111,28 @@ pixman_expand_to_float (argb_t   *dst,
pixman_format_code_t  format,
int   width)
 {
+static const float multipliers[16] = {
+   0.0f,
+   1.0f / ((1 <<  1) - 1),
+   1.0f / ((1 <<  2) - 1),
+   1.0f / ((1 <<  3) - 1),
+   1.0f / ((1 <<  4) - 1),
+   1.0f / ((1 <<  5) - 1),
+   1.0f / ((1 <<  6) - 1),
+   1.0f / ((1 <<  7) - 1),
+   1.0f / ((1 <<  8) - 1),
+   1.0f / ((1 <<  9) - 1),
+   1.0f / ((1 << 10) - 1),
+   1.0f / ((1 << 11) - 1),
+   1.0f / ((1 << 12) - 1),
+   1.0f / ((1 << 13) - 1),
+   1.0f / ((1 << 14) - 1),
+   1.0f / ((1 << 15) - 1),
+};
 int a_size, r_size, g_size, b_size;
 int a_shift, r_shift, g_shift, b_shift;
+float a_mul, r_mul, g_mul, b_mul;
+uint32_t a_mask, r_mask, g_mask, b_mask;
 int i;
 
 if (!PIXMAN_FORMAT_VIS (format))
@@ -132,6 +152,16 @@ pixman_expand_to_float (argb_t   *dst,
 g_shift = 16 - g_size;
 b_shift =  8 - b_size;
 
+a_mask = ((1 << a_size) - 1);
+r_mask = ((1 << r_size) - 1);
+g_mask = ((1 << g_size) - 1);
+b_mask = ((1 << b_size) - 1);
+
+a_mul = multipliers[a_size];
+r_mul = multipliers[r_size];
+g_mul = multipliers[g_size];
+b_mul = multipliers[b_size];
+
 /* Start at the end so that we can do the expansion in place
  * when src == dst
  */
@@ -139,10 +169,10 @@ pixman_expand_to_float (argb_t   *dst,
 {
const uint32_t pixel = src[i];
 
-   dst[i].a = a_size? unorm_to_float (pixel >> a_shift, a_size) : 1.0;
-   dst[i].r = r_size? unorm_to_float (pixel >> r_shift, r_size) : 0.0;
-   dst[i].g = g_size? unorm_to_float (pixel >> g_shift, g_size) : 0.0;
-   dst[i].b = b_size? unorm_to_float (pixel >> b_shift, b_size) : 0.0;
+   dst[i].a = a_mask? ((pixel >> a_shift) & a_mask) * a_mul : 1.0f;
+   dst[i].r = ((pixel >> r_shift) & r_mask) * r_mul;
+   dst[i].g = ((pixel >> g_shift) & g_mask) * g_mul;
+   dst[i].b = ((pixel >> b_shift) & b_mask) * b_mul;
 }
 }
 
-- 
1.7.4

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


Re: [Pixman] [PATCH 0/10] Floating point pipeline again

2012-09-26 Thread Søren Sandmann
Behdad Esfahbod  writes:

> On 09/26/2012 04:43 PM, Søren Sandmann wrote:
>> Hi,
>> 
>> Here is a new version of the floating point patches. The main changes
>> since last time are:
>> 
>> (a) It is now explicit that the only guarantee wrt. floating point
>> exceptions is that divide-by-zero is not generated. So if an
>> application enables for example FP_INVALID, it may crash. It can
>> safely enablE FP_DIVBYZERO though.
>> 
>> (b) pixman_expand_to_float() is faster. The first version was written
>> in a way that caused gcc to generate divisions in the inner
>> loop. The new version avoids that.
>> 
>> Below are the results of some benchmark runs. From top to bottom:
>> 
>> - Regular, unmodified pixman
>> - With all compositing going through the current 16 bpc wide path
>> - With all compositign going through the new floating point wide path
>
> What are the columns?

[test number], [cairo backend], [test name], [min time], [median time], [std 
variance]

The 2/2 column I believe indicates that the test was run twice and two
of those runs were used in the data gathering (ie., not considered
outliers).


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


Re: [Pixman] [PATCH 05/10] pixman-utils.c, pixman-private.h: Add floating point conversion routines

2012-09-26 Thread Søren Sandmann
Matt Turner  writes:

>> +pixman_bool_t
>> +_pixman_lookup_composite_function (pixman_implementation_t *toplevel,
>> +  pixman_op_t  op,
>> +  pixman_format_code_t src_format,
>> +  uint32_t src_flags,
>> +  pixman_format_code_t mask_format,
>> +  uint32_t mask_flags,
>> +  pixman_format_code_t dest_format,
>> +  uint32_t dest_flags,
>> +  pixman_implementation_t**out_imp,
>> +  pixman_composite_func_t *out_func);
>> +

This declaration is the result of a mismerge. I'll remove it before comitting.


>> +void
>> +pixman_expand_to_float (argb_t   *dst,
>> +   const uint32_t   *src,
>> +   pixman_format_code_t  format,
>> +   int   width)
>> +{

>> +void
>> +pixman_contract_from_float (uint32_t *dst,
>> +   const argb_t *src,
>> +   int   width)
>> +{
>
> As I'm sure you know, these functions can be done with SSE 2 or 4.1 if
> we could convert 4 pixels at once. How can we override their
> implementations with optimized ones?

A way to do that might be to make it a new entry point in the
implementation struct, and then make sure that the implementation
pointer is passed down to the accessors.

But a simpler approach would probably be to write SIMD iterators for the
most common formats that would convert to and from floating point
without using these expand/contract functions.

An idea here might be to change the "untransformed" iterators such that
they could take an accessor function as a parameter. Then the SIMD
implementations could simply write accessor functions and pass them to
that iterator.


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


[Pixman] [PATCH] Make pixman.h more const-correct

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

Add const to pointer arguments when the function doesn't change the
pointed-to data.
---
 pixman/pixman-conical-gradient.c |2 +-
 pixman/pixman-glyph.c|8 
 pixman/pixman-linear-gradient.c  |4 ++--
 pixman/pixman-radial-gradient.c  |4 ++--
 pixman/pixman-solid-fill.c   |2 +-
 pixman/pixman-trap.c |   10 +-
 pixman/pixman.c  |   10 +-
 pixman/pixman.h  |   24 
 8 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 8b52176..05d3595 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -180,7 +180,7 @@ _pixman_conical_gradient_iter_init (pixman_image_t *image, 
pixman_iter_t *iter)
 }
 
 PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
+pixman_image_create_conical_gradient (const pixman_point_fixed_t *  center,
   pixman_fixed_tangle,
   const pixman_gradient_stop_t *stops,
   int   n_stops)
diff --git a/pixman/pixman-glyph.c b/pixman/pixman-glyph.c
index 30a4099..657b62d 100644
--- a/pixman/pixman-glyph.c
+++ b/pixman/pixman-glyph.c
@@ -354,7 +354,7 @@ pixman_glyph_get_extents (pixman_glyph_cache_t *cache,
 PIXMAN_EXPORT pixman_format_code_t
 pixman_glyph_get_mask_format (pixman_glyph_cache_t *cache,
  int   n_glyphs,
- pixman_glyph_t *  glyphs)
+ const pixman_glyph_t *glyphs)
 {
 pixman_format_code_t format = PIXMAN_a1;
 int i;
@@ -401,7 +401,7 @@ pixman_composite_glyphs_no_mask (pixman_op_top,
 int32_tdest_y,
 pixman_glyph_cache_t  *cache,
 intn_glyphs,
-pixman_glyph_t*glyphs)
+const pixman_glyph_t  *glyphs)
 {
 pixman_region32_t region;
 pixman_format_code_t glyph_format = PIXMAN_null;
@@ -502,7 +502,7 @@ static void
 add_glyphs (pixman_glyph_cache_t *cache,
pixman_image_t *dest,
int off_x, int off_y,
-   int n_glyphs, pixman_glyph_t *glyphs)
+   int n_glyphs, const pixman_glyph_t *glyphs)
 {
 pixman_format_code_t glyph_format = PIXMAN_null;
 uint32_t glyph_flags = 0;
@@ -651,7 +651,7 @@ pixman_composite_glyphs (pixman_op_top,
 int32_theight,
 pixman_glyph_cache_t  *cache,
 intn_glyphs,
-pixman_glyph_t*glyphs)
+const pixman_glyph_t  *glyphs)
 {
 pixman_image_t *mask;
 
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 32b8ba7..e511368 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -255,8 +255,8 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image, 
pixman_iter_t  *iter)
 }
 
 PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_linear_gradient (pixman_point_fixed_t *p1,
- pixman_point_fixed_t *p2,
+pixman_image_create_linear_gradient (const pixman_point_fixed_t *  p1,
+ const pixman_point_fixed_t *  p2,
  const pixman_gradient_stop_t *stops,
  int   n_stops)
 {
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 715711f..41bb79d 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -420,8 +420,8 @@ _pixman_radial_gradient_iter_init (pixman_image_t *image, 
pixman_iter_t *iter)
 }
 
 PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_radial_gradient (pixman_point_fixed_t *inner,
- pixman_point_fixed_t *outer,
+pixman_image_create_radial_gradient (const pixman_point_fixed_t *  inner,
+ const pixman_point_fixed_t *  outer,
  pixman_fixed_t
inner_radius,
  pixman_fixed_t
outer_radius,
  const pixman_gradient_stop_t *stops,
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 8b25d5d..26f85ce 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -72,7 +72,7 @@ color_to_uint64 (const pixman_color_t *color)
 }
 
 PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_solid_fill (pixman_co

[Pixman] [PATCH] Make 'white' in add_glyphs() static and const

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

---
 pixman/pixman-glyph.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-glyph.c b/pixman/pixman-glyph.c
index 657b62d..15b3f1f 100644
--- a/pixman/pixman-glyph.c
+++ b/pixman/pixman-glyph.c
@@ -560,7 +560,7 @@ add_glyphs (pixman_glyph_cache_t *cache,
{
if (!white_img)
{
-   pixman_color_t white = { 0x, 0x, 0x, 0x };
+   static const pixman_color_t white = { 0x, 0x, 
0x, 0x };
 
if (!(white_img = pixman_image_create_solid_fill (&white)))
goto out;
-- 
1.7.4

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


Re: [Pixman] [PATCH] ARMv5 optimisations

2012-09-29 Thread Søren Sandmann
Siarhei Siamashka  writes:

>> As the code comes from the Android code base, it is Apache licensed -
>> is this a problem with Pixman?
>
> I am not a lawyer, but Apache license does not seem to be
> compatible with GPL2 according to:
>http://www.apache.org/licenses/GPL-compatibility.html
> This is an extra restriction, which does not exist in the current
> pixman MIT/X11 license. I personally would not touch Apache licensed
> code without a really good reason.

Yeah, unfortunately we can't ship Apache licensed code in pixman.

> BTW, the nearest scaling code from pixman-arm-simd-asm.S can be
> moved to the arm-v5 file if pixman gets ARMv5 support.

There is also an old bug here:

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

with some ARM assembly fill routines that probably could be resurrected
fairly easily.


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


Re: [Pixman] [PATCH] ARMv5 optimisations

2012-09-30 Thread Søren Sandmann
Andre Renaud  writes:

 As the code comes from the Android code base, it is Apache licensed -
 is this a problem with Pixman?
>>>
>>> I am not a lawyer, but Apache license does not seem to be
>>> compatible with GPL2 according to:
>>>http://www.apache.org/licenses/GPL-compatibility.html
>>> This is an extra restriction, which does not exist in the current
>>> pixman MIT/X11 license. I personally would not touch Apache licensed
>>> code without a really good reason.
>>
>> Yeah, unfortunately we can't ship Apache licensed code in pixman.
>
> Thanks for all the feedback, I'll probably take a look at the bugs &
> check them. However given that the license is incompatible, it doesn't
> seem like there is much point in continuing with this, as it's not
> possible for it to be merged. Unfortunately I don't think my ARM ASM
> skills are up to recreating these from scratch.
>
> Is the Pixman project GPL2? I thought it was all MIT - is that an
> upcoming change?

It's all MIT, but if we added Apache licensed code, it would effectively
become Apache licensed and therefore among other things become
incompatible with GPL2.


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


Re: [Pixman] debuging wxruby

2012-10-06 Thread Søren Sandmann
Svend Haugaard Sørensen  writes:

> The top of the stack dump look like this.
>
> #0  0xb47a6d9d in _pixman_lookup_composite_function (toplevel=0x80be750, 
> op=PIXMAN_OP_SRC, 
> src_format=262144, src_flags=1043063, mask_format=0, mask_flags=8192, 
> dest_format=PIXMAN_a8r8g8b8, dest_flags=34032255, out_imp=0xbfffb82c, 
> out_func=0xbfffb828)
> at 
> /var/tmp/portage/x11-libs/pixman-0.26.0/work/pixman-0.26.0/pixman/pixman-utils.c:74

A crash at this point suggests that something is broken with thread
local storage on your setup. When you compiled pixman, which type of
thread local storage was detected by the configure script?


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


Re: [Pixman] debuging wxruby

2012-10-07 Thread Søren Sandmann
Svend Haugaard Sørensen  writes:

> On Sun, 07 Oct 2012 05:10:18 +0200
> sandm...@cs.au.dk (Søren Sandmann) wrote:
>
>> Svend Haugaard Sørensen  writes:
>> 
>> > The top of the stack dump look like this.
>> >
>> > #0  0xb47a6d9d in _pixman_lookup_composite_function
>> > (toplevel=0x80be750, op=PIXMAN_OP_SRC, src_format&2144,
>> > src_flags43063, mask_format=0, mask_flags92,
>> > dest_format=PIXMAN_a8r8g8b8, dest_flags4032255,
>> > out_imp=0xbfffb82c, out_func=0xbfffb828)
>> > at 
>> > /var/tmp/portage/x11-libs/pixman-0.26.0/work/pixman-0.26.0/pixman/pixman-utils.c:74
>> 
>> A crash at this point suggests that something is broken with thread
>> local storage on your setup. When you compiled pixman, which type of
>> thread local storage was detected by the configure script?
>> 
>> 
>> Søren
>
> The configure script write this to the output.
> checking for thread local storage (TLS) support... __thread
>
> I have posted the complete output on the gentoo forum.
> http://forums.gentoo.org/viewtopic-p-7157526.html#7157526
>  

Most likely the issue is the same as in this bug:

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

where some other library is using the TLS model "initial-exec", which
then conflicts with pixman using the "dynamic" model.


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


Re: [Pixman] debuging wxruby

2012-10-07 Thread Søren Sandmann
Svend Haugaard Sørensen  writes:

>> Most likely the issue is the same as in this bug:
>> 
>>https://bugs.freedesktop.org/show_bug.cgi?id4335
>> 
>> where some other library is using the TLS model "initial-exec", which
>> then conflicts with pixman using the "dynamic" model.
>
> And how do we find, test and fix that??
>
> Is the TLS supported by a certain dynamic library? Because the I
> can search for it.
>  
> PS. I don't use mesa, but the nvidia driver. 

It's possible that the root cause is this bug in glibc:

http://sourceware.org/bugzilla/show_bug.cgi?id=12453

If your C library is older than that, I'd try updating it first.


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


[Pixman] [PATCH] Only regard images as pixbufs if they have identity transformations

2012-10-07 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

In order for a src/mask pair to be considered a pixbuf, they have to
have identical transformations, but we don't check for that. Since the
only fast paths we have for pixbufs require identity transformations,
it sufficies to check that both source and mask are
untransformed.

This is also the reason that this bug can't be triggered by any test
code - if the source and mask had different transformations, we would
consider them a pixbuf, but then wouldn't take the fast path because
at least one of the transformations would be different from the
identity.
---
 pixman/pixman.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index bbe8b08..e3b6516 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -605,6 +605,7 @@ pixman_image_composite32 (pixman_op_t  op,
 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
(src->type == BITS && src->bits.bits == mask->bits.bits)   &&
(src->common.repeat == mask->common.repeat)&&
+   (src_flags & mask_flags & FAST_PATH_ID_TRANSFORM)  &&
(src_x == mask_x && src_y == mask_y))
 {
if (src_format == PIXMAN_x8b8g8r8)
-- 
1.7.11.4

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


[Pixman] [PATCH 2/2] region: Remove overlap argument from pixman_op()

2012-10-11 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This is used to compute whether the regions in question overlap, but
nothing makes use of this information, so it can be removed.
---
 pixman/pixman-region.c | 53 +-
 1 file changed, 14 insertions(+), 39 deletions(-)

diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 7dbcf9a..c30d49b 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -742,8 +742,7 @@ typedef pixman_bool_t (*overlap_proc_ptr) (region_type_t 
*region,
   box_type_t *   r2,
   box_type_t *   r2_end,
   inty1,
-  inty2,
-  int *  overlap);
+  inty2);
 
 static pixman_bool_t
 pixman_op (region_type_t *  new_reg,   /* Place to store result
*/
@@ -754,10 +753,10 @@ pixman_op (region_type_t *  new_reg,   /* 
Place to store result
   int  append_non1,   /* Append non-overlapping 
bands  
* in region 1 ?
*/
-  int  append_non2,   /* Append non-overlapping 
bands
+  int  append_non2/* Append non-overlapping 
bands
* in region 2 ?
*/
-  int *overlap)
+)
 {
 box_type_t *r1; /* Pointer into first region */
 box_type_t *r2; /* Pointer into 2d region   */
@@ -935,8 +934,7 @@ pixman_op (region_type_t *  new_reg,   /* Place 
to store result
 if (!(*overlap_func)(new_reg,
  r1, r1_band_end,
  r2, r2_band_end,
- ytop, ybot,
- overlap))
+ ytop, ybot))
{
goto bail;
}
@@ -1113,8 +,7 @@ pixman_region_intersect_o (region_type_t *region,
box_type_t *   r2,
box_type_t *   r2_end,
inty1,
-   inty2,
-   int *  overlap)
+   inty2)
 {
 int x1;
 int x2;
@@ -1210,13 +1207,9 @@ PREFIX (_intersect) (region_type_t * new_reg,
 else
 {
 /* General purpose intersection */
-int overlap; /* result ignored */
 
-if (!pixman_op (new_reg, reg1, reg2, pixman_region_intersect_o, FALSE, 
FALSE,
-&overlap))
-   {
+if (!pixman_op (new_reg, reg1, reg2, pixman_region_intersect_o, FALSE, 
FALSE))
return FALSE;
-   }

 pixman_set_extents (new_reg);
 }
@@ -1230,10 +1223,6 @@ PREFIX (_intersect) (region_type_t * new_reg,
 {  \
 if (r->x1 <= x2)   \
{   \
-/* Merge with current rectangle */ \
-if (r->x1 < x2)\
-   *overlap = TRUE;\
-   \
 if (x2 < r->x2)\
x2 = r->x2; \
}   \
@@ -1273,8 +1262,7 @@ pixman_region_union_o (region_type_t *region,
   box_type_t *   r2,
   box_type_t *   r2_end,
   inty1,
-  inty2,
-  int *  overlap)
+  inty2)
 {
 box_type_t *next_rect;
 int x1;/* left and right side of current union */
@@ -1383,8 +1371,6 @@ PREFIX (_union) (region_type_t *new_reg,
  region_type_t *reg1,
  region_type_t *reg2)
 {
-int overlap; /* result ignored */
-
 /* Return TRUE if some overlap
  * between reg1, reg2
  */
@@ -1450,7 +1436,7 @@ PREFIX (_union) (region_type_t *new_reg,
return TRUE;
 }
 
-if (!pixman_op (new_reg, reg1, reg2, pixman_region_union_o, TRUE, TRUE, 
&overlap))
+if (!pixman_op (new_reg, reg1, reg2, pixman_region_union_o, TRUE, TRUE))
return FALSE;
 
 new_reg->extents.x1 = MIN (re

[Pixman] [PATCH 1/2] region: Formatting fix

2012-10-11 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The while part of a do/while loop was formatted as if it were a while
loop with an empty body. Probably some indent tool misinterpreted the
code at some point.
---
 pixman/pixman-region.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 4626f9c..7dbcf9a 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -1517,9 +1517,7 @@ quick_sort_rects (
 r++;
 i++;
}
-
-while (i != numRects && (r->y1 < y1 || (r->y1 == y1 && r->x1 < 
x1)))
-   ;
+   while (i != numRects && (r->y1 < y1 || (r->y1 == y1 && r->x1 < 
x1)));
 
r = &(rects[j]);
 do
-- 
1.7.11.4

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


Re: [Pixman] image byte order?

2012-10-12 Thread Søren Sandmann
Jonathan Morton  writes:

>> > The 24-bit formats are not.
>> 
>> So PIXMAN_r8g8b8 has the red byte first no matter what the endian is,
>> correct?
>
> Yes.  This is potentially useful for subpixel antialiasing masks, BTW.

The 24 bit formats are native endian as well, so PIXMAN_r8g8b8 is a
sequence of [r, g, b] bytes on big endian, and a sequence of [b, g, r]
bytes on little endian.


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


[Pixman] [PATCH] Add new pixman_image_create_bits_no_clear() API

2012-10-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

When pixman_image_create_bits() function is given NULL for bits, it
will allocate a new buffer and initialize it to zero. However, in some
cases, only a small region of the image is actually used; in that case
it is wasteful to touch all of the memory.

The new pixman_image_create_bits_no_clear() works exactly like
_create_bits() except that it doesn't initialize any newly allocated
memory.
---
 pixman/pixman-bits-image.c |   54 +++-
 pixman/pixman-fast-path.c  |3 +-
 pixman/pixman-private.h|3 +-
 pixman/pixman.h|5 
 4 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 029093d..085dd16 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1388,7 +1388,8 @@ static uint32_t *
 create_bits (pixman_format_code_t format,
  int  width,
  int  height,
- int *   rowstride_bytes)
+ int *   rowstride_bytes,
+pixman_bool_tclear)
 {
 int stride;
 size_t buf_size;
@@ -1420,7 +1421,10 @@ create_bits (pixman_format_code_t format,
 if (rowstride_bytes)
*rowstride_bytes = stride;
 
-return calloc (buf_size, 1);
+if (clear)
+   return calloc (buf_size, 1);
+else
+   return malloc (buf_size);
 }
 
 pixman_bool_t
@@ -1429,7 +1433,8 @@ _pixman_bits_image_init (pixman_image_t * image,
  int  width,
  int  height,
  uint32_t *   bits,
- int  rowstride)
+ int  rowstride,
+pixman_bool_tclear)
 {
 uint32_t *free_me = NULL;
 
@@ -1437,7 +1442,7 @@ _pixman_bits_image_init (pixman_image_t * image,
 {
int rowstride_bytes;
 
-   free_me = bits = create_bits (format, width, height, &rowstride_bytes);
+   free_me = bits = create_bits (format, width, height, &rowstride_bytes, 
clear);
 
if (!bits)
return FALSE;
@@ -1465,12 +1470,13 @@ _pixman_bits_image_init (pixman_image_t * image,
 return TRUE;
 }
 
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_bits (pixman_format_code_t format,
-  int  width,
-  int  height,
-  uint32_t *   bits,
-  int  rowstride_bytes)
+static pixman_image_t *
+create_bits_image_internal (pixman_format_code_t format,
+   int  width,
+   int  height,
+   uint32_t *   bits,
+   int  rowstride_bytes,
+   pixman_bool_tclear)
 {
 pixman_image_t *image;
 
@@ -1487,7 +1493,8 @@ pixman_image_create_bits (pixman_format_code_t format,
return NULL;
 
 if (!_pixman_bits_image_init (image, format, width, height, bits,
- rowstride_bytes / (int) sizeof (uint32_t)))
+ rowstride_bytes / (int) sizeof (uint32_t),
+ clear))
 {
free (image);
return NULL;
@@ -1495,3 +1502,28 @@ pixman_image_create_bits (pixman_format_code_t format,
 
 return image;
 }
+
+/* If bits is NULL, a buffer will be allocated and initialized to 0 */
+PIXMAN_EXPORT pixman_image_t *
+pixman_image_create_bits (pixman_format_code_t format,
+  int  width,
+  int  height,
+  uint32_t *   bits,
+  int  rowstride_bytes)
+{
+return create_bits_image_internal (
+   format, width, height, bits, rowstride_bytes, TRUE);
+}
+
+
+/* If bits is NULL, a buffer will be allocated and _not_ initialized */
+PIXMAN_EXPORT pixman_image_t *
+pixman_image_create_bits_no_clear (pixman_format_code_t format,
+  int  width,
+  int  height,
+  uint32_t *   bits,
+  int  rowstride_bytes)
+{
+return create_bits_image_internal (
+   format, width, height, bits, rowstride_bytes, FALSE);
+}
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 22bfd30..a0eed59 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1296,7 +1296,8 @@ fast_composite_tiled_repeat (pixman_implementation_t *imp,
 
/* Initialize/validate stack-allocated temporary image */
_pixman_bi

[Pixman] [PATCH 2/2] pixman_composite_trapezoids(): don't clip to extents for some operators

2012-10-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

pixman_composite_trapezoids() is supposed to composite across the
entire destination, but it actually only composites across the extent
of the trapezoids. For operators such as ADD or OVER this doesn't
matter since a zero source has no effect on the destination. But for
operators such as SRC or IN, it does matter.

So for such operators where a zero source has an effect, don't clip to
the trap extents.
---
 pixman/pixman-trap.c|   43 +++
 test/composite-traps-test.c |2 +-
 2 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index f633738..ab5c8c8 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -387,12 +387,43 @@ pixman_rasterize_trapezoid (pixman_image_t *  
image,
 }
 }
 
+static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] =
+{
+FALSE, /* Clear0   0*/
+FALSE, /* Src  1   0*/
+TRUE,  /* Dst  0   1*/
+TRUE,  /* Over 1   1-Aa */
+TRUE,  /* OverReverse  1-Ab1*/
+FALSE, /* In   Ab  0*/
+FALSE, /* InReverse0   Aa   */
+FALSE, /* Out  1-Ab0*/
+TRUE,  /* OutReverse   0   1-Aa */
+TRUE,  /* Atop Ab  1-Aa */
+FALSE, /* AtopReverse  1-AbAa   */
+TRUE,  /* Xor  1-Ab1-Aa */
+TRUE,  /* Add  1   1*/
+};
+
 static pixman_bool_t
-get_trap_extents (pixman_op_t op, const pixman_trapezoid_t *traps, int n_traps,
+get_trap_extents (pixman_op_t op, pixman_image_t *dest,
+ const pixman_trapezoid_t *traps, int n_traps,
  pixman_box32_t *box)
 {
 int i;
 
+/* When the operator is such that a zero source has an
+ * effect on the underlying image, we have to
+ * composite across the entire destination
+ */
+if (!zero_src_has_no_effect [op])
+{
+   box->x1 = 0;
+   box->y1 = 0;
+   box->x2 = dest->bits.width;
+   box->y2 = dest->bits.height;
+   return TRUE;
+}
+
 box->x1 = INT32_MAX;
 box->y1 = INT32_MAX;
 box->x2 = INT32_MIN;
@@ -443,12 +474,8 @@ get_trap_extents (pixman_op_t op, const pixman_trapezoid_t 
*traps, int n_traps,
  * All the trapezoids are conceptually rendered to an infinitely big image.
  * The (0, 0) coordinates of this image are then aligned with the (x, y)
  * coordinates of the source image, and then both images are aligned with
- * the (x, y) coordinates of the destination. Then, in principle, compositing
- * of these three images takes place across the entire destination.
- *
- * FIXME: However, there is currently a bug, where we restrict this compositing
- * to the bounding box of the trapezoids. This is incorrect for operators such
- * as SRC and IN where blank source pixels do have an effect on the 
destination.
+ * the (x, y) coordinates of the destination. Then these three images are
+ * composited across the entire destination.
  */
 PIXMAN_EXPORT void
 pixman_composite_trapezoids (pixman_op_t   op,
@@ -491,7 +518,7 @@ pixman_composite_trapezoids (pixman_op_top,
pixman_box32_t box;
int i;
 
-   if (!get_trap_extents (op, traps, n_traps, &box))
+   if (!get_trap_extents (op, dst, traps, n_traps, &box))
return;

tmp = pixman_image_create_bits (
diff --git a/test/composite-traps-test.c b/test/composite-traps-test.c
index ff03b50..9fc94a4 100644
--- a/test/composite-traps-test.c
+++ b/test/composite-traps-test.c
@@ -251,6 +251,6 @@ test_composite (int  testnum,
 int
 main (int argc, const char *argv[])
 {
-return fuzzer_test_main("composite traps", 4, 0xE3112106,
+return fuzzer_test_main("composite traps", 4, 0x33BFAA55,
test_composite, argc, argv);
 }
-- 
1.7.4

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


[Pixman] [PATCH 1/2] pixman_composite_trapezoids(): Factor out extents computation

2012-10-12 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The computation of the extents rectangle is moved to its own
function.
---
 pixman/pixman-trap.c |   93 -
 1 files changed, 53 insertions(+), 40 deletions(-)

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index 35128ee..f633738 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -387,6 +387,56 @@ pixman_rasterize_trapezoid (pixman_image_t *  
image,
 }
 }
 
+static pixman_bool_t
+get_trap_extents (pixman_op_t op, const pixman_trapezoid_t *traps, int n_traps,
+ pixman_box32_t *box)
+{
+int i;
+
+box->x1 = INT32_MAX;
+box->y1 = INT32_MAX;
+box->x2 = INT32_MIN;
+box->y2 = INT32_MIN;
+   
+for (i = 0; i < n_traps; ++i)
+{
+   const pixman_trapezoid_t *trap = &(traps[i]);
+   int y1, y2;
+   
+   if (!pixman_trapezoid_valid (trap))
+   continue;
+   
+   y1 = pixman_fixed_to_int (trap->top);
+   if (y1 < box->y1)
+   box->y1 = y1;
+   
+   y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
+   if (y2 > box->y2)
+   box->y2 = y2;
+   
+#define EXTEND_MIN(x)  \
+   if (pixman_fixed_to_int ((x)) < box->x1)\
+   box->x1 = pixman_fixed_to_int ((x));
+#define EXTEND_MAX(x)  \
+   if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box->x2)\
+   box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)));
+   
+#define EXTEND(x)  \
+   EXTEND_MIN(x);  \
+   EXTEND_MAX(x);
+   
+   EXTEND(trap->left.p1.x);
+   EXTEND(trap->left.p2.x);
+   EXTEND(trap->right.p1.x);
+   EXTEND(trap->right.p2.x);
+}
+   
+if (box->x1 >= box->x2 || box->y1 >= box->y2)
+   return FALSE;
+
+return TRUE;
+}
+
 /*
  * pixman_composite_trapezoids()
  *
@@ -439,46 +489,9 @@ pixman_composite_trapezoids (pixman_op_t   op,
 {
pixman_image_t *tmp;
pixman_box32_t box;
-   
-   box.x1 = INT32_MAX;
-   box.y1 = INT32_MAX;
-   box.x2 = INT32_MIN;
-   box.y2 = INT32_MIN;
-   
-   for (i = 0; i < n_traps; ++i)
-   {
-   const pixman_trapezoid_t *trap = &(traps[i]);
-   int y1, y2;
-   
-   if (!pixman_trapezoid_valid (trap))
-   continue;
-   
-   y1 = pixman_fixed_to_int (trap->top);
-   if (y1 < box.y1)
-   box.y1 = y1;
-   
-   y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
-   if (y2 > box.y2)
-   box.y2 = y2;
-   
-#define EXTEND_MIN(x)  \
-   if (pixman_fixed_to_int ((x)) < box.x1) \
-   box.x1 = pixman_fixed_to_int ((x));
-#define EXTEND_MAX(x)  \
-   if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box.x2) \
-   box.x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)));
-   
-#define EXTEND(x)  \
-   EXTEND_MIN(x);  \
-   EXTEND_MAX(x);
-   
-   EXTEND(trap->left.p1.x);
-   EXTEND(trap->left.p2.x);
-   EXTEND(trap->right.p1.x);
-   EXTEND(trap->right.p2.x);
-   }
-   
-   if (box.x1 >= box.x2 || box.y1 >= box.y2)
+   int i;
+
+   if (!get_trap_extents (op, traps, n_traps, &box))
return;

tmp = pixman_image_create_bits (
-- 
1.7.4

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


Re: [Pixman] [PATCH] configure.ac: PIXMAN_LINK_WITH_ENV fix

2012-10-17 Thread Søren Sandmann
Makes sense to me. Pushed to master.

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


[Pixman] [ANNOUNCE] pixman release 0.27.4 now available

2012-10-25 Thread Søren Sandmann
A new pixman release 0.27.4 is now available. This is a release
candidate for a stable 0.28.0 release.

News:

   * Improvements to the MIPS DSPr2 backend
   * Compositing wide formats is done with floating point
   * A large number of bug fixes

Please test and send bug reports to pixman@lists.freedesktop.org or file
them at

https://bugs.freedesktop.org/enter_bug.cgi?product=pixman

Thanks,
Soren


tar.gz:
http://cairographics.org/snapshots/pixman-0.27.4.tar.gz
http://xorg.freedesktop.org/archive/individual/lib/pixman-0.27.4.tar.gz

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

Hashes:
MD5:  d55534b5a691bea305e7bcd5ba654427  pixman-0.27.4.tar.gz
MD5:  e0312169da99576023df25d673132d2f  pixman-0.27.4.tar.bz2
SHA1: 6bd2834e18f77b815047ec27ea8965fa26a36c2b  pixman-0.27.4.tar.gz
SHA1: 42103f7cadaf0a68114d46cf2d3532086313847f  pixman-0.27.4.tar.bz2

GPG signature:
http://cairographics.org/snapshots/pixman-0.27.4.tar.gz.sha1.asc
(signed by Søren Sandmann Pedersen =gcc-4.8

Nemanja Lukic (7):
  MIPS: DSPr2: Added fast-paths for OVER operation: - 
over__n_ - ov
  MIPS: DSPr2: Added fast-paths for OVER operation: - 
over__n_0565 - ov
  MIPS: DSPr2: Added fast-paths for OVER operation: - 
over_0565_n_0565 - ov
  MIPS: DSPr2: Added OVER combiner and two new fast paths: - 
over__
  MIPS: DSPr2: Added fast-paths for ADD operation: - add_n_8_8 - 
add_n_8_88
  MIPS: DSPr2: Added more fast-paths for ADD operation: - 
add_0565_8_0565 -
  MIPS: DSPr2: Added more fast-paths for ADD operation: - 
add___888

Siarhei Siamashka (4):
  Add scaled nearest repeat fast paths
  MIPS: skip runtime detection for DSPr2 if -mdspr2 option is in 
CFLAGS
  Add missing force_inline to in() function used for C fast paths
  Workaround for FTBFS with gcc 4.6 (http://gcc.gnu.org/PR54965)

Søren Sandmann Pedersen (44):
  Post-release version bump to 0.27.3
  Define TIMER_BEGIN and TIMER_END even when timers are not enabled
  Make show_image() cope with more formats
  demos: Add srgb_trap_test.c
  Remove pointless declaration of 
_pixman_image_get_scanline_generic_64()
  Remove obsolete TODO file
  pixel_checker: Move sRGB conversion into get_limits()
  test/utils.c: Use pow(), not powf() in sRGB conversion routines
  implementation: Write lookup_combiner() in a less convoluted way.
  Move blt delegation into pixman-implementation.c
  Move fill delegation into pixman-implementation.c
  Move delegation of src/dest iter init into pixman-implementation.c
  Rename _pixman_lookup_composite_function() to 
_pixman_implementation_look
  _pixman_implementation_create(): Initialize implementation with 
memset()
  implementation: Rename delegate to fallback
  Add PIXMAN_x8b8g8r8 and PIXMAN_a8b8g8r8 formats to scaling-test
  Fix bug in fast_composite_scaled_nearest()
  Fix bugs in component alpha combiners for separable PDF operators
  Add rotate-test.c test program
  Fix bugs in pixman-image.c
  pixman-combine.c.template: Formatting clean-ups
  affine-test: Print out the transformation matrix when verbose
  test: Add inifinite-loop test
  Fix for infinite-loop test
  rotate-test: Call image_endian_swap() in make_image()
  Make pixman.h more const-correct
  glyph-test: Prepare for floating point
  blitters-test: Prepare for floating point
  Add pixman-combine-float.c
  Add combiner test
  pixman-utils.c, pixman-private.h: Add floating point conversion 
routines
  pixman-access.c: Add floating point accessor functions
  Switch the wide pipeline over to using floating point
  Remove 64 bit pipeline
  Don't auto-generate pixman-combine32.[ch] anymore
  Speed up pixman_expand_to_float()
  Remove BUILT_SOURCES
  Only regard images as pixbufs if they have identity 
transformations
  region: Formatting fix
  region: Remove overlap argument from pixman_op()
  Add new pixman_image_create_bits_no_clear() API
  pixman_composite_trapezoids(): Factor out extents computation
  pixman_composite_trapezoids(): don't clip to extents for some 
operators
  Pre-release version bump to 0.27.4
___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


Re: [Pixman] pixman on iOS

2012-11-01 Thread Søren Sandmann
Siarhei Siamashka  writes:

>> > I would suggest to just change the order of checks for
>> > __declspec(thread) and __thread in configure.ac
>> 
>> We should maybe try using -Werror=ignored-attributes in the test, or
>> just prefer the first one.
>
> Using -Werror=ignored-attributes will not help because clang-3.1 (and
> maybe older versions too) just silently ignores __declspec(thread).
> This non-working TLS problem could have been detected by the pixman test
> suite if clang had OpenMP support. In any case, I was just lucky to
> notice the fresh warning when doing preemptive testing for the current
> clang svn (just to be sure that pixman would not need any ugly compiler
> bug workarounds for the upcoming clang-3.2).
>
> Regarding your original patch, how does iOS behave when somebody
> tries to use __thread keyword? Does it fail compilation?

If nobody knows the answer to this, let's just change the order of the
checks as you suggested. We can't support iOS unless someone is willing
to maintain it.


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


Re: [Pixman] [PATCH 3/3] MIPS: DSPr2: Added more fast-paths for OVER operation:

2012-11-05 Thread Søren Sandmann
Nemanja Lukic  writes:

> From: Nemanja Lukic 
>
> Performance numbers before/after on MIPS-74kc @ 1GHz:
>
> lowlevel-blt-bench results
>
> Referent (before):
> over_n_0565 =  L1:  12.04  L2:  21.45  M: 18.50 ( 24.55%)  HT:  6.93  
> VT:  6.45  R:  6.38  RT:  2.16 (  22Kops/s)

This one:

> over_n_ =  L1:  93.76  L2:  85.96  M: 24.41 ( 64.78%)  HT:  8.93  
> VT:  8.08  R:  7.99  RT:  2.54 (  25Kops/s)

> over_n_ =  L1:  55.31  L2:  49.07  M: 28.60 ( 75.93%)  HT: 23.99  
> VT: 22.95  R: 22.34  RT: 12.85 (  61Kops/s)

looks like a performance regression for L1 and L2?


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


[Pixman] [ANNOUNCE] pixman major release 0.28.0 now available

2012-11-07 Thread Søren Sandmann
A new major release 0.28.0 of the pixman rendering library is now
available. Highlights of this release:

  * Support for sRGB coded images [Antti Lankila]

  * New API for fast glyph rendering [Soren Sandmann]

  * Faster bilinear scaling on iwMMX, Loongson and MMX [Matt Turner]

  * More fast paths in the MIPS DSPr2 backend [Nemanja Lukic]

  * Faster scaling in general and on SSE2 in particular [Siarhei
Siamashka]

Please send bug reports to pixman@lists.freedesktop.org or file them at

https://bugs.freedesktop.org/enter_bug.cgi?product=pixman


Thanks,
Soren



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

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

Hashes:
MD5:  0554c354aed2d7845180f310a9a15f20  pixman-0.28.0.tar.gz
MD5:  703c3f62437b161c610056e076560570  pixman-0.28.0.tar.bz2
SHA1: 79828c1a69b459c8cc7d468dd09e2b11ecdc9c19  pixman-0.28.0.tar.gz
SHA1: cfc7a18a8811bf4ff0890f547c315bda8097f6ad  pixman-0.28.0.tar.bz2

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

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

Log:
Andrea Canciani (3):
  build: Fix compilation on win32
  mmx: Fix x86 build on MSVC
  build: Improve win32 build system

Antti S. Lankila (5):
  Faster unorm_to_unorm for wide processing.
  Remove unnecessary dst initialization
  Add support for sRGB surfaces
  Add sRGB blending demo program
  Add tests to validate new sRGB behavior

Benny Siegert (1):
  configure.ac: PIXMAN_LINK_WITH_ENV fix

Matt Turner (22):
  mmx: add and use expand_4xpacked565 function
  mmx: implement expand_4x565 in terms of expand_4xpacked565
  fast: add add_0565_0565 function
  mmx: add add_0565_0565
  mmx: add over_reverse_n_
  mmx: add missing _mm_empty calls
  autotools: use custom build rule to build iwMMXt code
  configure.ac: add iwmmxt2 configure flag
  .gitignore: add test/glyph-test
  sse2: enable over_n_0565 for b5g6r5
  sse2: add src_x888_0565
  Fix distcheck due to custom iwMMXt rules
  mmx: Use expand_alpha instead of mask/shift
  mmx: add scaled bilinear src__
  mmx: add scaled bilinear over__
  mmx: add scaled bilinear over__8_
  mmx: optimize bilinear function when using 7-bit precision
  loongson: optimize _mm_set_pi* functions with shuffle instructions
  sse2: add missing ABGR entires for bilinear src__
  build: Remove useless DEP_CFLAGS/DEP_LIBS variables
  sse2: mark pack_565_2x128_128 as static force_inline
  iwmmxt: Don't define dummy _mm_empty for >=gcc-4.8

Nemanja Lukic (9):
  MIPS: DSPr2: Added several bilinear fast paths with a8 mask
  MIPS: DSPr2: Added more bilinear fast paths (without mask)
  MIPS: DSPr2: Added fast-paths for OVER operation: - 
over__n_ - ov
  MIPS: DSPr2: Added fast-paths for OVER operation: - 
over__n_0565 - ov
  MIPS: DSPr2: Added fast-paths for OVER operation: - 
over_0565_n_0565 - ov
  MIPS: DSPr2: Added OVER combiner and two new fast paths: - 
over__
  MIPS: DSPr2: Added fast-paths for ADD operation: - add_n_8_8 - 
add_n_8_88
  MIPS: DSPr2: Added more fast-paths for ADD operation: - 
add_0565_8_0565 -
  MIPS: DSPr2: Added more fast-paths for ADD operation: - 
add___888

Sebastian Bauer (4):
  Qualify the static variables in pixman_f_transform_invert() with 
the cons
  Changed the style of two function headers
  Added HAVE_CONFIG_H check before including config.h
  Use angle brackets form of including config.h

Siarhei Siamashka (12):
  test: OpenMP 2.5 requires signed loop iteration variables
  test: fix bisecting issue in fuzzer-find-diff.pl
  test: Fix for strict aliasing issue in 'get_random_seed'
  test: support nearest/bilinear scaling in lowlevel-blt-bench
  sse2: faster bilinear scaling (use _mm_loadl_epi64)
  Bilinear interpolation precision is now configurable at compile 
time
  sse2: _mm_madd_epi16 for faster bilinear scaling with 7-bit 
precision
  Change default bilinear interpolation precision to 7 bits
  Add scaled nearest repeat fast paths

[Pixman] [PATCH] pixman_image_composite: Reduce opaque masks to NULL

2012-11-09 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

When the mask is known to be opaque, we might as well reduce it to
NULL to take advantage of the various fast paths that operate on NULL
masks.
---
 pixman/pixman.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman.c b/pixman/pixman.c
index e3b6516..e0ccd87 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -587,7 +587,7 @@ pixman_image_composite32 (pixman_op_t  op,
 src_format = src->common.extended_format_code;
 src_flags = src->common.flags;
 
-if (mask)
+if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE))
 {
mask_format = mask->common.extended_format_code;
mask_flags = mask->common.flags;
-- 
1.7.4

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


[Pixman] [PATCH] pixman.h: Add typedefs for pixman_f_transform and pixman_f_vector

2012-11-09 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

---
 pixman/pixman.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/pixman/pixman.h b/pixman/pixman.h
index c8723cf..33ebf3f 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -226,6 +226,9 @@ pixman_bool_t pixman_transform_is_inverse   (const 
struct pixman_transform *
 /*
  * Floating point matrices
  */
+typedef struct pixman_f_transform pixman_f_transform_t;
+typedef struct pixman_f_vector pixman_f_vector_t;
+
 struct pixman_f_vector
 {
 double  v[3];
-- 
1.7.11.7

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


[Pixman] [PATCH] Allow src and dst to be identical in pixman_f_transform_invert()

2012-11-11 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

It is useful to be able to invert a matrix in place, but currently
pixman_f_transform_invert() will produce wrong results if you pass the
same matrix as both source and destination.

Fix that by inverting into a temporary matrix and then copying that to
the destination.
---
 pixman/pixman-matrix.c |   15 +--
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/pixman/pixman-matrix.c b/pixman/pixman-matrix.c
index a029ab7..d2ab609 100644
--- a/pixman/pixman-matrix.c
+++ b/pixman/pixman-matrix.c
@@ -336,14 +336,14 @@ PIXMAN_EXPORT pixman_bool_t
 pixman_transform_invert (struct pixman_transform *  dst,
  const struct pixman_transform *src)
 {
-struct pixman_f_transform m, r;
+struct pixman_f_transform m;
 
 pixman_f_transform_from_pixman_transform (&m, src);
 
-if (!pixman_f_transform_invert (&r, &m))
+if (!pixman_f_transform_invert (&m, &m))
return FALSE;
 
-if (!pixman_transform_from_pixman_f_transform (dst, &r))
+if (!pixman_transform_from_pixman_f_transform (dst, &m))
return FALSE;
 
 return TRUE;
@@ -469,10 +469,11 @@ PIXMAN_EXPORT pixman_bool_t
 pixman_f_transform_invert (struct pixman_f_transform *  dst,
const struct pixman_f_transform *src)
 {
-double det;
-int i, j;
 static const int a[3] = { 2, 2, 1 };
 static const int b[3] = { 1, 0, 0 };
+pixman_f_transform_t d;
+double det;
+int i, j;
 
 det = 0;
 for (i = 0; i < 3; i++)
@@ -507,10 +508,12 @@ pixman_f_transform_invert (struct pixman_f_transform *
  dst,
if (((i + j) & 1) != 0)
p = -p;

-   dst->m[j][i] = det * p;
+   d.m[j][i] = det * p;
}
 }
 
+*dst = d;
+
 return TRUE;
 }
 
-- 
1.7.4

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


Re: [Pixman] [PATCH] pixman: Use uintptr_t in type casts from pointer to integral value

2012-11-16 Thread Søren Sandmann
Stefan Weil  writes:

> These modifications fix lots of compiler warnings for systems where
> sizeof(unsigned long) != sizeof(void *).
> This is especially true for MinGW-w64 (64 bit Windows).

All three patches pushed to master. I suspect there may be issues with
some versions of MSVC not having uintptr_t, but that will have to be
dealt with by MSVC users.


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


[Pixman] [PATCH 1/3] Round fixed-point multiplication

2012-11-21 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

After two fixed-point numbers are multiplied, the result is shifted
into place, but up until now pixman has simply discarded the low-order
bits instead of rounding to the closest number.

Fix that by adding 0x8000 (or 0x2 in one place) before shifting and
update the test checksums to match.
---
 pixman/pixman-matrix.c |   10 +-
 test/affine-test.c |6 +++---
 test/rotate-test.c |2 +-
 test/scaling-test.c|6 +++---
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/pixman/pixman-matrix.c b/pixman/pixman-matrix.c
index d2ab609..cd2f1b5 100644
--- a/pixman/pixman-matrix.c
+++ b/pixman/pixman-matrix.c
@@ -62,7 +62,7 @@ pixman_transform_point_3d (const struct pixman_transform 
*transform,
{
partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] *
   (pixman_fixed_48_16_t) vector->vector[i]);
-   v += partial >> 16;
+   v += (partial + 0x8000) >> 16;
}

if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
@@ -96,16 +96,16 @@ pixman_transform_point (const struct pixman_transform 
*transform,
{
partial = ((pixman_fixed_32_32_t) transform->matrix[j][i] *
   (pixman_fixed_32_32_t) vector->vector[i]);
-   v[j] += partial >> 2;
+   v[j] += (partial + 2) >> 2;
}
 }
 
-if (!(v[2] >> 16))
+if (!((v[2] + 0x8000) >> 16))
return FALSE;
 
 for (j = 0; j < 2; j++)
 {
-   quo = v[j] / (v[2] >> 16);
+   quo = v[j] / ((v[2] + 0x8000) >> 16);
if (quo > pixman_max_fixed_48_16 || quo < pixman_min_fixed_48_16)
return FALSE;
vector->vector[j] = (pixman_fixed_t) quo;
@@ -138,7 +138,7 @@ pixman_transform_multiply (struct pixman_transform *  
dst,
(pixman_fixed_32_32_t) l->matrix[dy][o] *
(pixman_fixed_32_32_t) r->matrix[o][dx];
 
-   v += partial >> 16;
+   v += (partial + 0x8000) >> 16;
}
 
if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
diff --git a/test/affine-test.c b/test/affine-test.c
index 7bc28b4..daa86c8 100644
--- a/test/affine-test.c
+++ b/test/affine-test.c
@@ -310,11 +310,11 @@ test_composite (int  testnum,
 }
 
 #if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x1EF2175A
+#define CHECKSUM 0x344413F0
 #elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x74050F50
+#define CHECKSUM 0xC8181A76
 #elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0x4362EAE8
+#define CHECKSUM 0xD672A457
 #else
 #define CHECKSUM 0x
 #endif
diff --git a/test/rotate-test.c b/test/rotate-test.c
index d63a289..a0488ef 100644
--- a/test/rotate-test.c
+++ b/test/rotate-test.c
@@ -108,6 +108,6 @@ int
 main (int argc, const char *argv[])
 {
 return fuzzer_test_main ("rotate", 15000,
-0x03A24D51,
+0x5236FD9F,
 test_transform, argc, argv);
 }
diff --git a/test/scaling-test.c b/test/scaling-test.c
index 2736123..0354103 100644
--- a/test/scaling-test.c
+++ b/test/scaling-test.c
@@ -380,11 +380,11 @@ test_composite (int  testnum,
 }
 
 #if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x8D3A7539
+#define CHECKSUM 0x107B67ED
 #elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x03A23E0C
+#define CHECKSUM 0x30EC0CF0
 #elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0xE96D1A5E
+#define CHECKSUM 0x87B496BC
 #else
 #define CHECKSUM 0x
 #endif
-- 
1.7.4

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


[Pixman] [PATCH 0/3] Some rounding related patches

2012-11-21 Thread Søren Sandmann
The following patches fixed-point arithmetic to round instead of
truncate. That is, instead of this:

(a * b) >> 16

the patches now do this instead:

(a * b + 0x8000) >> 16

which I believe produces more accurate results. The second patch does
the same thing for the color calculations in the convolution filter,
where currently if the user isn't careful to normalize the convolution
matrix, we can end up with opaque images becoming slightly translucent
or the like.

Finally, the third patch adds a file "rounding.txt" that describes in
detail how the filtering code gets from a source image location to a
pixel value.

The fixed-point rounding does cause some changes to transformed
output, so the test suite has gotten new checksums. I'd appreciate
testing on architectures other than x86 to ensure the various
transformed fast paths didn't break.

Siarhei pointed out here:

   http://lists.freedesktop.org/archives/pixman/2012-June/002095.html

that the current bilinear filters also have an issue where the weights
are computed based on truncated rather than rounded locations. In
addition to that they also have the same issue as the convolution
filter in that the *color* computation should in principle also be
rounded rather than truncated from 16 to 8 bits as it is now.

It would be worthwhile to fix these bugs, but the patches here don't
attempt to.


Soren


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


[Pixman] [PATCH 2/3] Convolution filter: round color values instead of truncating

2012-11-21 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The pixel computed by the convolution filter should be rounded off,
not truncated. As a simple example consider a convolution matrix
consisting of five times 0x. If all five all five input pixels are
0xff, then the result of truncating will be

(5 * 0x * 255) >> 16 = 254

But the real value of the computation is (5 * 0x / 65536.0) * 254
= 254.9961, so the error is almost 1. If the user isn't very careful
about normalizing the convolution kernel so that it sums to one in
fixed point, such error might cause solid images to change color, or
opaque images to become translucent.

The fix is simply to round instead of truncate.
---
 pixman/pixman-bits-image.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 085dd16..7787ef1 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -413,10 +413,10 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
}
 }
 
-satot >>= 16;
-srtot >>= 16;
-sgtot >>= 16;
-sbtot >>= 16;
+satot = (satot + 0x8000) >> 16;
+srtot = (srtot + 0x8000) >> 16;
+sgtot = (sgtot + 0x8000) >> 16;
+sbtot = (sbtot + 0x8000) >> 16;
 
 satot = CLIP (satot, 0, 0xff);
 srtot = CLIP (srtot, 0, 0xff);
-- 
1.7.4

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


[Pixman] [PATCH 3/3] Add text file rounding.txt describing how rounding works

2012-11-21 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

It is not entirely obvious how pixman gets from "location in the
source image" to "pixel value stored in the destination". This file
describes how the filters work, and in particular how positions are
rounded to samples.
---
 pixman/rounding.txt |  134 +++
 1 files changed, 134 insertions(+), 0 deletions(-)
 create mode 100644 pixman/rounding.txt

diff --git a/pixman/rounding.txt b/pixman/rounding.txt
new file mode 100644
index 000..1a19f45
--- /dev/null
+++ b/pixman/rounding.txt
@@ -0,0 +1,134 @@
+*** General notes about rounding
+
+Suppose a function is sampled at positions [k + o] where k is an
+integer and o is a fractional offset 0 <= o < 1.
+
+To round a value to the nearest sample, breaking ties by rounding up,
+we can do this:
+
+   round(x) = floor(x - o + 0.5) + o
+
+That is, first subtract o to let us pretend that the samples are at
+integer coordinates, then add 0.5 and floor to round to nearest
+integer, then add the offset back in.
+
+To break ties by rounding down:
+
+round(x) = ceil(x - o - 0.5) + o
+
+or if we have an epsilon value:
+
+round(x) = floor(x - o + 0.5 - e) + o
+
+To always round *up* to the next sample:
+
+round_up(x) = ceil(x - o) + o
+
+To always round *down* to the previous sample:
+
+round_down(x) = floor(x - o) + o
+
+If a set of samples is stored in an array, you get from the sample
+position to an index by subtracting the position of the first sample
+in the array:
+
+index(s) = s - first_sample
+
+
+*** Application to pixman
+
+In pixman, images are sampled with o = 0.5, that is, pixels are
+located midways between integers. We usually break ties by rounding
+down (i.e., "round towards north-west").
+
+
+-- NEAREST filtering:
+
+The NEAREST filter simply picks the closest pixel to the given
+position:
+
+round(x) = floor(x - 0.5 + 0.5 - e) + 0.5 = floor (x - e) + 0.5
+
+The first sample of a pixman image has position 0.5, so to find the
+index in the pixel array, we have to subtract 0.5:
+
+floor (x - e) + 0.5 - 0.5 = floor (x - e).
+
+Therefore a 16.16 fixed-point image location is turned into a pixel
+value with NEAREST filtering by doing this:
+
+pixels[((y - e) >> 16) * stride + ((x - e) >> 16)]
+
+where stride is the number of pixels allocated per scanline and e =
+0x0001.
+
+
+-- CONVOLUTION filtering:
+
+A convolution matrix is considered a sampling of a function f at
+values surrounding 0. For example, this convolution matrix:
+
+   [a, b, c, d]
+
+is interpreted as the values of a function f:
+
+   a = f(-1.5)
+b = f(-0.5)
+c = f(0.5)
+d = f(1.5)
+
+The sample offset in this case is o = 0.5 and the first sample has
+position s0 = -1.5. If the matrix is:
+
+[a, b, c, d, e]
+
+the sample offset is o = 0 and the first sample has position s0 =
+-2.0. In general we have 
+
+  s0 = (- width / 2.0 + 0.5).
+
+and
+
+  o = frac (s0)
+
+To evaluate f at a position between the samples, we round to the
+closest sample, and then we subtract the position of the first sample
+to get the index in the matrix:
+
+   f(t) = matrix[floor(t - o + 0.5) + o - s0]
+
+Note that in this case we break ties by rounding up.
+
+If we write s0 = m + o, where m is an integer, this is equivalent to
+
+f(t) = matrix[floor(t - o + 0.5) + o - (m + o)]
+= matrix[floor(t - o + 0.5 - m) + o - o]
+= matrix[floor(t - s0 + 0.5)]
+
+The convolution filter in pixman positions f such that 0 aligns with
+the given position x. For a given pixel x0 in the image, the closest
+sample of f is then computed by taking (x - x0) and rounding that to
+the closest index:
+
+   i = floor ((x0 - x) - s0 + 0.5)
+
+To perform the convolution, we have to find the first pixel x0 whose
+corresponding sample has index 0. We can write x0 = k + 0.5, where k
+is an integer:
+
+ 0 = floor(k + 0.5 - x - s0 + 0.5)
+
+  = k + floor(1 - x - s0)
+
+  = k - ceil(x + s0 - 1)
+
+  = k - floor(x + s0 - e)
+
+  = k - floor(x - (width - 1) / 2.0 - e)
+
+And so the final formula for the index k of x0 in the image is:
+
+   k = floor(x - (width - 1) / 2.0 - e)
+
+Computing the result is then simply a matter of convolving all the
+pixels starting at k with all the samples in the matrix.
-- 
1.7.4

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


[Pixman] Image resampling [PATCH 0/6]

2012-11-23 Thread Søren Sandmann
Hi,

Reviewing the supersampling patch here:

   http://cgit.freedesktop.org/~ajohnson/pixman/log/?h=supersampling

I wasn't happy with either the performance and image quality, and I
realized that the whole supersampling approach just isn't going to
fly. Since I told people to do it that way, I apologize for that. The
approach advocated by Bill Spitzak in the various downsampling threads
of computing a convolution kernel up front, is the much better way to
go. To make up for being misleading, the following patches implement
comprehensive support for high-quality image scaling filters.

Pixman already has a convolution filter, but since it only allows one
sample per pixel of the filter, it is limited in the quality that it can
support, so the following patches (to be applied on top of the three
rounding patches) add a new filter type

PIXMAN_FILTER_SEPARABLE_CONVOLUTION

that supports multiple different convolution matrices that are chosen
between based on the subpixel source location. The matrices are
specified as tensor products of x/y vectors, which makes them
separable by definition.

The patches also add a helper function

pixman_filter_create_separable_convolution()

that will create the parameters for the filter based on scaling
factors, filter kernels and subsampling resolution. Currently the
supported kernels are impulse, box, linear, cubic
(Mitchell-Netravali), lanczos2, lanczos3, lanczos3_stretched
(aka. Blinn's 'Nice' filter), and Gaussian.

There also a new demo program "demos/scale" that shows how
the new API can be used.

For some useful math regarding image transformations, see
http://people.redhat.com/otaylor/gtk/pixbuf-transform-math.ps . For
some informatino about how to compute the convolution matrices, see
the additions to rounding.txt in the second patch.


-=- Adding support to cairo and further work

Once these patches have landed in Pixman, support will have to be
added to cairo to make use of them. How to do that exactly requires
figuring out what new API to offer, and how the tradeoffs between
performance and quality should be made. This is not something that I
personally plan to work on anytime soon, except to make three notes:

  - While transformations that are not pure scalings will not
generally result in a separable filter, OK-looking results for
non-scalings can be achieved by using scaling factors based on the
bounding box of a transformation 

  - For equivalent quality to GdkPixbuf do this: In each direction
compute the scaling factors and then, if the scaling factor is
less than 1 (ie., a downscaling), use PIXMAN_KERNEL_BOX for both
reconstruction and sampling, and if it's greater than one, use
PIXMAN_KERNEL_LINEAR for reconstruction and PIXMAN_KERNEL_IMPULSE
for sampling.

  - If PIXMAN_KERNEL_GAUSSIAN is used with large downscaling factors
and the resulting filter is then used with an identity transform,
the result is a Gaussian blur, which is a feature that has
sometimes been requested.

The code in demos/scale.c may be useful as an example.


-=- Further work and examples

There is some additional work that could be done:

- Performance improvements. Low-hanging fruit includes adding new fast
  path iterators that assume the source is a8r8g8b8 or r5g6b5. Higher
  hanging fruit is SIMD optimziations and implementations that take
  advantage of separability. It may also be interesting to speed up
  pixman_filter_create_separable_convolution() by tabularizing some of
  the trigonometric functions etc.

- A non-separable, but subsampled, convolution filter type could be
  interesting to allow correct filters for non-scaling transformations
  and non-separable filters in general.


As a reward for reading this entire mail, here are some images:

Original (2.6 MB):

 http://www.daimi.au.dk/~sandmann/house.jpg

Scaled down 12.9 times in each dimension:

- With a box filter:

   http://www.daimi.au.dk/~sandmann/house-box.png

- With Lanczos3:

   http://www.daimi.au.dk/~sandmann/house-lanczos3.png

- With stretched Lanczos3:

   http://www.daimi.au.dk/~sandmann/house-nice.png

For more examples, try demos/scale.

The patch series is also available in this repository:

http://cgit.freedesktop.org/~sandmann/pixman/log/?h=separable


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


[Pixman] [PATCH 4/6] demos/gtk-utils.[ch]: Add pixman_image_from_file()

2012-11-23 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This function uses GdkPixbuf to load various common formats such as
.png and .jpg into a pixman image.
---
 demos/gtk-utils.c |   66 +
 demos/gtk-utils.h |3 ++
 2 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/demos/gtk-utils.c b/demos/gtk-utils.c
index 8291a1e..d7e946d 100644
--- a/demos/gtk-utils.c
+++ b/demos/gtk-utils.c
@@ -3,6 +3,72 @@
 #include "../test/utils.h"
 #include "gtk-utils.h"
 
+pixman_image_t *
+pixman_image_from_file (const char *filename, pixman_format_code_t format)
+{
+GdkPixbuf *pixbuf;
+pixman_image_t *image;
+int width, height;
+uint32_t *data, *d;
+uint8_t *gdk_data;
+int n_channels;
+int j, i;
+int stride;
+
+if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL)))
+   return NULL;
+
+image = NULL;
+
+width = gdk_pixbuf_get_width (pixbuf);
+height = gdk_pixbuf_get_height (pixbuf);
+n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+gdk_data = gdk_pixbuf_get_pixels (pixbuf);
+stride = gdk_pixbuf_get_rowstride (pixbuf);
+
+if (!(data = malloc (width * height * sizeof (uint32_t
+   goto out;
+
+d = data;
+for (j = 0; j < height; ++j)
+{
+   uint8_t *gdk_line = gdk_data;
+
+   for (i = 0; i < width; ++i)
+   {
+   int r, g, b, a;
+   uint32_t pixel;
+
+   r = gdk_line[0];
+   g = gdk_line[1];
+   b = gdk_line[2];
+
+   if (n_channels == 4)
+   a = gdk_line[3];
+   else
+   a = 0xff;
+
+   r = (r * a + 127) / 255;
+   g = (g * a + 127) / 255;
+   b = (b * a + 127) / 255;
+
+   pixel = (a << 24) | (r << 16) | (g << 8) | b;
+
+   *d++ = pixel;
+   gdk_line += n_channels;
+   }
+
+   gdk_data += stride;
+}
+
+image = pixman_image_create_bits (
+   format, width, height, data, width * 4);
+
+out:
+g_object_unref (pixbuf);
+return image;
+}
+
 GdkPixbuf *
 pixbuf_from_argb32 (uint32_t *bits,
int width,
diff --git a/demos/gtk-utils.h b/demos/gtk-utils.h
index 55cb701..36be4de 100644
--- a/demos/gtk-utils.h
+++ b/demos/gtk-utils.h
@@ -6,6 +6,9 @@
 
 void show_image (pixman_image_t *image);
 
+pixman_image_t *
+pixman_image_from_file (const char *filename, pixman_format_code_t format);
+
 GdkPixbuf *pixbuf_from_argb32 (uint32_t *bits,
int width,
int height,
-- 
1.7.4

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


[Pixman] [PATCH 1/6] Add new filter PIXMAN_FILTER_SEPARABLE_CONVOLUTION

2012-11-23 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This filter is a new way to use a convolution matrix for filtering. In
contrast to the existing CONVOLUTION filter, this new variant is
different in two respects:

- It is subsampled: Instead of just one convolution matrix, this
  filter chooses between a number of matrices based on the subpixel
  sample location, allowing the convolution kernel to be sampled at a
  higher resolution.

- It is separable: Each matrix is specified as the tensor product of
  two vectors. This has the advantages that many fewer values have to
  be stored, and that the filtering can be done separately in the x
  and y dimensions (although the initial implementation doesn't
  actually do that).

The motivation for this new filter is to improve image downsampling
quality. Currently, the best pixman can do is the regular convolution
filter which is limited to coarsely sampled convolution kernels.

With this new feature, any separable filter can be used at any desired
resolution.
---
 pixman/pixman-bits-image.c |  102 
 pixman/pixman-image.c  |   19 +++-
 pixman/pixman.c|8 +++
 pixman/pixman.h|   23 +-
 4 files changed, 149 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 7787ef1..97db108 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -426,6 +426,104 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
 return ((satot << 24) | (srtot << 16) | (sgtot <<  8) | (sbtot));
 }
 
+static uint32_t
+bits_image_fetch_pixel_convolution_separable (bits_image_t *image,
+  pixman_fixed_t x,
+  pixman_fixed_t y,
+  get_pixel_tget_pixel)
+{
+pixman_fixed_t *params = image->common.filter_params;
+pixman_repeat_t repeat_mode = image->common.repeat;
+int width = image->width;
+int height = image->height;
+int cwidth = pixman_fixed_to_int (params[0]);
+int cheight = pixman_fixed_to_int (params[1]);
+int x_phase_bits = pixman_fixed_to_int (params[2]);
+int y_phase_bits = pixman_fixed_to_int (params[3]);
+int x_phase_shift = 16 - x_phase_bits;
+int y_phase_shift = 16 - y_phase_bits;
+int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
+int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
+pixman_fixed_t *y_params;
+int srtot, sgtot, sbtot, satot;
+int32_t x1, x2, y1, y2;
+int32_t px, py;
+int i, j;
+
+/* Round x and y to the middle of the closest phase before continuing. This
+ * ensures that the convolution matrix is aligned right, since it was
+ * positioned relative to a particular phase (and not relative to whatever
+ * exact fraction we happen to get here).
+ */
+x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
+y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
+
+px = (x & 0x) >> x_phase_shift;
+py = (y & 0x) >> y_phase_shift;
+
+y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
+
+x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
+y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
+x2 = x1 + cwidth;
+y2 = y1 + cheight;
+
+srtot = sgtot = sbtot = satot = 0;
+
+for (i = y1; i < y2; ++i)
+{
+pixman_fixed_48_16_t fy = *y_params++;
+pixman_fixed_t *x_params = params + 4 + px * cwidth;
+
+if (fy)
+{
+for (j = x1; j < x2; ++j)
+{
+pixman_fixed_t fx = *x_params++;
+   int rx = j;
+   int ry = i;
+
+if (fx)
+{
+pixman_fixed_t f;
+uint32_t pixel;
+
+if (repeat_mode != PIXMAN_REPEAT_NONE)
+{
+repeat (repeat_mode, &rx, width);
+repeat (repeat_mode, &ry, height);
+
+pixel = get_pixel (image, rx, ry, FALSE);
+}
+else
+{
+pixel = get_pixel (image, rx, ry, TRUE);
+   }
+
+f = (fy * fx + 0x8000) >> 16;
+
+srtot += (int)RED_8 (pixel) * f;
+sgtot += (int)GREEN_8 (pixel) * f;
+sbtot += (int)BLUE_8 (pixel) * f;
+satot += (int)ALPHA_8 (pixel) * f;
+}
+}
+   }
+}
+
+satot = (satot + 0x8000) >> 16;
+srtot = (srtot + 0x8000) >> 16;
+sgtot = (sgtot + 0x8000) >> 16;
+sbtot = (sbtot + 0x8000) >> 16;
+
+   

[Pixman] [PATCH 2/6] rounding.txt: Describe how SEPARABLE_CONVOLUTION filter works

2012-11-23 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Add some notes on how to compute the convolution matrices to be used
with the SEPARABLE_CONVOLUTION filter.
---
 pixman/rounding.txt |   33 +
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/pixman/rounding.txt b/pixman/rounding.txt
index 1a19f45..b52b084 100644
--- a/pixman/rounding.txt
+++ b/pixman/rounding.txt
@@ -132,3 +132,36 @@ And so the final formula for the index k of x0 in the 
image is:
 
 Computing the result is then simply a matter of convolving all the
 pixels starting at k with all the samples in the matrix.
+
+
+--- SEPARABLE_CONVOLUTION
+
+For this filter, x is first rounded to one of n regularly spaced
+subpixel positions. This subpixel position determines which of n
+convolution matrices is being used.
+
+Then, as in a regular convolution filter, the first pixel to be used
+is determined:
+
+   k = floor (x - (width - 1) / 2.0 - e)
+
+and then the image pixels starting there are convolved with the chosen
+matrix. If we write x = xi + frac, where xi is an integer, we get
+
+   k = xi + floor (frac - (width - 1) / 2.0 - e)
+
+so the location of k relative to x is given by:
+
+(k + 0.5 - x) = xi + floor (frac - (width - 1) / 2.0 - e) + 0.5 - x
+
+  = floor (frac - (width - 1) / 2.0 - e) + 0.5 - frac
+
+which means the contents of the matrix corresponding to (frac) should
+contain width samplings of the function, with the first sample at:
+
+   floor (frac - (width - 1) / 2.0 - e) + 0.5 - frac
+
+This filter is called separable because each of the k x k convolution
+matrices is specified with two k-wide vectors, one for each dimension,
+where each entry in the matrix is computed as the product of the
+corresponding entries in the vectors.
-- 
1.7.4

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


[Pixman] [PATCH 3/6] Add new pixman_filter_create_separable_convolution() API

2012-11-23 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This new API is a helper function to create filter parameters suitable
for use with PIXMAN_FILTER_SEPARABLE_CONVOLUTION.

For each dimension, given a scale factor, reconstruction and sample
filter kernels, and a subsampling resolution, this function will
compute a convolution of the two kernels scaled appropriately, then
sample that convolution and return the resulting vectors in a form
suitable for being used as parameters to
PIXMAN_FILTER_SEPARABLE_CONVOLUTION.

The filter kernels offered are the following:

  - IMPULSE:Dirac delta function, ie., point sampling
  - BOX:Box filter
  - LINEAR: Linear filter, aka. "Tent" filter
  - CUBIC:  Cubic filter, currently Mitchell-Netravali
  - GAUSSIAN:   Gaussian function, sigma=1, support=3*sigma
  - LANCZOS2:   Two-lobed Lanczos filter
  - LANCZOS3:   Three-lobed Lanczos filter
  - LANCZOS3_STRETCHED: Three-lobed Lanczos filter, stretched by 4/3.0.
This is the "Nice" filter from Dirty Pixels by
Jim Blinn.

The intended way to use this function is to extract scaling factors
from the transformation and then pass those to this function to get a
filter suitable for compositing with that transformation. The filter
kernels can be chosen according to quality and performance tradeoffs.

To get equivalent quality to GdkPixbuf for downscalings, use BOX for
both reconstruction and sampling. For upscalings, use LINEAR for
reconstruction and IMPULSE for sampling (though note that for
upscaling in both X and Y directions, simply using
PIXMAN_FILTER_BILINEAR will likely be a better choice).
---
 pixman/Makefile.sources |1 +
 pixman/pixman-filter.c  |  340 +++
 pixman/pixman.h |   27 
 3 files changed, 368 insertions(+), 0 deletions(-)
 create mode 100644 pixman/pixman-filter.c

diff --git a/pixman/Makefile.sources b/pixman/Makefile.sources
index 5351fb0..c624eb9 100644
--- a/pixman/Makefile.sources
+++ b/pixman/Makefile.sources
@@ -6,6 +6,7 @@ libpixman_sources = \
pixman-combine32.c  \
pixman-combine-float.c  \
pixman-conical-gradient.c   \
+   pixman-filter.c \
pixman-x86.c\
pixman-mips.c   \
pixman-arm.c\
diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
new file mode 100644
index 000..c9d2dc7
--- /dev/null
+++ b/pixman/pixman-filter.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2012, Red Hat, Inc.
+ * Copyright 2012, Soren Sandmann
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Soren Sandmann 
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "pixman-private.h"
+
+typedef double (* kernel_func_t) (double x);
+
+typedef struct
+{
+pixman_kernel_tkernel;
+kernel_func_t  func;
+double width;
+} filter_info_t;
+
+static double
+impulse_kernel (double x)
+{
+return (x == 0.0)? 1.0 : 0.0;
+}
+
+static double
+box_kernel (double x)
+{
+return 1;
+}
+
+static double
+linear_kernel (double x)
+{
+return 1 - fabs (x);
+}
+
+static double
+gaussian_kernel (double x)
+{
+#define SQRT2 (1.4142135623730950488016887242096980785696718753769480)
+#define SIGMA (SQRT2 / 2.0)
+
+return exp (- x * x / (2 * SIGMA * SIGMA)) / (SIGMA * sqrt (2.0 * M_PI));
+}
+
+static double
+sinc (double x)
+{
+if (x == 0.0)
+   return 1.0;
+else
+   return sin (M_PI * x) / (M_PI * x);
+}
+
+static double
+lanczos (double x, int n)
+{
+return sinc (x) * sinc (x * (1.0 / n));
+}
+
+static double
+lanczos2_kernel (double x)
+{
+return lanczos (x, 2);
+}
+
+static double
+lanczos3_kernel (dou

[Pixman] [PATCH 5/6] demos: Add new demo program, "scale"

2012-11-23 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This program allows interactively scaling and rotating images with
using various filters and repeat modes. It uses
pixman_filter_create_separate_convolution() to generate the filters.
---
 demos/Makefile.am |6 +-
 demos/scale.c |  431 +
 demos/scale.ui|  302 +
 3 files changed, 737 insertions(+), 2 deletions(-)
 create mode 100644 demos/scale.c
 create mode 100644 demos/scale.ui

diff --git a/demos/Makefile.am b/demos/Makefile.am
index f324f5f..ffb7a6b 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -22,9 +22,10 @@ DEMOS =  \
quad2quad   \
checkerboard\
srgb-trap-test  \
-   srgb-test
+   srgb-test   \
+   scale
 
-EXTRA_DIST = parrot.c parrot.jpg
+EXTRA_DIST = parrot.c parrot.jpg scale.ui
 
 gradient_test_SOURCES = gradient-test.c $(GTK_UTILS)
 alpha_test_SOURCES = alpha-test.c $(GTK_UTILS)
@@ -39,6 +40,7 @@ tri_test_SOURCES = tri-test.c $(GTK_UTILS)
 checkerboard_SOURCES = checkerboard.c $(GTK_UTILS)
 srgb_test_SOURCES = srgb-test.c $(GTK_UTILS)
 srgb_trap_test_SOURCES = srgb-trap-test.c $(GTK_UTILS)
+scale_SOURCES = scale.c $(GTK_UTILS)
 
 noinst_PROGRAMS = $(DEMOS)
 
diff --git a/demos/scale.c b/demos/scale.c
new file mode 100644
index 000..9100ff7
--- /dev/null
+++ b/demos/scale.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright 2012, Red Hat, Inc.
+ * Copyright 2012, Soren Sandmann
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Soren Sandmann 
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include 
+#include 
+#include 
+#include 
+#include "gtk-utils.h"
+
+typedef struct
+{
+GtkBuilder *builder;
+pixman_image_t *   original;
+GtkAdjustment * scale_x_adjustment;
+GtkAdjustment * scale_y_adjustment;
+GtkAdjustment * rotate_adjustment;
+int scaled_width;
+int scaled_height;
+} app_t;
+
+static GtkWidget *
+get_widget (app_t *app, const char *name)
+{
+GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (app->builder, 
name));
+
+if (!widget)
+g_error ("Widget %s not found\n", name);
+
+return widget;
+}
+
+static double
+min4 (double a, double b, double c, double d)
+{
+double m1, m2;
+
+m1 = MIN (a, b);
+m2 = MIN (c, d);
+return MIN (m1, m2);
+}
+
+static double
+max4 (double a, double b, double c, double d)
+{
+double m1, m2;
+
+m1 = MAX (a, b);
+m2 = MAX (c, d);
+return MAX (m1, m2);
+}
+
+static void
+compute_extents (pixman_f_transform_t *trans, double *sx, double *sy)
+{
+double min_x, max_x, min_y, max_y;
+pixman_f_vector_t v[4] =
+{
+   { { 1, 1, 1 } },
+   { { -1, 1, 1 } },
+   { { -1, -1, 1 } },
+   { { 1, -1, 1 } },
+};
+
+pixman_f_transform_point (trans, &v[0]);
+pixman_f_transform_point (trans, &v[1]);
+pixman_f_transform_point (trans, &v[2]);
+pixman_f_transform_point (trans, &v[3]);
+
+min_x = min4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]);
+max_x = max4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]);
+min_y = min4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]);
+max_y = max4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]);
+
+*sx = (max_x - min_x) / 2.0;
+*sy = (max_y - min_y) / 2.0;
+}
+
+typedef struct
+{
+char   name [20];
+pixman_kernel_tvalue;
+} named_int_t;
+
+static const named_int_t filters[] =
+{
+{ "Box",   PIXMAN_KERNEL_BOX },
+{ "Impulse",   PIXMAN_KERNEL_IMPULSE },
+{ "Linear",PIXMAN_KERNEL_LINEAR },
+{ "Cubic", 

Re: [Pixman] [PATCH 6/6] Add demos/zone_plate.png

2012-11-26 Thread Søren Sandmann
Siarhei Siamashka  writes:

> Hi, the size of this PNG file can be cut in half:
>
> $ optipng -o7 zone_plate.png 
> ** Processing: zone_plate.png
> 512x512 pixels, 3x8 bits/pixel, RGB
> Reducing image to 8 bits/pixel, grayscale
> Input IDAT size = 522048 bytes
> Input file size = 522879 bytes

Good point. I'll run it through optipng before pushing.


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


Re: [Pixman] Image resampling [PATCH 0/6]

2012-11-27 Thread Søren Sandmann
Søren Sandmann  writes:

> There is some additional work that could be done:
>
> - Performance improvements. Low-hanging fruit includes adding new fast
>   path iterators that assume the source is a8r8g8b8 or r5g6b5.

I went ahead and wrote some affine fast paths. There is still room for
improvement though.


Søren



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


[Pixman] [PATCH] Add fast paths for separable convolution

2012-11-27 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Similar to the fetchers for affine bilinear and nearest, add some fast
paths for the separable convolution filter for all combinations of
formats x8r8g8b8, a8r8g8b8, r5g6b5, a8 with the four repeat modes.

On a 1.2GHz AMD Phenom the time to scale down a 3200x1200 image by
9.22 went from 0.2238s to 0.1875s, an improvement of about 16%. For
comparison GdkPixbuf does the same thing in about 0.07s, so there is
still a lot of room for improvement.
---
 pixman/pixman-bits-image.c |  183 +++-
 pixman/pixman-image.c  |3 +
 pixman/pixman-private.h|1 +
 3 files changed, 184 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index e76b78c..86d80c3 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -720,11 +720,155 @@ bits_image_fetch_general (pixman_iter_t  *iter,
 return buffer;
 }
 
-static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
 typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
 
 static force_inline void
+bits_image_fetch_separable_convolution_affine (pixman_image_t * image,
+  int  offset,
+  int  line,
+  int  width,
+  uint32_t *   buffer,
+  const uint32_t * mask,
+
+  convert_pixel_t  convert_pixel,
+  pixman_format_code_t format,
+  pixman_repeat_t  repeat_mode)
+{
+bits_image_t *bits = &image->bits;
+pixman_fixed_t *params = image->common.filter_params;
+int cwidth = pixman_fixed_to_int (params[0]);
+int cheight = pixman_fixed_to_int (params[1]);
+int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
+int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
+int x_phase_bits = pixman_fixed_to_int (params[2]);
+int y_phase_bits = pixman_fixed_to_int (params[3]);
+int x_phase_shift = 16 - x_phase_bits;
+int y_phase_shift = 16 - y_phase_bits;
+pixman_fixed_t vx, vy;
+pixman_fixed_t ux, uy;
+pixman_vector_t v;
+int k;
+
+/* reference point is the center of the pixel */
+v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
+v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
+v.vector[2] = pixman_fixed_1;
+
+if (!pixman_transform_point_3d (image->common.transform, &v))
+   return;
+
+ux = image->common.transform->matrix[0][0];
+uy = image->common.transform->matrix[1][0];
+
+vx = v.vector[0];
+vy = v.vector[1];
+
+for (k = 0; k < width; ++k)
+{
+   pixman_fixed_t *y_params;
+   int satot, srtot, sgtot, sbtot;
+   pixman_fixed_t x, y;
+   int32_t x1, x2, y1, y2;
+   int32_t px, py;
+   int i, j;
+
+   if (mask && !mask[k])
+   goto next;
+
+   /* Round x and y to the middle of the closest phase before continuing. 
This
+* ensures that the convolution matrix is aligned right, since it was
+* positioned relative to a particular phase (and not relative to 
whatever
+* exact fraction we happen to get here).
+*/
+   x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 
1);
+   y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 
1);
+
+   px = (x & 0x) >> x_phase_shift;
+   py = (y & 0x) >> y_phase_shift;
+
+   x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
+   y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
+   x2 = x1 + cwidth;
+   y2 = y1 + cheight;
+
+   satot = srtot = sgtot = sbtot = 0;
+
+   y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
+
+   for (i = y1; i < y2; ++i)
+   {
+   pixman_fixed_t fy = *y_params++;
+
+   if (fy)
+   {
+   pixman_fixed_t *x_params = params + 4 + px * cwidth;
+
+   for (j = x1; j < x2; ++j)
+   {
+   pixman_fixed_t fx = *x_params++;
+   int rx = j;
+   int ry = i;
+   
+   if (fx)
+   {
+   pixman_fixed_t f;
+   uint32_t pixel, mask;
+   uint8_t *row;
+
+   mask = PIXMAN_FORMAT_A (format)? 0 : 0xff00;
+
+   if (repeat_mode != PIXMAN_REPEAT_NONE)
+   {
+   repeat (repeat_mode, &rx, bits->width);
+   repeat (re

Re: [Pixman] [PATCH 0/5] PRNG upgrade for pixman tests

2012-11-29 Thread Søren Sandmann
Siarhei Siamashka  writes:

> A simple linear congruential generator (LCG) has been used for pixman
> test suite since the introduction of the tests based on random fuzzing.
> There was no particular reason why it was selected. The compilers are
> traditionally using LCG. So just implementing LCG for pixman tests, we
> got it as good (and as bad) as "rand" from the C library, but
> deterministic, predictable and fully under our control.
>
> But LCG has some practical issues, which are already showing up:

This patch series looks like a very nice improvement. Excellent work as
always.

> As for the SIMD implementation, I decided to take a somewhat unusual
> approach. Typically one uses CPU-specific intrinsics. This provides
> support for just one hardware platform (let's say x86 SSE2), but
> with a choice of multiple compilers (gcc, clang, icc, ...). I decided
> to do this the other way around :) And implemented the code using
> the GCC specific vector extensions:
> http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
> This means that just a single compiler is supported (GCC 4.7 or newer),
> but the code is quite conveniently optimized for multiple platforms at
> once (x86 SSE2, ARM NEON, PPC Altivec, ...).

It might be interesting to try using these extensions within pixman
itself as a fallback for the cases where we don't have CPU specific fast
paths.


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


[Pixman] [PATCH] Add demo program for conical gradients

2012-12-05 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This new test is derived from radial-test.c and displays conical
gradients at various angles.

It also demonstrates how PIXMAN_REPEAT_NORMAL is supposed to work when
used with a gradient specification where the first stop is not a 0.0:
In this case the gradient is supposed to have a smooth transition from
the last stop back to the first stop with no sharp transitions. It
also shows that the repeat mode is not ignored for conical gradients
as one might be tempted to think.
---
 demos/Makefile.am|2 +
 demos/conical-test.c |  134 ++
 2 files changed, 136 insertions(+), 0 deletions(-)
 create mode 100644 demos/conical-test.c

diff --git a/demos/Makefile.am b/demos/Makefile.am
index ffb7a6b..4d88cb8 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -14,6 +14,7 @@ DEMOS =   \
composite-test  \
gradient-test   \
radial-test \
+   conical-test\
alpha-test  \
screen-test \
convolution-test\
@@ -36,6 +37,7 @@ trap_test_SOURCES = trap-test.c $(GTK_UTILS)
 screen_test_SOURCES = screen-test.c $(GTK_UTILS)
 convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
 radial_test_SOURCES = radial-test.c $(GTK_UTILS)
+conical_test_SOURCES = conical-test.c $(GTK_UTILS)
 tri_test_SOURCES = tri-test.c $(GTK_UTILS)
 checkerboard_SOURCES = checkerboard.c $(GTK_UTILS)
 srgb_test_SOURCES = srgb-test.c $(GTK_UTILS)
diff --git a/demos/conical-test.c b/demos/conical-test.c
new file mode 100644
index 000..1e08e42
--- /dev/null
+++ b/demos/conical-test.c
@@ -0,0 +1,134 @@
+#include "../test/utils.h"
+#include "gtk-utils.h"
+
+#define SIZE 128
+#define GRADIENTS_PER_ROW 7
+#define NUM_ROWS ((NUM_GRADIENTS + GRADIENTS_PER_ROW - 1) / GRADIENTS_PER_ROW)
+#define WIDTH (SIZE * GRADIENTS_PER_ROW)
+#define HEIGHT (SIZE * NUM_ROWS)
+#define NUM_GRADIENTS 35
+
+#define double_to_color(x) \
+(((uint32_t) ((x)*65536)) - (((uint32_t) ((x)*65536)) >> 16))
+
+#define PIXMAN_STOP(offset,r,g,b,a)\
+{ pixman_double_to_fixed (offset), \
+   {   \
+   double_to_color (r),\
+   double_to_color (g),\
+   double_to_color (b),\
+   double_to_color (a) \
+   }   \
+}
+
+
+static const pixman_gradient_stop_t stops[] = {
+PIXMAN_STOP (0.25,   1, 0, 0, 0.7),
+PIXMAN_STOP (0.5,1, 1, 0, 0.7),
+PIXMAN_STOP (0.75,   0, 1, 0, 0.7),
+PIXMAN_STOP (1.0,0, 0, 1, 0.7)
+};
+
+#define NUM_STOPS (sizeof (stops) / sizeof (stops[0]))
+
+static pixman_image_t *
+create_conical (int index)
+{
+pixman_point_fixed_t c;
+double angle;
+
+c.x = pixman_double_to_fixed (0);
+c.y = pixman_double_to_fixed (0);
+
+angle = (0.5 / NUM_GRADIENTS + index / (double)NUM_GRADIENTS) * 720 - 180;
+
+return pixman_image_create_conical_gradient (
+   &c, pixman_double_to_fixed (angle), stops, NUM_STOPS);
+}
+
+#define CHECK_SIZE 25
+
+static void
+fill_checkerboard (pixman_image_t *image, int width, int height)
+{
+#define C1 0x
+#define C2 0x
+
+pixman_color_t check1 = { C1, C1, C1, 0x };
+pixman_color_t check2 = { C2, C2, C2, 0x };
+pixman_image_t *c1, *c2;
+int i, j;
+
+c1 = pixman_image_create_solid_fill (&check1);
+c2 = pixman_image_create_solid_fill (&check2);
+
+for (j = 0; j < height; j += CHECK_SIZE)
+{
+   for (i = 0; i < width; i += CHECK_SIZE)
+   {
+   pixman_image_t *src;
+
+   if i / CHECK_SIZE) ^ (j / CHECK_SIZE)) & 1) == 0)
+   src = c1;
+   else
+   src = c2;
+   
+   pixman_image_composite32 (PIXMAN_OP_SRC, src, NULL, image,
+ 0, 0, 0, 0, i, j,
+ CHECK_SIZE, CHECK_SIZE);
+   }
+}
+}
+
+int
+main (int argc, char **argv)
+{
+pixman_transform_t transform;
+pixman_image_t *src_img, *dest_img;
+int i;
+
+enable_divbyzero_exceptions ();
+
+dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+WIDTH, HEIGHT,
+NULL, 0);
+
+fill_checkerboard (dest_img, WIDTH, HEIGHT);
+
+pixman_transform_init_identity (&transform);
+
+pixman_transform_translate (NULL, &transform,
+   pixman_double_to_fixed (0.5),
+   pixman_double_to_fixed (0.5));
+
+pixman_transform_scale (NULL, &transform,
+   pixman_double_to_fixed (SIZE),
+   pixman_double_to_fixe

Re: [Pixman] [cairo] Cairo/pixman behavior with large translations

2012-12-06 Thread Søren Sandmann
Siarhei Siamashka  writes:

> The main culprits are functions pixman_transform_point_3d() and
> pixman_transform_point() here:
> 
> http://cgit.freedesktop.org/pixman/tree/pixman/pixman-matrix.c?id=pixman-0.28.0#n49
> They perform multiplication of a matrix (16.16 fixed point) with a
> vector (16.16 fixed point), to get a vector with 16.16 fixed point
> values. This code can be upgraded to perform multiplication of the same
> 16.16 fixed point matrix, but use something like 31.16 fixed point
> for input vectors and get results in the 48.16 fixed point output
> vectors. The caller then should be able to deal with the 48.16
> results depending on the type of repeat set for the image. One
> example is here:
> 
> http://cgit.freedesktop.org/pixman/tree/pixman/pixman-inlines.h?id=pixman-0.28.0#n417
> In this code, the "src_x" and "src_y" arguments are originally coming
> from pixman_image_composite32() function and are already supposed to be
> larger than 16 bits after the following commit:
> 
> http://cgit.freedesktop.org/pixman/commit/?id=e841c556d59ca0aa6d86eaf6dbf061ae0f4287de
> If they are getting converted to fixed point, we already get something
> like 32.16 fixed point values which are asking for a larger vector
> argument for pixman_transform_point_3d() function (though we might
> want not to allow the use of full 32-bit range for "src_x" and "src_y"
> in order to keep some headroom and safeguard against overflows). In any
> case, immediately after pixman_transform_point_3d() we are
> tweaking v.vector[0] and v.vector[1] according to the repeat type:
> 
> http://cgit.freedesktop.org/pixman/tree/pixman/pixman-inlines.h?id=pixman-0.28.0#n432
> Updating this code ("repeat" and "pad_repeat_get_scanline_bounds"
> functions) to deal with 48.16 fixed point values from the vector can't
> be too hard.

There is really a lot to be said for this 31.16 format. Intermediate
results from matrix and vector multiplications fit in 64 bits, and image
access coordinates up to +/- 1 billion pixels can be supported. Yet it
is still a fixed-point format so there won't be any weird effects where
positions are rounded differently depending on where they are on the
screen.  If 64 bit coordinates become a performance problem, a new flag,
"FAST_PATH_16_16_IS_ENOUGH" or something, could be added so that fast
paths could use 32 bit coordinates. (We used to have something like this
before pixman started to just return without compositing when it detects
overflow).

It's very tempting to switch pixman over to using this format
internally.

The one thing I'm not sure of is whether this bug:

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

"Under a non-affine transform, or, in fact, any transform where the
 'w' component of the (u,v,w) homogeneous source coordinate is not 1,
 the representation of u,v,w as 16.16 fixed point numbers will
 over/under flow on a regular basis even given fairly mundane
 transformations (like a simple keystone correction). I've fixed the
 intel driver to do these computations in floating point; I'm not
 sure we want to try to use fixed point here."

is adequately taken care off by using this format.

It's worth pointing out that even if there are useful non-affine
transformations that still overflow, a homogeneous transformation matrix
doesn't change if multiplied or divided by an arbitrary constant, so if
worse comes to worst, we could drop precision by rounding the
overflowing result down to 47 bits and then dividing all the other
entries by a similar amount, in effect faking a floating point type.

Keith, comments on this would definitely be appreciated. For the RandR
use cases, would 31.16 be good enough?


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


Re: [Pixman] [cairo] Cairo/pixman behavior with large translations

2012-12-06 Thread Søren Sandmann
Søren Sandmann  writes:

> Intermediate results from matrix and vector multiplications fit in 64
> bits, and

That is, as long as the final result doesn't overflow the 31.16 type,
the intermediate values fit in 64 bits.


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


[Pixman] [PATCH 1/2] demos/radial-test: Add zero-radius circles to demonstrate rendering bugs

2012-12-07 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Add two new gradients: one where the start circle is degenerate with a
radius of 0, and one where the end circle is degenerate.

All the new gradients except the one with degenerate start circle and
REPEAT_NONE are rendered with a bright dot in the middle. In most but
not all cases this is incorrect.

Cc: ranm...@gmail.com
---
 demos/radial-test.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/demos/radial-test.c b/demos/radial-test.c
index e64f357..203ad68 100644
--- a/demos/radial-test.c
+++ b/demos/radial-test.c
@@ -1,7 +1,7 @@
 #include "../test/utils.h"
 #include "gtk-utils.h"
 
-#define NUM_GRADIENTS 7
+#define NUM_GRADIENTS 9
 #define NUM_STOPS 3
 #define NUM_REPEAT 4
 #define SIZE 128
@@ -28,6 +28,9 @@
  * centers (0, 0) and (1, 0), but with different radiuses. From left
  * to right:
  *
+ * - Degenerate start circle completely inside the end circle
+ * 0.00 -> 1.75; dr = 1.75 > 0; a = 1 - 1.75^2 < 0
+ *
  * - Small start circle completely inside the end circle
  * 0.25 -> 1.75; dr =  1.5 > 0; a = 1 - 1.50^2 < 0
  *
@@ -49,15 +52,20 @@
  * - Small end circle completely inside the start circle
  * 1.75 -> 0.25; dr = -1.5 > 0; a = 1 - 1.50^2 < 0
  *
+ * - Degenerate end circle completely inside the start circle
+ * 0.00 -> 1.75; dr = 1.75 > 0; a = 1 - 1.75^2 < 0
+ *
  */
 
 const static double radiuses[NUM_GRADIENTS] = {
+0.00,
 0.25,
 0.50,
 0.50,
 1.00,
 1.00,
 1.50,
+1.75,
 1.75
 };
 
-- 
1.7.11.7

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


[Pixman] [PATCH 2/2] radial: When comparing the compute t to mindr, use >= rather than >

2012-12-07 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

It is legitimate for t * dr value to be exactly equal to the minimum
dr. This happens when the sampled point is precisely on the edge of
the c1 circle, or exactly on the center of c1 when its radius is 0.

This fixes the dots in demos/radial-test.c except for two: When the c2
circle has radius 0 and a repeat mode of NONE, the dot remains. When
the repeat mode is NORMAL, the dot is now red where it used to be
white. Before these cases correspond to a t value of 1.0, which we
generally treat as a value that is outside the gradient's defined
interval [0.0,1) and is therefore subject to the repeat
algorithm. Given this, in the repeat==NONE case, a value of 1.0 is
expected to generate a value of { 0, 0, 0, 0 }. In the repeat==NORMAL,
it wraps around and becomes the value at 0.0, which is red in
radial-test.

Cc: ranm...@gmail.com
---
 pixman/pixman-radial-gradient.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 8d56246..6a21796 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -109,7 +109,7 @@ radial_compute_color (doublea,
}
else
{
-   if (t * dr > mindr)
+   if (t * dr >= mindr)
return _pixman_gradient_walker_pixel (walker, t);
}
 
@@ -145,9 +145,9 @@ radial_compute_color (doublea,
}
else
{
-   if (t0 * dr > mindr)
+   if (t0 * dr >= mindr)
return _pixman_gradient_walker_pixel (walker, t0);
-   else if (t1 * dr > mindr)
+   else if (t1 * dr >= mindr)
return _pixman_gradient_walker_pixel (walker, t1);
}
 }
-- 
1.7.11.7

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


[Pixman] [PATCH 1/3] test/utils.[ch]: Add utility function to draw a checkerboard

2012-12-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

This is useful in demo programs to display the alpha channel.
---
 test/utils.c | 54 ++
 test/utils.h |  5 +
 2 files changed, 59 insertions(+)

diff --git a/test/utils.c b/test/utils.c
index 66c8dcb..08eaabb 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -548,6 +548,60 @@ write_png (pixman_image_t *image, const char *filename)
 
 #endif
 
+static void
+color8_to_color16 (uint32_t color8, pixman_color_t *color16)
+{
+color16->alpha = ((color8 & 0xff00) >> 24);
+color16->red =   ((color8 & 0x00ff) >> 16);
+color16->green = ((color8 & 0xff00) >> 8);
+color16->blue =  ((color8 & 0x00ff) >> 0);
+
+color16->alpha |= color16->alpha << 8;
+color16->red   |= color16->red << 8;
+color16->blue  |= color16->blue << 8;
+color16->green |= color16->green << 8;
+}
+
+void
+draw_checkerboard (pixman_image_t *image,
+  int check_size,
+  uint32_t color1, uint32_t color2)
+{
+pixman_color_t check1, check2;
+pixman_image_t *c1, *c2;
+int n_checks_x, n_checks_y;
+int i, j;
+
+color8_to_color16 (color1, &check1);
+color8_to_color16 (color2, &check2);
+
+c1 = pixman_image_create_solid_fill (&check1);
+c2 = pixman_image_create_solid_fill (&check2);
+
+n_checks_x = (
+   pixman_image_get_width (image) + check_size - 1) / check_size;
+n_checks_y = (
+   pixman_image_get_height (image) + check_size - 1) / check_size;
+
+for (j = 0; j < n_checks_y; j++)
+{
+   for (i = 0; i < n_checks_x; i++)
+   {
+   pixman_image_t *src;
+
+   if (((i ^ j) & 1))
+   src = c1;
+   else
+   src = c2;
+
+   pixman_image_composite32 (PIXMAN_OP_SRC, src, NULL, image,
+ 0, 0, 0, 0,
+ i * check_size, j * check_size,
+ check_size, check_size);
+   }
+}
+}
+
 /*
  * 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 78cf0d1..45b457e 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -124,6 +124,11 @@ a8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int 
n_pixels);
 pixman_bool_t
 write_png (pixman_image_t *image, const char *filename);
 
+void
+draw_checkerboard (pixman_image_t *image,
+  int check_size,
+  uint32_t color1, uint32_t color2);
+
 /* 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.7.11.7

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


[Pixman] [PATCH 2/3] demos/conical-test: Use the draw_checkerboard() utility function

2012-12-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

Instead of having its own copy.
---
 demos/conical-test.c | 38 ++
 1 file changed, 2 insertions(+), 36 deletions(-)

diff --git a/demos/conical-test.c b/demos/conical-test.c
index 1e08e42..6b32430 100644
--- a/demos/conical-test.c
+++ b/demos/conical-test.c
@@ -46,40 +46,6 @@ create_conical (int index)
&c, pixman_double_to_fixed (angle), stops, NUM_STOPS);
 }
 
-#define CHECK_SIZE 25
-
-static void
-fill_checkerboard (pixman_image_t *image, int width, int height)
-{
-#define C1 0x
-#define C2 0x
-
-pixman_color_t check1 = { C1, C1, C1, 0x };
-pixman_color_t check2 = { C2, C2, C2, 0x };
-pixman_image_t *c1, *c2;
-int i, j;
-
-c1 = pixman_image_create_solid_fill (&check1);
-c2 = pixman_image_create_solid_fill (&check2);
-
-for (j = 0; j < height; j += CHECK_SIZE)
-{
-   for (i = 0; i < width; i += CHECK_SIZE)
-   {
-   pixman_image_t *src;
-
-   if i / CHECK_SIZE) ^ (j / CHECK_SIZE)) & 1) == 0)
-   src = c1;
-   else
-   src = c2;
-   
-   pixman_image_composite32 (PIXMAN_OP_SRC, src, NULL, image,
- 0, 0, 0, 0, i, j,
- CHECK_SIZE, CHECK_SIZE);
-   }
-}
-}
-
 int
 main (int argc, char **argv)
 {
@@ -92,8 +58,8 @@ main (int argc, char **argv)
 dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
 WIDTH, HEIGHT,
 NULL, 0);
-
-fill_checkerboard (dest_img, WIDTH, HEIGHT);
+ 
+draw_checkerboard (dest_img, 25, 0xffaa, 0xff88);
 
 pixman_transform_init_identity (&transform);
 
-- 
1.7.11.7

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


[Pixman] [PATCH 3/3] demos/radial-test: Add checkerboard to display the alpha channel

2012-12-08 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

---
 demos/radial-test.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/demos/radial-test.c b/demos/radial-test.c
index 203ad68..08a367c 100644
--- a/demos/radial-test.c
+++ b/demos/radial-test.c
@@ -147,6 +147,8 @@ main (int argc, char **argv)
 WIDTH, HEIGHT,
 NULL, 0);
 
+draw_checkerboard (dest_img, 25, 0xffaa, 0xffbb);
+
 pixman_transform_init_identity (&transform);
 
 /*
-- 
1.7.11.7

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


[Pixman] Subject: [ANNOUNCE] pixman release 0.28.2 now available

2012-12-10 Thread Søren Sandmann
A new pixman release 0.28.2 is now available.

This stable release in the 0.28 series contains fixes for 64 bit
Windows, clang, and PowerPC on MacOS and OpenBSD.

Søren


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

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

Hashes:
MD5:  f68916a612921c24e5f94f1eae71d121  pixman-0.28.2.tar.gz
MD5:  f6e3294c4edb7b6bca8459e604286348  pixman-0.28.2.tar.bz2
SHA1: fd81193e3d970a4a44f8c3818fc10cb449fdca8b  pixman-0.28.2.tar.gz
SHA1: 9e9ede6e13061030f9c827219cb87f47e32ecdb4  pixman-0.28.2.tar.bz2

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

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

Log:
Benjamin Gilbert (1):
  Fix thread safety on mingw-w64 and clang

Joshua Root (1):
  Fix undeclared variable use and sysctlbyname error handling on ppc

Stefan Weil (1):
  Always use xmmintrin.h for 64 bit Windows

Søren Sandmann Pedersen (2):
  Post-release version bump to 0.28.1
  Pre-release version bump to 0.28.2
___
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman


[Pixman] [PATCH 1/3] Add testing of trapezoids to stress-test

2012-12-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The entry points add_trapezoids(), rasterize_trapezoid() and
composite_trapezoid() are exercised with random trapezoids.

This uncovers crashes with stress-test seeds 0x17ee and 0x313c.
---
 test/stress-test.c | 160 -
 1 file changed, 135 insertions(+), 25 deletions(-)

diff --git a/test/stress-test.c b/test/stress-test.c
index ee55c21..9d949af 100644
--- a/test/stress-test.c
+++ b/test/stress-test.c
@@ -205,8 +205,29 @@ rand_y (pixman_image_t *image)
return log_rand ();
 }
 
+static pixman_format_code_t
+random_format (pixman_bool_t prefer_alpha)
+{
+pixman_format_code_t format;
+int n = prng_rand_n (ARRAY_LENGTH (image_formats));
+
+if (prefer_alpha && prng_rand_n (4) != 0)
+{
+do
+{
+format = image_formats[n++ % ARRAY_LENGTH (image_formats)];
+} while (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_A);
+}
+else
+{
+format = image_formats[n];
+}
+
+return format;
+}
+
 static pixman_image_t *
-create_random_bits_image (void)
+create_random_bits_image (pixman_bool_t prefer_alpha)
 {
 pixman_format_code_t format;
 pixman_indexed_t *indexed;
@@ -220,7 +241,7 @@ create_random_bits_image (void)
 int n_coefficients = 0;
 
 /* format */
-format = image_formats[prng_rand_n (ARRAY_LENGTH (image_formats))];
+format = random_format (prefer_alpha);
 
 indexed = NULL;
 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
@@ -389,7 +410,7 @@ set_general_properties (pixman_image_t *image, 
pixman_bool_t allow_alpha_map)
pixman_image_t *alpha_map;
int16_t x, y;
 
-   alpha_map = create_random_bits_image ();
+   alpha_map = create_random_bits_image (FALSE);
 
if (alpha_map)
{
@@ -695,7 +716,7 @@ create_random_image (void)
 {
 default:
 case 0:
-   result = create_random_bits_image ();
+   result = create_random_bits_image (FALSE);
break;
 
 case 1:
@@ -721,6 +742,39 @@ create_random_image (void)
 return result;
 }
 
+static void
+random_line (pixman_line_fixed_t *line, int width, int height)
+{
+line->p1.x = prng_rand_n (width) << 16;
+line->p1.y = prng_rand_n (height) << 16;
+line->p2.x = prng_rand_n (width) << 16;
+line->p2.y = prng_rand_n (height) << 16;
+}
+
+static pixman_trapezoid_t *
+create_random_trapezoids (int *n_traps, int height, int width)
+{
+pixman_trapezoid_t *trapezoids;
+int i;
+
+*n_traps = prng_rand_n (16) + 1;
+
+trapezoids = malloc (sizeof (pixman_trapezoid_t) * *n_traps);
+
+for (i = 0; i < *n_traps; ++i)
+{
+pixman_trapezoid_t *t = &(trapezoids[i]);
+
+t->top = prng_rand_n (height) << 16;
+t->bottom = prng_rand_n (height) << 16;
+
+random_line (&t->left, height, width);
+random_line (&t->right, height, width);
+}
+
+return trapezoids;
+}
+
 static const pixman_op_t op_list[] =
 {
 PIXMAN_OP_SRC,
@@ -792,31 +846,87 @@ run_test (uint32_t seed, pixman_bool_t verbose, uint32_t 
mod)
if (mod == 0 || (seed % mod) == 0)
printf ("Seed 0x%08x\n", seed);
 }
-   
-prng_srand (seed);
 
-source = create_random_image ();
-mask   = create_random_image ();
-dest   = create_random_bits_image ();
+source = mask = dest = NULL;
+
+prng_srand (seed);
 
-if (source && mask && dest)
+if (prng_rand_n (8) == 0)
 {
-   set_general_properties (dest, TRUE);
-
-   op = op_list [prng_rand_n (ARRAY_LENGTH (op_list))];
-
-   pixman_image_composite32 (op,
- source, mask, dest,
- rand_x (source), rand_y (source),
- rand_x (mask), rand_y (mask),
- 0, 0, 
- dest->bits.width,
- dest->bits.height);
+int n_traps;
+pixman_trapezoid_t *trapezoids;
+
+dest = create_random_bits_image (TRUE);
+
+if (dest)
+{
+set_general_properties (dest, TRUE);
+
+trapezoids = create_random_trapezoids (
+&n_traps, dest->bits.width, dest->bits.height);
+
+if (trapezoids)
+{
+switch (prng_rand_n (3))
+{
+case 0:
+pixman_rasterize_trapezoid (
+dest, &trapezoids[prng_rand_n (n_traps)],
+rand_x (dest), rand_y (dest));
+break;
+
+case 1:
+source = create_random_image ();
+
+if (source)
+{
+op = op_list [prng_rand_n (ARRAY_LENGTH (op_list))

[Pixman] [PATCH 2/3] pixman_composite_trapezoids: Return early if mask_format is not of TYPE_ALPHA

2012-12-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

stress-test -s 0x17ee crashes because pixman_composite_trapezoids() is
given a mask_format of PIXMAN_c8, which causes it to create a
temporary image with that format but without a palette. This causes
crashes later.

The only mask_format that we actually support are those of TYPE_ALPHA,
so this patch add a return_if_fail() to ensure this.

Similarly, although currently it won't crash if given an invalid
format, alpha-only formats have always been the only thing that made
sense for the pixman_rasterize_edges() functions, so add a
return_if_fail() ensuring that the destination format is of type
PIXMAN_TYPE_ALPHA.
---
 pixman/pixman-edge.c | 1 +
 pixman/pixman-trap.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/pixman/pixman-edge.c b/pixman/pixman-edge.c
index 8d498ab..ad6dfc4 100644
--- a/pixman/pixman-edge.c
+++ b/pixman/pixman-edge.c
@@ -374,6 +374,7 @@ pixman_rasterize_edges (pixman_image_t *image,
 pixman_fixed_t  b)
 {
 return_if_fail (image->type == BITS);
+return_if_fail (PIXMAN_FORMAT_TYPE (image->bits.format) == PIXMAN_TYPE_A);
 
 if (image->bits.read_func || image->bits.write_func)
pixman_rasterize_edges_accessors (image, l, r, t, b);
diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index ab5c8c8..4dad179 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -491,6 +491,8 @@ pixman_composite_trapezoids (pixman_op_top,
 {
 int i;
 
+return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A);
+
 if (n_traps <= 0)
return;
 
-- 
1.7.11.7

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


[Pixman] [PATCH 3/3] pixman_composite_trapezoids(): Check for NULL return from create_bits()

2012-12-13 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

A check is needed that the creation of the temporary image in
pixman_composite_trapezoids() succeeds.

Fixes crash in stress-test -s 0x313c on my system.
---
 pixman/pixman-trap.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index 4dad179..91766fd 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -523,8 +523,9 @@ pixman_composite_trapezoids (pixman_op_top,
if (!get_trap_extents (op, dst, traps, n_traps, &box))
return;

-   tmp = pixman_image_create_bits (
-   mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1);
+   if (!(tmp = pixman_image_create_bits (
+ mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1)))
+   return;

for (i = 0; i < n_traps; ++i)
{
-- 
1.7.11.7

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


Re: [Pixman] Fwd: make error on pixman library

2012-12-14 Thread Søren Sandmann
Andrew Scott  writes:

> /bin/bash: line 5:  5532 Floating point exception${dir}$tst
> FAIL: combiner-test

Thanks for the bug report. Can we get a backtrace for it? That is, after
running combiner-test once, run it again like this:

~/pixman/test% gdb .libs/lt-combiner-test
(gdb) run
...
(gdb) bt


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


Re: [Pixman] Fwd: make error on pixman library

2012-12-15 Thread Søren Sandmann
Søren Sandmann  writes:

>> /bin/bash: line 5:  5532 Floating point exception${dir}$tst
>> FAIL: combiner-test

I managed to reproduce this using the -m32 option to gcc. The problem is
a divide-by-zero in blend_color_dodge():

static force_inline float
blend_color_dodge (float sa, float s, float da, float d)
{
if (d == 0.0f)
return 0.0f;
else if (d * sa >= sa * da - s * da)
return sa * da;
else if (sa - s == 0.0f)
return sa * da;
else
return sa * sa * d / (sa - s);
}

The division is guarded by

if (sa - s == 0.0f)
;
else
 / (sa - s);

which in theory should be correct, but isn't with the combination of x87
and gcc optimizations. The following patch fixes the issue by changing
the comparision for equality with zero into a comparision for the
interval -FLT_MIN, FLT_MIN.


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


[Pixman] [PATCH] float-combiner.c: Change tests for x == 0.0 tests to - FLT_MIN < x < FLT_MIN

2012-12-15 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

pixman-float-combiner.c currently uses checks like these:

if (x == 0.0f)
...
else
... / x;

to prevent division by 0. In theory this is correct: a division-by-zero
exception is only supposed to happen when the floating point numerator is
exactly equal to a positive or negative zero.

However, in practice, the combination of x87 and gcc optimizations
causes issues. The x87 registers are 80 bits wide, which means the
initial test:

if (x == 0.0f)

may be false when x is an 80 bit floating point number, but when x is
rounded to a 32 bit single precision number, it becomes equal to
0.0. In principle, gcc should compensate for this quirk of x87, and
there are some options such as -ffloat-store, -fexcess-precision=standard,
and -std=c99 that will make it do so, but these all have a performance
cost.  It is also possible to set the FPU to a mode that makes it do
all computation with single or double precision, but that would
require pixman to save the existing mode before doing anything with
floating point and restore it afterwards.

Instead, this patch side-steps the issue by replacing exact checks for
equality with zero with a new macro that checkes whether the value is
between -FLT_MIN and FLT_MIN.

There is extensive reading material about this issue linked off the
infamous gcc bug 323:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
---
 pixman/pixman-combine-float.c |   28 +++-
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/pixman/pixman-combine-float.c b/pixman/pixman-combine-float.c
index c3d54f0..c916df8 100644
--- a/pixman/pixman-combine-float.c
+++ b/pixman/pixman-combine-float.c
@@ -42,6 +42,8 @@
 #define force_inline __inline__
 #endif
 
+#define IS_ZERO(f) (-FLT_MIN < (f) && (f) < FLT_MIN)
+
 typedef float (* combine_channel_t) (float sa, float s, float da, float d);
 
 static force_inline void
@@ -201,56 +203,56 @@ get_factor (combine_factor_t factor, float sa, float da)
break;
 
 case SA_OVER_DA:
-   if (da == 0.0f)
+   if (IS_ZERO (da))
f = 1.0f;
else
f = CLAMP (sa / da);
break;
 
 case DA_OVER_SA:
-   if (sa == 0.0f)
+   if (IS_ZERO (sa))
f = 1.0f;
else
f = CLAMP (da / sa);
break;
 
 case INV_SA_OVER_DA:
-   if (da == 0.0f)
+   if (IS_ZERO (da))
f = 1.0f;
else
f = CLAMP ((1.0f - sa) / da);
break;
 
 case INV_DA_OVER_SA:
-   if (sa == 0.0f)
+   if (IS_ZERO (sa))
f = 1.0f;
else
f = CLAMP ((1.0f - da) / sa);
break;
 
 case ONE_MINUS_SA_OVER_DA:
-   if (da == 0.0f)
+   if (IS_ZERO (da))
f = 0.0f;
else
f = CLAMP (1.0f - sa / da);
break;
 
 case ONE_MINUS_DA_OVER_SA:
-   if (sa == 0.0f)
+   if (IS_ZERO (sa))
f = 0.0f;
else
f = CLAMP (1.0f - da / sa);
break;
 
 case ONE_MINUS_INV_DA_OVER_SA:
-   if (sa == 0.0f)
+   if (IS_ZERO (sa))
f = 0.0f;
else
f = CLAMP (1.0f - (1.0f - da) / sa);
break;
 
 case ONE_MINUS_INV_SA_OVER_DA:
-   if (da == 0.0f)
+   if (IS_ZERO (da))
f = 0.0f;
else
f = CLAMP (1.0f - (1.0f - sa) / da);
@@ -403,11 +405,11 @@ blend_lighten (float sa, float s, float da, float d)
 static force_inline float
 blend_color_dodge (float sa, float s, float da, float d)
 {
-if (d == 0.0f)
+if (IS_ZERO (d))
return 0.0f;
 else if (d * sa >= sa * da - s * da)
return sa * da;
-else if (sa - s == 0.0f)
+else if (IS_ZERO (sa - s))
return sa * da;
 else
return sa * sa * d / (sa - s);
@@ -420,7 +422,7 @@ blend_color_burn (float sa, float s, float da, float d)
return sa * da;
 else if (sa * (da - d) >= s * da)
return 0.0f;
-else if (s == 0.0f)
+else if (IS_ZERO (s))
return 0.0f;
 else
return sa * (da - sa * (da - d) / s);
@@ -440,14 +442,14 @@ blend_soft_light (float sa, float s, float da, float d)
 {
 if (2 * s < sa)
 {
-   if (da == 0.0f)
+   if (IS_ZERO (da))
return d * sa;
else
return d * sa - d * (da - d) * (sa - 2 * s) / da;
 }
 else
 {
-   if (da == 0.0f)
+   if (IS_ZERO (da))
{
return 0.0f;
}
-- 
1.7.4

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


Re: [Pixman] [PATCH/RFC 0/4] New option to build pixman as C++ code (--enable-enforced-cplusplus)

2012-12-16 Thread Søren Sandmann
Siarhei Siamashka  writes:

> This is not intended to be immediately pushed to pixman git repository.
> At least not until it proves to have some real practical use. Except
> maybe for the 'xor'->'filler' variable rename patch, which clearly
> should not cause any regressions or inconveniences.

There is a number of things in this series that look like good changes
regardless of moving to C++ or not. Some I noticed:

The SIZE_MAX change was requested here:

http://lists.freedesktop.org/archives/pixman/2012-August/002196.html

and someone recently mailed me privately and pointed out that Solaris 9
doesn't have it either.

The xor->filler change should be harmless as you point out, and 'filler'
probably is a better name than 'xor'.

The uint32->pixman_format_t in pixman-glyph.c looks good.

Regarding the malloc() changes, it might be worthwhile to add some
macros that take a typename as a parameter, along the lines of

   #define pixman_new(type, n)\
  ((type *)pixman_malloc_ab (sizeof (type), n))

so that we get warnings if we try to assign the result to an incorrect
pointer type. Although for a lot of code in pixman, we do actually rely
on the ability to do type aliasing of malloc()ed memory, so maybe the
usefulness of such macros is limited.

> Any comments or ideas? Hopefully not a C vs. C++ flamewar :)

Every once in a while I let myself be convinced me that C++ can be used
as a better C, but whenever I have tried it, it has somehow always ended
up driving me crazy with longer compile times and casts all over the
place. I guess I could see the potential for better debug builds that
you mention in the first commit message, but I'd definitely like to see
some concrete benefits before committing to keep all pixman code
compilable as C++.


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


Re: [Pixman] [PATCH] float-combiner.c: Change tests for x == 0.0 tests to - FLT_MIN < x < FLT_MIN

2012-12-16 Thread Søren Sandmann
Siarhei Siamashka  writes:

> I just wonder how big is the performance cost for adding an extra
> comparison operation. Probably much less than using -ffloat-store,
> -fexcess-precision=standard, and -std=c99 options, but might be
> interesting to confirm.

It's not going to matter all that much in any case since we are talking
about floating point variants of operations that involve
divisions. These are not used that much, and the divisions will tend to
swamp a lot of the difference.

However, I added conjoint_over__2a10 to lowlevel-blt-test and did
some measurements:

As a baseline, current master compiled with -m32 and == 0.0f checks:

conjoint_over__2a10 =  L1:   5.62  L2:   5.67  M:  5.65 (  0.50%) HT:  
5.59  VT:  5.52  R:  5.49  RT:  5.06 (  68Kops/s)

With the FLT_MIN checks:

conjoint_over__2a10 =  L1:   5.68  L2:   5.73  M:  5.72 (  0.51%) HT:  
5.65  VT:  5.53  R:  5.45  RT:  5.02 (  67Kops/s)

The numbers are actually slightly better with the checks, so I suspect
the difference is just noise (although conceivably, the checks may
filter out more divisions than before).

When just pixman-combine-float.c is compiled with -ffloat-store:

conjoint_over__2a10 =  L1:   5.58  L2:   5.60  M:  5.60 (  0.50%) HT:  
5.53  VT:  5.44  R:  5.41  RT:  4.99 (  67Kops/s)

The numbers here are slightly worse than the baseline, but possibly
still just noise.

If all of pixman is compiled with -ffloat-store:

conjoint_over__2a10 =  L1:   4.31  L2:   4.34c  M:  4.31 (  0.38%) HT:  
4.26  VT:  4.21  R:  4.14  RT:  3.92 (  53Kops/s)

the numbers are clearly worse.

Finally, the numbers in x86_64 mode. Current master:

conjoint_over__2a10 =  L1:  19.09  L2:  19.58  M: 19.13 (  1.75%) HT: 
17.47  VT: 17.35  R: 17.32  RT: 13.72 ( 178Kops/s)

With FLT_MIN checks:

conjoint_over__2a10 =  L1:  19.09  L2:  19.59  M: 19.51 (  1.76%) HT: 
17.52  VT: 17.02  R: 17.00  RT: 13.43 ( 175Kops/s)

Ie., no real difference.


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


[Pixman] [PATCH] Make the noop iterator work for solid images

2012-12-17 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The noop iterator is supposedly handling solid images, but currently
it never triggers because a solid image cannot have both an extended
format code of PIXMAN_solid while at the same time having the
FAST_PATH_BITS_IMAGE flag set.

If these two were to be set at the same time, the
fast_composite_tiled_repeat() fast path would trigger for solid images
(because it triggers for PIXMAN_any formats, which includes
PIXMAN_solid), but for solid images we can usually do better than that
fast path.

So this patch changes the noop iterator to no longer require the
FAST_PATH_BITS_IMAGE flag and handle both solid fill images and 1x1
bits images.
---
 pixman/pixman-noop.c |   19 +--
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c
index 850caa1..adaa0c7 100644
--- a/pixman/pixman-noop.c
+++ b/pixman/pixman-noop.c
@@ -77,25 +77,32 @@ noop_src_iter_init (pixman_implementation_t *imp, 
pixman_iter_t *iter)
iter->get_scanline = _pixman_iter_get_scanline_noop;
 }
 else if (image->common.extended_format_code == PIXMAN_solid
&&
-((iter->image_flags & (FAST_PATH_BITS_IMAGE | 
FAST_PATH_NO_ALPHA_MAP)) ==
- (FAST_PATH_BITS_IMAGE | FAST_PATH_NO_ALPHA_MAP)))
+(iter->image_flags & FAST_PATH_NO_ALPHA_MAP))
 {
-   bits_image_t *bits = &image->bits;
-
if (iter->iter_flags & ITER_NARROW)
{
-   uint32_t color = bits->fetch_pixel_32 (bits, 0, 0);
uint32_t *buffer = iter->buffer;
uint32_t *end = buffer + iter->width;
+   uint32_t color;
+
+   if (image->type == SOLID)
+   color = image->solid.color_32;
+   else
+   color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
 
while (buffer < end)
*(buffer++) = color;
}
else
{
-   argb_t color = bits->fetch_pixel_float (bits, 0, 0);
argb_t *buffer = (argb_t *)iter->buffer;
argb_t *end = buffer + iter->width;
+   argb_t color;
+
+   if (image->type == SOLID)
+   color = image->solid.color_float;
+   else
+   color = image->bits.fetch_pixel_float (&image->bits, 0, 0);
 
while (buffer < end)
*(buffer++) = color;
-- 
1.7.4

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


Re: [Pixman] [PATCH] Make the noop iterator work for solid images

2012-12-19 Thread Søren Sandmann
Siarhei Siamashka  writes:

> Isn't this code in noop iterator mostly a duplicate of:
> 
> http://cgit.freedesktop.org/pixman/tree/pixman/pixman-solid-fill.c?id=pixman-0.28.2#n29
> which gets called from general_src_iter_init:
> 
> http://cgit.freedesktop.org/pixman/tree/pixman/pixman-general.c?id=pixman-0.28.2#n40
>
> At least earlier _pixman_solid_fill_iter_init was used when running
> cairo perf traces. But not anymore after your patch is applied.
>
> Sure, I can see a rationale to handle such simple cases earlier and
> not pass them through the whole fallbacks chain (where they could
> potentially and unexpectedly match something less efficient like
> fast_composite_tiled_repeat). But maybe it's a good idea to also
> get rid of _pixman_solid_fill_iter_init in this case (unless I'm
> missing something and it is still in use)?

I guess that makes sense. The one case that was handled by
_pixman_solid_fill_iter_init() is a solid image with an alpha map, but
since alpha maps are ignored for anything but bits images, there is no
reason to not handle this case in noop as well.

This further breaks down the concept introduced with the refactoring in
0.16 that images are self-contained objects that know how to draw
themselves in favor of the concept that implementations are objects that
know how to draw images.


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


[Pixman] [PATCH] Handle solid images in the noop iterator

2012-12-19 Thread Søren Sandmann
From: Søren Sandmann Pedersen 

The noop src iterator already has code to handle solid images, but
that code never actually runs currently because it is not possible for
an image to have both a format code of PIXMAN_solid and a flag of
FAST_PATH_BITS_IMAGE.

If these two were to be set at the same time, the
fast_composite_tiled_repeat() fast path would trigger for solid images
(because it triggers for PIXMAN_any formats, which includes
PIXMAN_solid), but for solid images we can usually do better than that
fast path.

So this patch removes _pixman_solid_fill_iter_init() and instead
handles such images (along with 1x1 bits images without an alpha map)
in pixman-noop.c.
---
 pixman/pixman-general.c|8 
 pixman/pixman-noop.c   |   20 ++--
 pixman/pixman-private.h|3 ---
 pixman/pixman-solid-fill.c |   25 -
 4 files changed, 18 insertions(+), 38 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 0bf91e4..f175d77 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -42,9 +42,7 @@ 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);
-else if (image->type == LINEAR)
+if (image->type == LINEAR)
_pixman_linear_gradient_iter_init (image, iter);
 else if (image->type == RADIAL)
_pixman_radial_gradient_iter_init (image, iter);
@@ -52,7 +50,9 @@ general_src_iter_init (pixman_implementation_t *imp, 
pixman_iter_t *iter)
_pixman_conical_gradient_iter_init (image, iter);
 else if (image->type == BITS)
_pixman_bits_image_src_iter_init (image, iter);
-else
+else if (image->type == SOLID)
+_pixman_log_error (FUNC, "Solid image not handled by noop");
+else 
_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
 
 return TRUE;
diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c
index 850caa1..e39996d 100644
--- a/pixman/pixman-noop.c
+++ b/pixman/pixman-noop.c
@@ -77,25 +77,33 @@ noop_src_iter_init (pixman_implementation_t *imp, 
pixman_iter_t *iter)
iter->get_scanline = _pixman_iter_get_scanline_noop;
 }
 else if (image->common.extended_format_code == PIXMAN_solid
&&
-((iter->image_flags & (FAST_PATH_BITS_IMAGE | 
FAST_PATH_NO_ALPHA_MAP)) ==
- (FAST_PATH_BITS_IMAGE | FAST_PATH_NO_ALPHA_MAP)))
+(iter->image->type == SOLID ||
+ (iter->image_flags & FAST_PATH_NO_ALPHA_MAP)))
 {
-   bits_image_t *bits = &image->bits;
-
if (iter->iter_flags & ITER_NARROW)
{
-   uint32_t color = bits->fetch_pixel_32 (bits, 0, 0);
uint32_t *buffer = iter->buffer;
uint32_t *end = buffer + iter->width;
+   uint32_t color;
+
+   if (image->type == SOLID)
+   color = image->solid.color_32;
+   else
+   color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
 
while (buffer < end)
*(buffer++) = color;
}
else
{
-   argb_t color = bits->fetch_pixel_float (bits, 0, 0);
argb_t *buffer = (argb_t *)iter->buffer;
argb_t *end = buffer + iter->width;
+   argb_t color;
+
+   if (image->type == SOLID)
+   color = image->solid.color_float;
+   else
+   color = image->bits.fetch_pixel_float (&image->bits, 0, 0);
 
while (buffer < end)
*(buffer++) = color;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index ea447aa..dfc4fa6 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -263,9 +263,6 @@ void
 _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter);
 
 void
-_pixman_solid_fill_iter_init (pixman_image_t *image, pixman_iter_t  *iter);
-
-void
 _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t  
*iter);
 
 void
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 60d56d5..5f9fef6 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -26,31 +26,6 @@
 #endif
 #include "pixman-private.h"
 
-void
-_pixman_solid_fill_iter_init (pixman_image_t *image, pixman_iter_t  *iter)
-{
-if (iter->iter_flags & ITER_NARROW)
-{
-   uint32_t *b = (uint32_t *)iter->buffer;
-   uint32_t *e = b + iter->width;
-   uint32_t color = iter->image->solid.color_32;
-
-   while (b < e)
-   *(b++) = color;
-}
-else
-{
-   argb_t *b = (argb_t *)iter->buffer;
-   argb_t *e = b + iter->width;
-   argb_t color = image->solid.color_float;

[Pixman] [PATCH] pixman-filter.c: Cope with NULL returns from malloc()

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

---
 pixman/pixman-filter.c |   25 +++--
 1 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
index c9d2dc7..6fe7c93 100644
--- a/pixman/pixman-filter.c
+++ b/pixman/pixman-filter.c
@@ -231,6 +231,8 @@ create_1d_filter (int *width,
 *width = ceil (size);
 
 p = params = malloc (*width * n_phases * sizeof (pixman_fixed_t));
+if (!params)
+return NULL;
 
 step = 1.0 / n_phases;
 
@@ -309,7 +311,7 @@ pixman_filter_create_separable_convolution (int 
*n_values,
 {
 double sx = fabs (pixman_fixed_to_double (scale_x));
 double sy = fabs (pixman_fixed_to_double (scale_y));
-pixman_fixed_t *horz, *vert, *params;
+pixman_fixed_t *horz = NULL, *vert = NULL, *params = NULL;
 int subsample_x, subsample_y;
 int width, height;
 
@@ -323,15 +325,18 @@ pixman_filter_create_separable_convolution (int   
  *n_values,
 
 params = malloc (*n_values * sizeof (pixman_fixed_t));
 
-params[0] = pixman_int_to_fixed (width);
-params[1] = pixman_int_to_fixed (height);
-params[2] = pixman_int_to_fixed (subsample_bits_x);
-params[3] = pixman_int_to_fixed (subsample_bits_y);
-
-memcpy (params + 4, horz,
-   width * subsample_x * sizeof (pixman_fixed_t));
-memcpy (params + 4 + width * subsample_x, vert,
-   height * subsample_y * sizeof (pixman_fixed_t));
+if (horz && vert && params)
+{
+params[0] = pixman_int_to_fixed (width);
+params[1] = pixman_int_to_fixed (height);
+params[2] = pixman_int_to_fixed (subsample_bits_x);
+params[3] = pixman_int_to_fixed (subsample_bits_y);
+
+memcpy (params + 4, horz,
+width * subsample_x * sizeof (pixman_fixed_t));
+memcpy (params + 4 + width * subsample_x, vert,
+height * subsample_y * sizeof (pixman_fixed_t));
+}
 
 free (horz);
 free (vert);
-- 
1.7.4

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


Re: [Pixman] [PATCH] pixman-filter.c: Cope with NULL returns from malloc()

2012-12-20 Thread Søren Sandmann
Søren Sandmann  writes:

> From: Søren Sandmann Pedersen 

This patch is wrong. If the horz and vert allocations fail, but the
params one doesn't, a pointer to uninitialized memory will be
returned. New patch to follow shortly.


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


[Pixman] [PATCH] pixman-filter.c: Cope with NULL returns from malloc()

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

v2: Don't return a pointer to uninitialized memory when the allocation
of horz and vert fails, but allocation of params doesn't.
---
 pixman/pixman-filter.c |   10 +-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
index c9d2dc7..26b39d5 100644
--- a/pixman/pixman-filter.c
+++ b/pixman/pixman-filter.c
@@ -231,6 +231,8 @@ create_1d_filter (int *width,
 *width = ceil (size);
 
 p = params = malloc (*width * n_phases * sizeof (pixman_fixed_t));
+if (!params)
+return NULL;
 
 step = 1.0 / n_phases;
 
@@ -309,7 +311,7 @@ pixman_filter_create_separable_convolution (int 
*n_values,
 {
 double sx = fabs (pixman_fixed_to_double (scale_x));
 double sy = fabs (pixman_fixed_to_double (scale_y));
-pixman_fixed_t *horz, *vert, *params;
+pixman_fixed_t *horz = NULL, *vert = NULL, *params = NULL;
 int subsample_x, subsample_y;
 int width, height;
 
@@ -319,9 +321,14 @@ pixman_filter_create_separable_convolution (int
 *n_values,
 horz = create_1d_filter (&width, reconstruct_x, sample_x, sx, subsample_x);
 vert = create_1d_filter (&height, reconstruct_y, sample_y, sy, 
subsample_y);
 
+if (!horz || !vert)
+goto out;
+
 *n_values = 4 + width * subsample_x + height * subsample_y;
 
 params = malloc (*n_values * sizeof (pixman_fixed_t));
+if (!params)
+goto out;
 
 params[0] = pixman_int_to_fixed (width);
 params[1] = pixman_int_to_fixed (height);
@@ -333,6 +340,7 @@ pixman_filter_create_separable_convolution (int 
*n_values,
 memcpy (params + 4 + width * subsample_x, vert,
height * subsample_y * sizeof (pixman_fixed_t));
 
+out:
 free (horz);
 free (vert);
 
-- 
1.7.4

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


Re: [Pixman] [PATCH] sse2: Add a fast path for add_n_8888

2013-01-02 Thread Søren Sandmann
Chris Wilson  writes:

> This path is being exercised by inplace compositing of trapezoids, for
> instance as used in the firefox-asteroids cairo-trace.
>
> core2 @ 2.66GHz,
>
> reference memcpy speed = 4898.2MB/s (1224.6MP/s for 32bpp fills)
>
> before: add_n_ = L1:   4.36  L2:   4.27  M:  1.61 (  0.13%)  HT:
> 1.65  VT:  1.63  R:  1.63  RT:  1.59 (  21Kops/s)
>
> after:  add_n_ = L1:2969.09  L2:3926.11  M:603.30 ( 49.27%)  HT:524.69
> VT:401.01  R:407.59  RT:210.34 ( 804Kops/s)

Just two brief comments, and then I'll disappear again (until the 11th
or so):

- It looks like this function will work for abgr destinations as well as
  argb.

- I'm surprised that the new function is _that_ much better. The current
  code should hit an SSE2 combiner and noop iterators for both source
  and destination, so while I'd expect a solid improvement from a
  dedicated fast path, it is hard to believe that it would be 919 times
  faster than the old. If these numbers are real, there has to be
  something wrong with either the benchmark or the current code.


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


Re: [Pixman] [PATCH] bits: Special case src_iter for 1x1R images

2013-01-06 Thread Søren Sandmann
Chris Wilson  writes:

> These are often used inplace of a solid-fill gradient, with the
> expectation that have similar performance and hit the same fast paths.
> One exception is the identification of the 1x1R <-> solid-fill
> equivalence in general_composite_rect(). By adding the special case to
> _pixman_bits_image_src_iter_init, we can recover the lost performance:

This issue is also fixed by the patch here:

http://lists.freedesktop.org/archives/pixman/2012-December/002444.html

which I will push shortly (with an updated commit message that includes
similar performance numbers to those you posted).

Doing it in the noop implementation is better because it avoids the
question of, say, a repeating SSE2 iterator potentially getting picked
before the one in pixman-bits-image.c.


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


<    1   2   3   4   5   6   7   8   9   >