[Pixman] [PATCH] pixman.h: Only define stdint types when PIXMAN_DONT_DEFINE_STDINT is undefined
From: Søren Sandmann Pedersen s...@redhat.com In SPICE, with Microsoft Visual C++, pixman.h is included after another file that defines these types, which causes warnings and errors. This patch allows such code to just define PIXMAN_DONT_DEFINE_STDINT to use its own version of those types. Cc: al...@redhat.com --- pixman/pixman.h |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/pixman/pixman.h b/pixman/pixman.h index 69af0f9..ce1cca0 100644 --- a/pixman/pixman.h +++ b/pixman/pixman.h @@ -84,6 +84,9 @@ PIXMAN_BEGIN_DECLS /* * Standard integers */ + +#if !defined (PIXMAN_DONT_DEFINE_STDINT) + #if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__) || defined (__HP_cc) # include inttypes.h #elif defined (_MSC_VER) @@ -101,6 +104,8 @@ typedef unsigned __int64 uint64_t; # include stdint.h #endif +#endif + /* * Boolean */ -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 0/2] Thread local support on OS X
So apparently OS X does not support __thread which means current pixman does not compile there. See this: http://tinderbox.x.org/builds/2010-03-16-0022/logs/pixman/#build The following patches add some macros that expand to various types of thread local support. On Linux, Unix, and Windows they continue to expand to __thread and __declspec(thread), but on OS X they expand to a set of functions that use pthread_once() and pthread_get/setspecific() for thread local data. I'm not particularly happy with this, but the only alternative seems to be to just disable the fast path cache there. If anyone has better ideas, I'm interested. I have tested that the pthread_get/setspecific() code works on Linux, but I don't have any way to test it on OS X. I'd appreciate if someone can test it there. Of course, comments on the code are welcome too. Thanks, Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Don't use __thread on MinGW.
From: Søren Sandmann Pedersen s...@redhat.com It is apparently broken. See this: http://mingw-users.1079350.n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-thread-specifier-not-working-td3440749.html We'll need to support thread local storage on MinGW32 some other way. Cc: t...@iki.fi --- configure.ac |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index aabe721..c9d0c66 100644 --- a/configure.ac +++ b/configure.ac @@ -524,6 +524,9 @@ support_for__thread=no AC_MSG_CHECKING(for __thread) AC_COMPILE_IFELSE([ +#ifdef __MINGW32__ +#error MinGW has broken __thread support +#endif __thread int x ; int main () { return 0; } ], support_for__thread=yes) -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Add macros for thread local storage on MinGW 32
From: Søren Sandmann Pedersen s...@redhat.com These macros are identical to the ones that Tor Lillqvist posted here: http://lists.freedesktop.org/archives/pixman/2010-April/000160.html with one exception: the variable is allocated with calloc() and not malloc(). Cc: t...@iki.fi --- pixman/pixman-compiler.h | 65 ++ 1 files changed, 65 insertions(+), 0 deletions(-) diff --git a/pixman/pixman-compiler.h b/pixman/pixman-compiler.h index 531c8c9..1a1350d 100644 --- a/pixman/pixman-compiler.h +++ b/pixman/pixman-compiler.h @@ -77,6 +77,71 @@ # define PIXMAN_GET_THREAD_LOCAL(name) \ (name) +#elif defined(__MINGW32__) !defined(__WIN64) + +/* We can't include windows.h as it causes carious clashes with + * identifiers in pixman, sigh. So just declare the functions we need + * here. + */ +extern __stdcall long InterlockedCompareExchange(long volatile *, long, long); +#define InterlockedCompareExchangePointer(d,e,c) \ +(void *)InterlockedCompareExchange((long volatile *)(d),(long)(e),(long)(c)) +extern __stdcall int TlsAlloc (void); +extern __stdcall void *TlsGetValue (unsigned); +extern __stdcall int TlsSetValue (unsigned, void *); +extern __stdcall void *CreateMutexA(void *, int, char *); +extern __stdcall int CloseHandle(void *); +extern __stdcall unsigned WaitForSingleObject (void *, unsigned); +extern __stdcall int ReleaseMutex (void *); + +# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ +static volatile int tls_ ## name ## _initialized = 0; \ +static void *tls_ ## name ## _mutex = NULL; \ +static unsigned tls_ ## name ## _index;\ + \ +static type * \ +tls_ ## name ## _alloc (void) \ +{ \ +type *value = calloc (1, sizeof (type)); \ +if (value) \ +TlsSetValue (tls_ ## name ## _index, value); \ +return value; \ +} \ + \ +static force_inline type * \ +tls_ ## name ## _get (void) \ +{ \ + type *value;\ + if (!tls_ ## name ## _initialized) \ + { \ + if (!tls_ ## name ## _mutex)\ + { \ + void *mutex = CreateMutexA (NULL, 0, NULL); \ + if (InterlockedCompareExchangePointer ( \ + tls_ ## name ## _mutex, mutex, NULL) != NULL) \ + { \ + CloseHandle (mutex);\ + } \ + } \ + WaitForSingleObject (tls_ ## name ## _mutex, 0x); \ + if (!tls_ ## name ## _initialized) \ + { \ + tls_ ## name ## _index = TlsAlloc (); \ + tls_ ## name ## _initialized = 1; \ + } \ + ReleaseMutex (tls_ ## name ## _mutex); \ + } \ + if (tls_ ## name ## _index == 0x) \ + return NULL;\ + value = TlsGetValue (tls_ ## name ## _index); \ + if (!value) \ + value = tls_ ## name ## _alloc (); \ + return value; \ +} + +# define PIXMAN_GET_THREAD_LOCAL(name) \ +tls_ ## name ## _get () + #elif defined(_MSC_VER) # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ -- 1.6.0.6 ___ Pixman mailing list Pixman
[Pixman] [PATCH] In the FAST_NEAREST macro call the function 8888_8888 and not x888_x888
From: Søren Sandmann Pedersen s...@redhat.com The x888 suggests that they have something to do with the x8r8g8b8 formats, but that's not the case; they are assuming a8r8g8b8 formats. (Although in some cases they also work for x8r8g8b8 type formats). --- pixman/pixman-fast-path.c | 36 ++-- 1 files changed, 18 insertions(+), 18 deletions(-) diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index 7b8c9bc..2e9d39a 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1590,12 +1590,12 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ ## OP (pixman_implementat } \ } -FAST_NEAREST(x888_x888_none, , , uint32_t, uint32_t, SRC, NONE); -FAST_NEAREST(x888_x888_normal, , , uint32_t, uint32_t, SRC, NORMAL); -FAST_NEAREST(x888_x888_none, , , uint32_t, uint32_t, OVER, NONE); -FAST_NEAREST(x888_x888_normal, , , uint32_t, uint32_t, OVER, NORMAL); -FAST_NEAREST(x888_565_none, , 0565, uint32_t, uint16_t, SRC, NONE); -FAST_NEAREST(x888_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL); +FAST_NEAREST(__none, , , uint32_t, uint32_t, SRC, NONE); +FAST_NEAREST(__normal, , , uint32_t, uint32_t, SRC, NORMAL); +FAST_NEAREST(__none, , , uint32_t, uint32_t, OVER, NONE); +FAST_NEAREST(__normal, , , uint32_t, uint32_t, OVER, NORMAL); +FAST_NEAREST(_565_none, , 0565, uint32_t, uint16_t, SRC, NONE); +FAST_NEAREST(_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL); FAST_NEAREST(565_565_none, 0565, 0565, uint16_t, uint16_t, SRC, NONE); FAST_NEAREST(565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL); FAST_NEAREST(_565_none, , 0565, uint32_t, uint16_t, OVER, NONE); @@ -1855,23 +1855,23 @@ static const pixman_fast_path_t c_fast_paths[] = PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \ } -SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, x888_x888), -SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, x888_x888), -SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, x888_x888), -SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, x888_x888), +SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, _), +SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, _), +SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, _), +SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, _), -SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, x888_x888), -SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, x888_x888), +SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, _), +SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, _), -SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, x888_565), -SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, x888_565), +SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, _565), +SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, _565), SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, 565_565), -SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, x888_x888), -SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, x888_x888), -SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, x888_x888), -SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, x888_x888), +SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, _), +SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, _), +SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, _), +SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, _), SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, _565), -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] fast-path: Some formatting fixes
From: Søren Sandmann Pedersen s...@redhat.com Add spaces before parentheses; fix indentation in the macro. --- pixman/pixman-fast-path.c | 26 +- 1 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index 2e9d39a..c65dfb1 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1547,8 +1547,8 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ ## OP (pixman_implementat } \ else /* PIXMAN_OP_SRC */ \ { \ - *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); \ - *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s2); \ + *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); \ + *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s2); \ } \ } \ \ @@ -1584,22 +1584,22 @@ fast_composite_scaled_nearest_ ## scale_func_name ## _ ## OP (pixman_implementat } \ else /* PIXMAN_OP_SRC */ \ { \ - *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); \ + *dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); \ } \ } \ } \ } -FAST_NEAREST(__none, , , uint32_t, uint32_t, SRC, NONE); -FAST_NEAREST(__normal, , , uint32_t, uint32_t, SRC, NORMAL); -FAST_NEAREST(__none, , , uint32_t, uint32_t, OVER, NONE); -FAST_NEAREST(__normal, , , uint32_t, uint32_t, OVER, NORMAL); -FAST_NEAREST(_565_none, , 0565, uint32_t, uint16_t, SRC, NONE); -FAST_NEAREST(_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL); -FAST_NEAREST(565_565_none, 0565, 0565, uint16_t, uint16_t, SRC, NONE); -FAST_NEAREST(565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL); -FAST_NEAREST(_565_none, , 0565, uint32_t, uint16_t, OVER, NONE); -FAST_NEAREST(_565_normal, , 0565, uint32_t, uint16_t, OVER, NORMAL); +FAST_NEAREST (__none, , , uint32_t, uint32_t, SRC, NONE); +FAST_NEAREST (__normal, , , uint32_t, uint32_t, SRC, NORMAL); +FAST_NEAREST (__none, , , uint32_t, uint32_t, OVER, NONE); +FAST_NEAREST (__normal, , , uint32_t, uint32_t, OVER, NORMAL); +FAST_NEAREST (_565_none, , 0565, uint32_t, uint16_t, SRC, NONE); +FAST_NEAREST (_565_normal, , 0565, uint32_t, uint16_t, SRC, NORMAL); +FAST_NEAREST (565_565_none, 0565, 0565, uint16_t, uint16_t, SRC, NONE); +FAST_NEAREST (565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL); +FAST_NEAREST (_565_none, , 0565, uint32_t, uint16_t, OVER, NONE); +FAST_NEAREST (_565_normal, , 0565, uint32_t, uint16_t, OVER, NORMAL); static force_inline uint32_t fetch_nearest (pixman_repeat_t src_repeat, -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] bits: Fix potential divide-by-zero in projective code
From: Søren Sandmann Pedersen s...@redhat.com If the homogeneous coordinate is 0, just set the coordinates to 0. --- pixman/pixman-bits-image.c | 16 1 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 95710b4..36ea0af 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -695,12 +695,20 @@ bits_image_fetch_transformed (pixman_image_t * image, { for (i = 0; i width; ++i) { - pixman_fixed_t x0, y0; - if (!mask || mask[i]) { - x0 = ((pixman_fixed_48_16_t)x 16) / w; - y0 = ((pixman_fixed_48_16_t)y 16) / w; + pixman_fixed_t x0, y0; + + if (w != 0) + { + x0 = ((pixman_fixed_48_16_t)x 16) / w; + y0 = ((pixman_fixed_48_16_t)y 16) / w; + } + else + { + x0 = 0; + y0 = 0; + } buffer[i] = bits_image_fetch_pixel_filtered (image-bits, x0, y0); -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] If we bail out of do_composite, make sure to undo any workarounds.
From: Søren Sandmann Pedersen s...@redhat.com The workaround for an old X bug has to be undone if we bail from do_composite, so we can't just return. --- pixman/pixman.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pixman/pixman.c b/pixman/pixman.c index 80a766a..2d06ce2 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -742,7 +742,7 @@ do_composite (pixman_op_t op, region, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height)) { - return; + goto out; } extents = pixman_region32_extents (region); @@ -759,7 +759,7 @@ do_composite (pixman_op_t op, */ op = optimize_operator (op, src_flags, mask_flags, dest_flags); if (op == PIXMAN_OP_DST) - return; + goto out; lookup_composite_function (op, src_format, src_flags, @@ -776,6 +776,7 @@ do_composite (pixman_op_t op, (mask_flags FAST_PATH_SIMPLE_REPEAT), region, func); +out: if (need_workaround) { unapply_workaround (src, src_bits, src_dx, src_dy); -- 1.7.1.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/7] Eliminate get_pixel_32() and get_pixel_64() from bits_image.
From: Søren Sandmann Pedersen s...@redhat.com These functions can simply be passed as arguments to the various pixel fetchers. We don't need to store them. Since they are known at compile time and the pixel fetchers are force_inline, this is not a performance issue. Also temporarily make all pixel access go through the alpha path. --- pixman/pixman-bits-image.c | 78 +-- pixman/pixman-private.h|4 -- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 81722c2..0372217 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -96,38 +96,47 @@ _pixman_image_store_scanline_64 (bits_image_t * image, /* Fetch functions */ static uint32_t -bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y) +fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) { uint32_t pixel; -uint32_t pixel_a; + +if (check_bounds + (x 0 || x = image-width || y 0 || y = image-height)) +{ + return 0; +} pixel = image-fetch_pixel_raw_32 (image, x, y); -assert (image-common.alpha_map); +if (image-common.alpha_map) +{ + uint32_t pixel_a; -x -= image-common.alpha_origin_x; -y -= image-common.alpha_origin_y; + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; -if (x 0 || x = image-common.alpha_map-width || - y 0 || y = image-common.alpha_map-height) -{ - pixel_a = 0; -} -else -{ - pixel_a = image-common.alpha_map-fetch_pixel_raw_32 ( - image-common.alpha_map, x, y); - pixel_a = ALPHA_8 (pixel_a); -} + if (x 0 || x = image-common.alpha_map-width || + y 0 || y = image-common.alpha_map-height) + { + pixel_a = 0; + } + else + { + pixel_a = image-common.alpha_map-fetch_pixel_raw_32 ( + image-common.alpha_map, x, y); -pixel = 0x00ff; -pixel |= (pixel_a 24); + pixel_a = ALPHA_8 (pixel_a); + } + + pixel = 0x00ff; + pixel |= (pixel_a 24); +} return pixel; } static force_inline uint32_t -get_pixel (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) +fetch_pixel_no_alpha (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) { if (check_bounds (x 0 || x = image-width || y 0 || y = image-height)) @@ -135,9 +144,12 @@ get_pixel (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) return 0; } -return image-fetch_pixel_32 (image, x, y); +return image-fetch_pixel_raw_32 (image, x, y); } +typedef uint32_t (* get_pixel_t) (bits_image_t *image, + int x, int y, pixman_bool_t check_bounds); + static force_inline void repeat (pixman_repeat_t repeat, int size, int *coord) { @@ -169,7 +181,8 @@ repeat (pixman_repeat_t repeat, int size, int *coord) static force_inline uint32_t bits_image_fetch_pixel_nearest (bits_image_t *image, pixman_fixed_t x, - pixman_fixed_t y) + pixman_fixed_t y, + get_pixel_t get_pixel) { int x0 = pixman_fixed_to_int (x - pixman_fixed_e); int y0 = pixman_fixed_to_int (y - pixman_fixed_e); @@ -281,7 +294,8 @@ bilinear_interpolation (uint32_t tl, uint32_t tr, static force_inline uint32_t bits_image_fetch_pixel_bilinear (bits_image_t *image, pixman_fixed_t x, -pixman_fixed_t y) +pixman_fixed_t y, +get_pixel_t get_pixel) { pixman_repeat_t repeat_mode = image-common.repeat; int width = image-width; @@ -538,7 +552,8 @@ bits_image_fetch_bilinear_no_repeat_ (pixman_image_t * ima, static force_inline uint32_t bits_image_fetch_pixel_convolution (bits_image_t *image, pixman_fixed_t x, - pixman_fixed_t y) + pixman_fixed_t y, + get_pixel_t get_pixel) { pixman_fixed_t *params = image-common.filter_params; int x_off = (params[0] - pixman_fixed_1) 1; @@ -611,23 +626,24 @@ bits_image_fetch_pixel_convolution (bits_image_t *image, static force_inline uint32_t bits_image_fetch_pixel_filtered (bits_image_t *image, pixman_fixed_t x, -pixman_fixed_t y) +pixman_fixed_t y, +get_pixel_tget_pixel) { switch (image-common.filter) { case PIXMAN_FILTER_NEAREST: case PIXMAN_FILTER_FAST: - return bits_image_fetch_pixel_nearest (image, x, y); + return
[Pixman] [PATCH 4/7] Eliminate the store_scanline_{32, 64} function pointers.
From: Søren Sandmann Pedersen s...@redhat.com Now that we can't recurse on alpha maps, they are not needed anymore. --- pixman/pixman-bits-image.c | 54 +--- pixman/pixman-private.h|4 --- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 09b69df..f8ddcbc 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -36,13 +36,12 @@ #include pixman-combine32.h /* Store functions */ - -static void -bits_image_store_scanline_32 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) +void +_pixman_image_store_scanline_32 (bits_image_t * image, + int x, + int y, + int width, + const uint32_t *buffer) { image-store_scanline_raw_32 (image, x, y, width, buffer); @@ -51,16 +50,17 @@ bits_image_store_scanline_32 (bits_image_t * image, x -= image-common.alpha_origin_x; y -= image-common.alpha_origin_y; - image-common.alpha_map-store_scanline_raw_32 (image-common.alpha_map, x, y, width, buffer); + image-common.alpha_map-store_scanline_raw_32 ( + image-common.alpha_map, x, y, width, buffer); } } -static void -bits_image_store_scanline_64 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) +void +_pixman_image_store_scanline_64 (bits_image_t * image, + int x, + int y, + int width, + const uint32_t *buffer) { image-store_scanline_raw_64 (image, x, y, width, buffer); @@ -69,30 +69,11 @@ bits_image_store_scanline_64 (bits_image_t * image, x -= image-common.alpha_origin_x; y -= image-common.alpha_origin_y; - image-common.alpha_map-store_scanline_raw_64 (image-common.alpha_map, x, y, width, buffer); + image-common.alpha_map-store_scanline_raw_64 ( + image-common.alpha_map, x, y, width, buffer); } } -void -_pixman_image_store_scanline_32 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ -image-store_scanline_32 (image, x, y, width, buffer); -} - -void -_pixman_image_store_scanline_64 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ -image-store_scanline_64 (image, x, y, width, buffer); -} - /* Fetch functions */ static force_inline uint32_t @@ -983,9 +964,6 @@ bits_image_property_changed (pixman_image_t *image) image-common.get_scanline_64 = _pixman_image_get_scanline_generic_64; image-common.get_scanline_32 = bits_image_fetch_general; } - -bits-store_scanline_64 = bits_image_store_scanline_64; -bits-store_scanline_32 = bits_image_store_scanline_32; } static uint32_t * diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 06f6d11..15a5bc2 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -187,10 +187,6 @@ struct bits_image store_scanline_t store_scanline_raw_32; store_scanline_t store_scanline_raw_64; -/* Store a scanline, taking alpha maps into account */ -store_scanline_t store_scanline_32; -store_scanline_t store_scanline_64; - /* Used for indirect access to the bits */ pixman_read_memory_func_t read_func; pixman_write_memory_func_t write_func; -- 1.7.1.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 5/7] Remove _raw_ from all the accessors.
From: Søren Sandmann Pedersen s...@redhat.com There are no non-raw accessors anymore. --- pixman/pixman-access.c | 40 pixman/pixman-bits-image.c | 28 ++-- pixman/pixman-private.h| 19 +++ 3 files changed, 41 insertions(+), 46 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 80fa9e8..a786947 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -2667,7 +2667,7 @@ store_scanline_generic_64 (bits_image_t * image, */ pixman_contract (argb8_pixels, (uint64_t *)values, width); -image-store_scanline_raw_32 (image, x, y, width, argb8_pixels); +image-store_scanline_32 (image, x, y, width, argb8_pixels); free (argb8_pixels); } @@ -2688,7 +2688,7 @@ fetch_scanline_generic_64 (pixman_image_t *image, /* Fetch the pixels into the first half of buffer and then expand them in * place. */ -image-bits.fetch_scanline_raw_32 (image, x, y, width, buffer, NULL); +image-bits.fetch_scanline_32 (image, x, y, width, buffer, NULL); format = image-bits.format; if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR || @@ -2711,7 +2711,7 @@ fetch_pixel_generic_64 (bits_image_t *image, int offset, int line) { -uint32_t pixel32 = image-fetch_pixel_raw_32 (image, offset, line); +uint32_t pixel32 = image-fetch_pixel_32 (image, offset, line); uint64_t result; pixman_format_code_t format; @@ -2743,7 +2743,7 @@ fetch_pixel_generic_lossy_32 (bits_image_t *image, int offset, int line) { -uint64_t pixel64 = image-fetch_pixel_raw_64 (image, offset, line); +uint64_t pixel64 = image-fetch_pixel_64 (image, offset, line); uint32_t result; pixman_contract (result, pixel64, 1); @@ -2754,12 +2754,12 @@ fetch_pixel_generic_lossy_32 (bits_image_t *image, typedef struct { pixman_format_code_t format; -fetch_scanline_t fetch_scanline_raw_32; -fetch_scanline_t fetch_scanline_raw_64; -fetch_pixel_32_t fetch_pixel_raw_32; -fetch_pixel_64_t fetch_pixel_raw_64; -store_scanline_t store_scanline_raw_32; -store_scanline_t store_scanline_raw_64; +fetch_scanline_t fetch_scanline_32; +fetch_scanline_t fetch_scanline_64; +fetch_pixel_32_t fetch_pixel_32; +fetch_pixel_64_t fetch_pixel_64; +store_scanline_t store_scanline_32; +store_scanline_t store_scanline_64; } format_info_t; #define FORMAT_INFO(format)\ @@ -2885,12 +2885,12 @@ setup_accessors (bits_image_t *image) { if (info-format == image-format) { - image-fetch_scanline_raw_32 = info-fetch_scanline_raw_32; - image-fetch_scanline_raw_64 = info-fetch_scanline_raw_64; - image-fetch_pixel_raw_32 = info-fetch_pixel_raw_32; - image-fetch_pixel_raw_64 = info-fetch_pixel_raw_64; - image-store_scanline_raw_32 = info-store_scanline_raw_32; - image-store_scanline_raw_64 = info-store_scanline_raw_64; + image-fetch_scanline_32 = info-fetch_scanline_32; + image-fetch_scanline_64 = info-fetch_scanline_64; + image-fetch_pixel_32 = info-fetch_pixel_32; + image-fetch_pixel_64 = info-fetch_pixel_64; + image-store_scanline_32 = info-store_scanline_32; + image-store_scanline_64 = info-store_scanline_64; return; } @@ -2901,13 +2901,13 @@ setup_accessors (bits_image_t *image) #ifndef PIXMAN_FB_ACCESSORS void -_pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image); +_pixman_bits_image_setup_accessors_accessors (bits_image_t *image); void -_pixman_bits_image_setup_raw_accessors (bits_image_t *image) +_pixman_bits_image_setup_accessors (bits_image_t *image) { if (image-read_func || image-write_func) - _pixman_bits_image_setup_raw_accessors_accessors (image); + _pixman_bits_image_setup_accessors_accessors (image); else setup_accessors (image); } @@ -2915,7 +2915,7 @@ _pixman_bits_image_setup_raw_accessors (bits_image_t *image) #else void -_pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image) +_pixman_bits_image_setup_accessors_accessors (bits_image_t *image) { setup_accessors (image); } diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index f8ddcbc..d27256d 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -43,14 +43,14 @@ _pixman_image_store_scanline_32 (bits_image_t * image, int width, const uint32_t *buffer) { -image
[Pixman] [PATCH] Add support for AltiVec detection for OpenBSD/PowerPC.
From: Brad Smith b...@comstyle.com Bug 29331. --- pixman/pixman-cpu.c | 25 - 1 files changed, 24 insertions(+), 1 deletions(-) diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c index e96b140..1b31885 100644 --- a/pixman/pixman-cpu.c +++ b/pixman/pixman-cpu.c @@ -61,6 +61,29 @@ pixman_have_vmx (void) return have_vmx; } +#elif defined (__OpenBSD__) +#include sys/param.h +#include sys/sysctl.h +#include machine/cpu.h + +static pixman_bool_t +pixman_have_vmx (void) +{ +if (!initialized) +{ + int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC }; + size_t length = sizeof(have_vmx); + int error = + sysctl (mib, 2, have_vmx, length, NULL, 0); + + if (error) + have_vmx = FALSE; + + initialized = TRUE; +} +return have_vmx; +} + #elif defined (__linux__) #include sys/types.h #include sys/stat.h @@ -123,7 +146,7 @@ pixman_have_vmx (void) return have_vmx; } -#else /* !__APPLE__ !__linux__ */ +#else /* !__APPLE__ !__OpenBSD__ !__linux__ */ #include signal.h #include setjmp.h -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] pixman_image_set_alpha_map(): Disallow alpha map cycles
From: Søren Sandmann Pedersen s...@redhat.com If someone tries to set an alpha map that itself has an alpha map, simply return. Also, if someone tries to add an alpha map to an image that is being _used_ as an alpha map, simply return. This ensures that an alpha map can never have an alpha map. --- pixman/pixman-image.c | 30 +++--- pixman/pixman-private.h |1 + 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 269c3c1..0b8bb3c 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -101,6 +101,7 @@ _pixman_image_allocate (void) pixman_region32_init (common-clip_region); + common-alpha_count = 0; common-have_clip_region = FALSE; common-clip_sources = FALSE; common-transform = NULL; @@ -195,9 +196,6 @@ pixman_image_unref (pixman_image_t *image) if (common-filter_params) free (common-filter_params); - if (common-alpha_map) - pixman_image_unref ((pixman_image_t *)common-alpha_map); - if (image-type == LINEAR || image-type == RADIAL || image-type == CONICAL) @@ -668,15 +666,41 @@ pixman_image_set_alpha_map (pixman_image_t *image, return_if_fail (!alpha_map || alpha_map-type == BITS); +if (alpha_map common-alpha_count 0) +{ + /* If this image is being used as an alpha map itself, +* then you can't give it an alpha map of its own. +*/ + return; +} + +if (alpha_map alpha_map-common.alpha_map) +{ + /* If the image has an alpha map of its own, +* then it can't be used as an alpha map itself +*/ + return; +} + if (common-alpha_map != (bits_image_t *)alpha_map) { if (common-alpha_map) + { + common-alpha_map-common.alpha_count--; + pixman_image_unref ((pixman_image_t *)common-alpha_map); + } if (alpha_map) + { common-alpha_map = (bits_image_t *)pixman_image_ref (alpha_map); + + common-alpha_map-common.alpha_count++; + } else + { common-alpha_map = NULL; + } } common-alpha_origin_x = x; diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 0629c42..c4e6bb8 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -80,6 +80,7 @@ struct image_common image_type_ttype; int32_t ref_count; pixman_region32_t clip_region; +int32_talpha_count;/* How many times this image is being used as an alpha map */ pixman_bool_t have_clip_region; /* FALSE if there is no clip */ pixman_bool_t client_clip;/* Whether the source clip was set by a client */ -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Merge pixman_image_composite32() and do_composite().
From: Søren Sandmann Pedersen s...@redhat.com There is not much point having a separate function that just validates the images. Also add a boolean return to lookup_composite_function() so that we can return if no composite function is found. --- pixman/pixman.c | 131 +++--- 1 files changed, 56 insertions(+), 75 deletions(-) diff --git a/pixman/pixman.c b/pixman/pixman.c index ddd4935..402c72c 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -501,7 +501,7 @@ typedef struct PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache); -static force_inline void +static force_inline pixman_bool_t lookup_composite_function (pixman_op_t op, pixman_format_code_t src_format, uint32_t src_flags, @@ -577,7 +577,7 @@ lookup_composite_function (pixman_op_t op, ++info; } } -return; +return FALSE; update_cache: if (i) @@ -595,6 +595,8 @@ update_cache: cache-cache[0].fast_path.dest_flags = dest_flags; cache-cache[0].fast_path.func = *out_func; } + +return TRUE; } static pixman_bool_t @@ -803,19 +805,38 @@ analyze_extent (pixman_image_t *image, int x, int y, return TRUE; } -static void -do_composite (pixman_op_t op, - pixman_image_t *src, - pixman_image_t *mask, - pixman_image_t *dest, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dest_x, - int dest_y, - int width, - int height) +/* + * Work around GCC bug causing crashes in Mozilla with SSE2 + * + * When using -msse, gcc generates movdqa instructions assuming that + * the stack is 16 byte aligned. Unfortunately some applications, such + * as Mozilla and Mono, end up aligning the stack to 4 bytes, which + * causes the movdqa instructions to fail. + * + * The __force_align_arg_pointer__ makes gcc generate a prologue that + * realigns the stack pointer to 16 bytes. + * + * On x86-64 this is not necessary because the standard ABI already + * calls for a 16 byte aligned stack. + * + * See https://bugs.freedesktop.org/show_bug.cgi?id=15693 + */ +#if defined (USE_SSE2) defined(__GNUC__) !defined(__x86_64__) !defined(__amd64__) +__attribute__((__force_align_arg_pointer__)) +#endif +PIXMAN_EXPORT void +pixman_image_composite32 (pixman_op_t op, + pixman_image_t * src, + pixman_image_t * mask, + pixman_image_t * dest, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) { pixman_format_code_t src_format, mask_format, dest_format; uint32_t src_flags, mask_flags, dest_flags; @@ -831,6 +852,11 @@ do_composite (pixman_op_t op, pixman_implementation_t *imp; pixman_composite_func_t func; +_pixman_image_validate (src); +if (mask) + _pixman_image_validate (mask); +_pixman_image_validate (dest); + src_format = src-common.extended_format_code; src_flags = src-common.flags; @@ -907,20 +933,21 @@ do_composite (pixman_op_top, if (op == PIXMAN_OP_DST) goto out; -lookup_composite_function (op, - src_format, src_flags, - mask_format, mask_flags, - dest_format, dest_flags, - imp, func); - -walk_region_internal (imp, op, - src, mask, dest, - src_x, src_y, mask_x, mask_y, - dest_x, dest_y, - width, height, - (src_flags FAST_PATH_SIMPLE_REPEAT), - (mask_flags FAST_PATH_SIMPLE_REPEAT), - region, func); +if (lookup_composite_function (op, + src_format, src_flags, + mask_format, mask_flags, + dest_format, dest_flags, + imp, func)) +{ + walk_region_internal (imp, op, + src, mask, dest, + src_x, src_y, mask_x, mask_y, + dest_x, dest_y, + width
[Pixman] [PATCH] Store a2b2g2r2 pixel through the WRITE macro
From: Søren Sandmann Pedersen s...@redhat.com Otherwise, accessor functions won't work. --- pixman/pixman-access.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 56de711..f1ce0ba 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -2425,11 +2425,11 @@ store_scanline_a2b2g2r2 (bits_image_t * image, { SPLIT_A (values[i]); - *(pixel++) = - ((a ) 0xc0) | - ((b 2) 0x30) | - ((g 4) 0x0c) | - ((r 6) ); + WRITE (image, pixel++, + ((a ) 0xc0) | + ((b 2) 0x30) | + ((g 4) 0x0c) | + ((r 6) )); } } -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] When pixman_compute_composite_region32() return FALSE, don't fini the region.
From: Søren Sandmann Pedersen s...@redhat.com The rule is that the region passed in must be initialized and that the region returned will still be valid. Ie., the lifecycle is the responsibility of the caller, regardless of what the function returns. Previously, composite_region32() would finalize the region and then return FALSE, and then the caller would finalize the region again, leading to memory corruption in some cases. --- pixman/pixman.c | 14 +- 1 files changed, 1 insertions(+), 13 deletions(-) diff --git a/pixman/pixman.c b/pixman/pixman.c index 402c72c..62b58b8 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -302,17 +302,13 @@ pixman_compute_composite_region32 (pixman_region32_t * region, if (region-extents.x1 = region-extents.x2 || region-extents.y1 = region-extents.y2) { - pixman_region32_init (region); return FALSE; } if (dst_image-common.have_clip_region) { if (!clip_general_image (region, dst_image-common.clip_region, 0, 0)) - { - pixman_region32_fini (region); return FALSE; - } } if (dst_image-common.alpha_map dst_image-common.alpha_map-common.have_clip_region) @@ -321,7 +317,6 @@ pixman_compute_composite_region32 (pixman_region32_t * region, -dst_image-common.alpha_origin_x, -dst_image-common.alpha_origin_y)) { - pixman_region32_fini (region); return FALSE; } } @@ -330,10 +325,7 @@ pixman_compute_composite_region32 (pixman_region32_t * region, if (src_image-common.have_clip_region) { if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y)) - { - pixman_region32_fini (region); return FALSE; - } } if (src_image-common.alpha_map src_image-common.alpha_map-common.have_clip_region) { @@ -341,7 +333,6 @@ pixman_compute_composite_region32 (pixman_region32_t * region, dest_x - (src_x - src_image-common.alpha_origin_x), dest_y - (src_y - src_image-common.alpha_origin_y))) { - pixman_region32_fini (region); return FALSE; } } @@ -349,17 +340,14 @@ pixman_compute_composite_region32 (pixman_region32_t * region, if (mask_image mask_image-common.have_clip_region) { if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y)) - { - pixman_region32_fini (region); return FALSE; - } + if (mask_image-common.alpha_map mask_image-common.alpha_map-common.have_clip_region) { if (!clip_source_image (region, (pixman_image_t *)mask_image-common.alpha_map, dest_x - (mask_x - mask_image-common.alpha_origin_x), dest_y - (mask_y - mask_image-common.alpha_origin_y))) { - pixman_region32_fini (region); return FALSE; } } -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Silence some warnings about uninitialized variables
From: Søren Sandmann Pedersen s...@redhat.com Neither were real problems, but GCC were complaining about them. --- pixman/pixman.c |3 +++ test/composite.c |1 + 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/pixman/pixman.c b/pixman/pixman.c index 62b58b8..47ffdd6 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -613,6 +613,9 @@ compute_sample_extents (pixman_transform_t *transform, { int i; + /* Silence GCC */ + tx1 = ty1 = tx2 = ty2 = 0; + for (i = 0; i 4; ++i) { pixman_fixed_48_16_t tx, ty; diff --git a/test/composite.c b/test/composite.c index 0624cd3..b530a20 100644 --- a/test/composite.c +++ b/test/composite.c @@ -882,6 +882,7 @@ main (void) mask.size? TRUE : FALSE); break; default: + ok = FALSE; /* Silence GCC */ break; } group_ok = group_ok ok; -- 1.7.1.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Do opacity computation with shifts instead of comparing with 0
From: Søren Sandmann Pedersen s...@redhat.com Also add a COMPILE_TIME_ASSERT() macro and use it to assert that the shift is correct. --- pixman/pixman-private.h |3 +++ pixman/pixman.c | 14 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 3557fb2..36b9d91 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -744,6 +744,9 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst, #undef DEBUG +#define COMPILE_TIME_ASSERT(x) \ +do { typedef int compile_time_assertion [(x)?1:-1]; } while (0) + /* Turn on debugging depending on what type of release this is */ #if (((PIXMAN_VERSION_MICRO % 2) == 0) ((PIXMAN_VERSION_MINOR % 2) == 1)) diff --git a/pixman/pixman.c b/pixman/pixman.c index 47ffdd6..cdf4b75 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -139,14 +139,18 @@ optimize_operator (pixman_op_t op, uint32_tdst_flags) { pixman_bool_t is_source_opaque, is_dest_opaque; -int opaqueness; -is_source_opaque = ((src_flags mask_flags) FAST_PATH_IS_OPAQUE) != 0; -is_dest_opaque = (dst_flags FAST_PATH_IS_OPAQUE) != 0; +#define OPAQUE_SHIFT 13 + +COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 OPAQUE_SHIFT)); + +is_dest_opaque = (dst_flags FAST_PATH_IS_OPAQUE); +is_source_opaque = ((src_flags mask_flags) FAST_PATH_IS_OPAQUE); -opaqueness = ((is_dest_opaque 1) | is_source_opaque); +is_dest_opaque = OPAQUE_SHIFT - 1; +is_source_opaque = OPAQUE_SHIFT; -return operator_table[op].opaque_info[opaqueness]; +return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque]; } static void -- 1.7.1.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/5] Update and extend the alphamap test
From: Søren Sandmann Pedersen s...@redhat.com - Test many more combinations of formats - Test destination alpha maps - Test various different alpha origins Also add a transformation to the destination, but comment it out because it is actually broken at the moment (and pretty difficult to fix). --- test/Makefile.am |2 +- test/alphamap.c | 243 -- 2 files changed, 218 insertions(+), 27 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index 3d98e17..f3b2b58 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -13,9 +13,9 @@ TESTPROGRAMS =\ window-test \ gradient-crash-test \ trap-crasher\ - alphamap\ alpha-loop \ scaling-crash-test \ + alphamap\ blitters-test \ scaling-test\ composite diff --git a/test/alphamap.c b/test/alphamap.c index e6a25ef..09de387 100644 --- a/test/alphamap.c +++ b/test/alphamap.c @@ -2,47 +2,238 @@ #include stdlib.h #include utils.h -#define WIDTH 400 -#define HEIGHT 200 +#define WIDTH 100 +#define HEIGHT 100 -int -main (int argc, char **argv) +static const pixman_format_code_t formats[] = +{ +PIXMAN_a8r8g8b8, +PIXMAN_a2r10g10b10, +PIXMAN_a4r4g4b4, +PIXMAN_a8 +}; + +static const pixman_format_code_t alpha_formats[] = +{ +PIXMAN_null, +PIXMAN_a8, +PIXMAN_a2r10g10b10, +PIXMAN_a4r4g4b4 +}; + +static const int origins[] = { -uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT); -uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); -uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); -int i; +0, 10, -100 +}; -pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH); -pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); +static const char * +format_name (pixman_format_code_t format) +{ +if (format == PIXMAN_a8) + return a8; +else if (format == PIXMAN_a2r10g10b10) + return a2r10g10b10; +else if (format == PIXMAN_a8r8g8b8) + return a8r8g8b8; +else if (format == PIXMAN_a4r4g4b4) + return a4r4g4b4; +else if (format == PIXMAN_null) + return none; +else + assert (0); -for (i = 0; i 2; ++i) +return unknown - bug in alphamap.c; +} + +static pixman_image_t * +make_image (pixman_format_code_t format) +{ +uint32_t *bits; +uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8; + +bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); + +return pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp); +} + +static pixman_image_t * +create_image (pixman_format_code_t format, pixman_format_code_t alpha_format, + int alpha_origin_x, int alpha_origin_y) +{ +pixman_image_t *image = make_image (format); + +if (alpha_format != PIXMAN_null) { - pixman_format_code_t sformat = (i == 0)? PIXMAN_a8r8g8b8 : PIXMAN_a2r10g10b10; - pixman_image_t *s = pixman_image_create_bits (sformat, WIDTH, HEIGHT, src, WIDTH * 4); - int j, k; + pixman_image_t *alpha = make_image (alpha_format); - pixman_image_set_alpha_map (s, a, 0, 0); + pixman_image_set_alpha_map (image, alpha, + alpha_origin_x, alpha_origin_y); +} - pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); +return image; +} - for (j = 0; j HEIGHT; ++j) +static uint8_t +get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) +{ +uint8_t *bits; +uint8_t r; + +if (image-common.alpha_map) +{ + if (x - orig_x = 0 x - orig_x WIDTH + y - orig_y = 0 y - orig_y HEIGHT) + { + image = (pixman_image_t *)image-common.alpha_map; + + x -= orig_x; + y -= orig_y; + } + else { - for (k = 0; k WIDTH; ++k) + return 0; + } +} + +bits = (uint8_t *)image-bits.bits; + +if (image-bits.format == PIXMAN_a8) +{ + r = bits[y * WIDTH + x]; +} +else if (image-bits.format == PIXMAN_a2r10g10b10) +{ + r = ((uint32_t *)bits)[y * WIDTH + x] 30; + r |= r 2; + r |= r 4; +} +else if (image-bits.format == PIXMAN_a8r8g8b8) +{ + r = ((uint32_t *)bits)[y * WIDTH + x] 24; +} +else if (image-bits.format == PIXMAN_a4r4g4b4) +{ + r = ((uint16_t *)bits)[y * WIDTH + x] 12; + r |= r 4; +} +else +{ + assert (0); +} + +return r; +} + +#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0]))) + +static int +run_test (int s, int d, int sa, int da, int soff, int doff) +{ +pixman_format_code_t sf = formats[s]; +pixman_format_code_t df = formats[d
[Pixman] [PATCH 3/5] Rename FAST_PATH_NO_WIDE_FORMAT to FAST_PATH_NARROW_FORMAT
From: Søren Sandmann Pedersen s...@redhat.com This avoids a negative in the name. Also, by renaming the wide variable in pixman-general.c to narrow and fixing up the logic correspondingly, the code there reads a lot more straightforwardly. --- pixman/pixman-fast-path.c |2 +- pixman/pixman-general.c | 46 ++-- pixman/pixman-image.c |4 +- pixman/pixman-private.h |6 ++-- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index f03752f..6dee472 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1864,7 +1864,7 @@ static const pixman_fast_path_t c_fast_paths[] = FAST_PATH_NO_ALPHA_MAP| \ FAST_PATH_NEAREST_FILTER | \ FAST_PATH_NO_ACCESSORS| \ - FAST_PATH_NO_WIDE_FORMAT) + FAST_PATH_NARROW_FORMAT) #define SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \ { PIXMAN_OP_ ## op, \ diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index fc742c0..fc276bd 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -63,11 +63,11 @@ general_composite_rect (pixman_implementation_t *imp, mask mask-type == BITS ? mask-bits.format : 0; const pixman_format_code_t dest_format = dest-type == BITS ? dest-bits.format : 0; -const int src_wide = PIXMAN_FORMAT_IS_WIDE (src_format); -const int mask_wide = mask PIXMAN_FORMAT_IS_WIDE (mask_format); -const int dest_wide = PIXMAN_FORMAT_IS_WIDE (dest_format); -const int wide = src_wide || mask_wide || dest_wide; -const int Bpp = wide ? 8 : 4; +const int src_narrow = !PIXMAN_FORMAT_IS_WIDE (src_format); +const int mask_narrow = !mask || !PIXMAN_FORMAT_IS_WIDE (mask_format); +const int dest_narrow = !PIXMAN_FORMAT_IS_WIDE (dest_format); +const int narrow = src_narrow mask_narrow dest_narrow; +const int Bpp = narrow ? 4 : 8; uint8_t *scanline_buffer = stack_scanline_buffer; uint8_t *src_buffer, *mask_buffer, *dest_buffer; fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL; @@ -106,29 +106,29 @@ general_composite_rect (pixman_implementation_t *imp, if (op == PIXMAN_OP_CLEAR) fetch_src = NULL; -else if (wide) - fetch_src = _pixman_image_get_scanline_64; -else +else if (narrow) fetch_src = _pixman_image_get_scanline_32; +else + fetch_src = _pixman_image_get_scanline_64; if (!mask || op == PIXMAN_OP_CLEAR) fetch_mask = NULL; -else if (wide) - fetch_mask = _pixman_image_get_scanline_64; -else +else if (narrow) fetch_mask = _pixman_image_get_scanline_32; +else + fetch_mask = _pixman_image_get_scanline_64; if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC) fetch_dest = NULL; -else if (wide) - fetch_dest = _pixman_image_get_scanline_64; -else +else if (narrow) fetch_dest = _pixman_image_get_scanline_32; - -if (wide) - store = _pixman_image_store_scanline_64; else + fetch_dest = _pixman_image_get_scanline_64; + +if (narrow) store = _pixman_image_store_scanline_32; +else + store = _pixman_image_store_scanline_64; /* Skip the store step and composite directly into the * destination if the output format of the compose func matches @@ -148,7 +148,7 @@ general_composite_rect (pixman_implementation_t *imp, op == PIXMAN_OP_OUT_REVERSE || op == PIXMAN_OP_DST))) { - if (!wide + if (narrow !dest-common.alpha_map !dest-bits.write_func) { @@ -175,19 +175,19 @@ general_composite_rect (pixman_implementation_t *imp, mask-common.component_alpha PIXMAN_FORMAT_RGB (mask-bits.format); -if (wide) +if (narrow) { if (component_alpha) - compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca; + compose = _pixman_implementation_combine_32_ca; else - compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64; + compose = _pixman_implementation_combine_32; } else { if (component_alpha) - compose = _pixman_implementation_combine_32_ca; + compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca; else - compose = _pixman_implementation_combine_32; + compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64; } if (!compose) diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index cfee865..102df6c 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -379,7 +379,7 @@ compute_image_info (pixman_image_t *image
[Pixman] [PATCH 4/5] Remove FAST_PATH_NARROW_FORMAT flag if there is a wide alpha map
From: Søren Sandmann Pedersen s...@redhat.com If an image has an alpha map that has wide components, then we need to use 64 bit processing for that image. We detect this situation in pixman-image.c and remove the FAST_PATH_NARROW_FORMAT flag. In pixman-general, the wide/narrow decision is now based on the flags instead of on the formats. --- pixman/pixman-general.c | 18 +++--- pixman/pixman-image.c | 15 +++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index fc276bd..4d234a0 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -57,17 +57,6 @@ general_composite_rect (pixman_implementation_t *imp, int32_t height) { uint8_t stack_scanline_buffer[SCANLINE_BUFFER_LENGTH * 3]; -const pixman_format_code_t src_format = - src-type == BITS ? src-bits.format : 0; -const pixman_format_code_t mask_format = - mask mask-type == BITS ? mask-bits.format : 0; -const pixman_format_code_t dest_format = - dest-type == BITS ? dest-bits.format : 0; -const int src_narrow = !PIXMAN_FORMAT_IS_WIDE (src_format); -const int mask_narrow = !mask || !PIXMAN_FORMAT_IS_WIDE (mask_format); -const int dest_narrow = !PIXMAN_FORMAT_IS_WIDE (dest_format); -const int narrow = src_narrow mask_narrow dest_narrow; -const int Bpp = narrow ? 4 : 8; uint8_t *scanline_buffer = stack_scanline_buffer; uint8_t *src_buffer, *mask_buffer, *dest_buffer; fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL; @@ -77,8 +66,15 @@ general_composite_rect (pixman_implementation_t *imp, pixman_bool_t component_alpha; uint32_t *bits; int32_t stride; +int narrow, Bpp; int i; +narrow = + (src-common.flags FAST_PATH_NARROW_FORMAT) + (!mask || mask-common.flags FAST_PATH_NARROW_FORMAT) + (dest-common.flags FAST_PATH_NARROW_FORMAT); +Bpp = narrow ? 4 : 8; + if (width * Bpp SCANLINE_BUFFER_LENGTH) { scanline_buffer = pixman_malloc_abc (width, 3, Bpp); diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 102df6c..029a1df 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -327,10 +327,6 @@ compute_image_info (pixman_image_t *image) flags |= FAST_PATH_Y_UNIT_ZERO; } -/* Alpha map */ -if (!image-common.alpha_map) - flags |= FAST_PATH_NO_ALPHA_MAP; - /* Filter */ switch (image-common.filter) { @@ -454,6 +450,17 @@ compute_image_info (pixman_image_t *image) break; } +/* Alpha map */ +if (!image-common.alpha_map) +{ + flags |= FAST_PATH_NO_ALPHA_MAP; +} +else +{ + if (PIXMAN_FORMAT_IS_WIDE (image-common.alpha_map-format)) + flags = ~FAST_PATH_NARROW_FORMAT; +} + /* Both alpha maps and convolution filters can introduce * non-opaqueness in otherwise opaque images. Also * an image with component alpha turned on is only opaque -- 1.7.1.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 5/5] Clip composite region against the destination alpha map extents.
From: Søren Sandmann Pedersen s...@redhat.com Otherwise we can end up writing outside the alpha map. --- pixman/pixman.c | 21 + 1 files changed, 17 insertions(+), 4 deletions(-) diff --git a/pixman/pixman.c b/pixman/pixman.c index cdf4b75..285bbfc 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -315,14 +315,27 @@ pixman_compute_composite_region32 (pixman_region32_t * region, return FALSE; } -if (dst_image-common.alpha_map dst_image-common.alpha_map-common.have_clip_region) +if (dst_image-common.alpha_map) { - if (!clip_general_image (region, dst_image-common.alpha_map-common.clip_region, --dst_image-common.alpha_origin_x, --dst_image-common.alpha_origin_y)) + if (!pixman_region32_intersect_rect (region, region, +dst_image-common.alpha_origin_x, +dst_image-common.alpha_origin_y, +dst_image-common.alpha_map-width, + dst_image-common.alpha_map-height)) { return FALSE; } + if (!pixman_region32_not_empty (region)) + return FALSE; + if (dst_image-common.alpha_map-common.have_clip_region) + { + if (!clip_general_image (region, dst_image-common.alpha_map-common.clip_region, +-dst_image-common.alpha_origin_x, +-dst_image-common.alpha_origin_y)) + { + return FALSE; + } + } } /* clip against src */ -- 1.7.1.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 0/5] Fix various alpha map related bugs
From: Søren Sandmann Pedersen sandm...@daimi.au.dk Hi, The following patch series contains some fixes for various alpha-map related bugs. The bugs are: - We don't currently clip the composite region against the extents of the alpha map of the destination. This means that if the alpha map doesn't cover the entire destination, we will make invalid writes to it. - If the alpha map is one of the 10bpc formats, then it doesn't have a 32 bit fetcher installed, which causes crashes. The fix for this is to make sure wide alpha maps result in wide processing. There is also a stylistic change where the NO_WIDE_FORMAT flag is renamed to FAST_PATH_NARROW_FORMAT to avoid the negative in the name. Finally, there are some updates to the test suite: - The alpha map test is much more aggressive. It now demonstrates the two bugs above and also tests that destination alpha maps are correctly read and written. - The alpha map test now also has code to set a transformation on the destination, but this is commented out because it causes crashes even with the other changes. This problem is somewhat difficult to fix because we currently don't have any fetchers that will do alphamap processing, but ignore transformations. - There is a new fence_malloc()/fence_free() pair of utility functions. These attempt to allocate the memory surrounded by mprotect()ed pages so that invalid reads or writes will cause crashes. Soren Søren Sandmann Pedersen (5): Add fence_malloc() and fence_free(). Update and extend the alphamap test Rename FAST_PATH_NO_WIDE_FORMAT to FAST_PATH_NARROW_FORMAT Remove FAST_PATH_NARROW_FORMAT flag if there is a wide alpha map Clip composite region against the destination alpha map extents. configure.ac | 10 ++ pixman/pixman-fast-path.c |2 +- pixman/pixman-general.c | 54 +-- pixman/pixman-image.c | 19 +++- pixman/pixman-private.h |6 +- pixman/pixman.c | 21 +++- test/Makefile.am |2 +- test/alphamap.c | 243 - test/utils.c | 105 +++- test/utils.h | 11 ++- 10 files changed, 401 insertions(+), 72 deletions(-) ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Rename all the fast paths with _8000 in their names to _8
From: Søren Sandmann Pedersen s...@redhat.com This inconsistent naming somehow survived the refactoring from a while back. --- pixman/pixman-arm-neon-asm.S | 22 +++--- pixman/pixman-arm-neon.c |4 ++-- pixman/pixman-arm-simd-asm.S |2 +- pixman/pixman-arm-simd.c | 16 pixman/pixman-fast-path.c| 28 ++-- pixman/pixman-mmx.c | 28 ++-- pixman/pixman-sse2.c | 30 +++--- test/lowlevel-blt-bench.c|6 +++--- 8 files changed, 68 insertions(+), 68 deletions(-) diff --git a/pixman/pixman-arm-neon-asm.S b/pixman/pixman-arm-neon-asm.S index 9f6568f..b854ab3 100644 --- a/pixman/pixman-arm-neon-asm.S +++ b/pixman/pixman-arm-neon-asm.S @@ -495,15 +495,15 @@ generate_composite_function \ /**/ -.macro pixman_composite_add_8000_8000_process_pixblock_head +.macro pixman_composite_add_8_8_process_pixblock_head vqadd.u8q14, q0, q2 vqadd.u8q15, q1, q3 .endm -.macro pixman_composite_add_8000_8000_process_pixblock_tail +.macro pixman_composite_add_8_8_process_pixblock_tail .endm -.macro pixman_composite_add_8000_8000_process_pixblock_tail_head +.macro pixman_composite_add_8_8_process_pixblock_tail_head vld1.8 {d0, d1, d2, d3}, [SRC]! PF add PF_X, PF_X, #32 PF tst PF_CTL, #0xF @@ -523,15 +523,15 @@ generate_composite_function \ .endm generate_composite_function \ -pixman_composite_add_8000_8000_asm_neon, 8, 0, 8, \ +pixman_composite_add_8_8_asm_neon, 8, 0, 8, \ FLAG_DST_READWRITE, \ 32, /* number of pixels, processed in a single block */ \ 10, /* prefetch distance */ \ default_init, \ default_cleanup, \ -pixman_composite_add_8000_8000_process_pixblock_head, \ -pixman_composite_add_8000_8000_process_pixblock_tail, \ -pixman_composite_add_8000_8000_process_pixblock_tail_head +pixman_composite_add_8_8_process_pixblock_head, \ +pixman_composite_add_8_8_process_pixblock_tail, \ +pixman_composite_add_8_8_process_pixblock_tail_head /**/ @@ -561,8 +561,8 @@ generate_composite_function \ 10, /* prefetch distance */ \ default_init, \ default_cleanup, \ -pixman_composite_add_8000_8000_process_pixblock_head, \ -pixman_composite_add_8000_8000_process_pixblock_tail, \ +pixman_composite_add_8_8_process_pixblock_head, \ +pixman_composite_add_8_8_process_pixblock_tail, \ pixman_composite_add___process_pixblock_tail_head generate_composite_function_single_scanline \ @@ -571,8 +571,8 @@ generate_composite_function_single_scanline \ 8, /* number of pixels, processed in a single block */ \ default_init, \ default_cleanup, \ -pixman_composite_add_8000_8000_process_pixblock_head, \ -pixman_composite_add_8000_8000_process_pixblock_tail, \ +pixman_composite_add_8_8_process_pixblock_head, \ +pixman_composite_add_8_8_process_pixblock_tail, \ pixman_composite_add___process_pixblock_tail_head /**/ diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c index ece6054..cdaa29a 100644 --- a/pixman/pixman-arm-neon.c +++ b/pixman/pixman-arm-neon.c @@ -52,7 +52,7 @@ PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_0565_rev, uint8_t, 3, uint16_t, 1) PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_pixbuf_, uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8000_8000, +PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8_8, uint8_t, 1, uint8_t, 1) PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add__, uint32_t, 1, uint32_t, 1) @@ -257,7 +257,7 @@ static const pixman_fast_path_t arm_neon_fast_paths[] = PIXMAN_STD_FAST_PATH (ADD, solid,a8, a8, neon_composite_add_n_8_8), PIXMAN_STD_FAST_PATH (ADD, a8, a8, a8, neon_composite_add_8_8_8), PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_add___), -PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, neon_composite_add_8000_8000), +PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, neon_composite_add_8_8), PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, neon_composite_add__), PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, neon_composite_add__), PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, neon_composite_over_reverse_n_), diff --git a/pixman/pixman-arm-simd-asm.S b/pixman/pixman-arm-simd-asm.S index 1a1a0d6..a3d2d40
[Pixman] [PATCH] Remove broken optimizations in combine_disjoint_over_u()
From: Søren Sandmann Pedersen s...@redhat.com The first broken optimization is that it checks a != 0x00 where it should check s != 0x00. The other is that it skips the computation when alpha is 0xff. That is wrong because in the formula: min (1, (1 - Aa)/Ab) the render specification states that if Ab is 0, the quotient is defined to positive infinity. That is the case even if (1 - Aa) is 0. --- pixman/pixman-combine.c.template | 14 +- test/blitters-test.c |2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template index c129980..0d3b95d 100644 --- a/pixman/pixman-combine.c.template +++ b/pixman/pixman-combine.c.template @@ -1296,17 +1296,13 @@ combine_disjoint_over_u (pixman_implementation_t *imp, comp4_t s = combine_mask (src, mask, i); comp2_t a = s A_SHIFT; - if (a != 0x00) + if (s != 0x00) { - if (a != MASK) - { - comp4_t d = *(dest + i); - a = combine_disjoint_out_part (d A_SHIFT, a); - UNcx4_MUL_UNc_ADD_UNcx4 (d, a, s); - s = d; - } + comp4_t d = *(dest + i); + a = combine_disjoint_out_part (d A_SHIFT, a); + UNcx4_MUL_UNc_ADD_UNcx4 (d, a, s); - *(dest + i) = s; + *(dest + i) = d; } } } diff --git a/test/blitters-test.c b/test/blitters-test.c index 7ba80eb..77a26dd 100644 --- a/test/blitters-test.c +++ b/test/blitters-test.c @@ -465,6 +465,6 @@ main (int argc, const char *argv[]) } return fuzzer_test_main(blitters, 200, - 0x217CF14A, + 0x1DB8BDF8, test_composite, argc, argv); } -- 1.7.1.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Plug leak in the alphamap test.
From: Søren Sandmann Pedersen s...@redhat.com The images are being created with non-NULL data, so we have to free it outselves. This is important because the Cygwin tinderbox is running out of memory and produces this: mmap failed on 2 1507328 mmap failed on 4 1507328 mmap failed on 2 1507328 mmap failed on 4 1507328 mmap failed on 4 1507328 mmap failed on 4 1507328 http://tinderbox.x.org/builds/2010-10-05-0014/logs/pixman/#check --- test/alphamap.c | 14 +- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/test/alphamap.c b/test/alphamap.c index 09de387..498fdab 100644 --- a/test/alphamap.c +++ b/test/alphamap.c @@ -45,15 +45,27 @@ format_name (pixman_format_code_t format) return unknown - bug in alphamap.c; } +static void +on_destroy (pixman_image_t *image, void *data) +{ +uint32_t *bits = pixman_image_get_data (image); + +fence_free (bits); +} + static pixman_image_t * make_image (pixman_format_code_t format) { uint32_t *bits; uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8; +pixman_image_t *image; bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); -return pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp); +image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp); + +if (image bits) + pixman_image_set_destroy_function (image, on_destroy, NULL); } static pixman_image_t * -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Delete the source_image_t struct.
From: Søren Sandmann Pedersen s...@redhat.com It serves no purpose anymore now that the source_class_t field is gone. --- pixman/pixman-conical-gradient.c | 17 - pixman/pixman-linear-gradient.c | 30 ++ pixman/pixman-private.h | 11 ++- pixman/pixman-radial-gradient.c | 19 +-- 4 files changed, 33 insertions(+), 44 deletions(-) diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c index 897948b..a3685d1 100644 --- a/pixman/pixman-conical-gradient.c +++ b/pixman/pixman-conical-gradient.c @@ -58,8 +58,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image, uint32_t * buffer, const uint32_t *mask) { -source_image_t *source = (source_image_t *)image; -gradient_t *gradient = (gradient_t *)source; +gradient_t *gradient = (gradient_t *)image; conical_gradient_t *conical = (conical_gradient_t *)image; uint32_t *end = buffer + width; pixman_gradient_walker_t walker; @@ -71,9 +70,9 @@ conical_gradient_get_scanline_32 (pixman_image_t *image, double ry = y + 0.5; double rz = 1.; -_pixman_gradient_walker_init (walker, gradient, source-common.repeat); +_pixman_gradient_walker_init (walker, gradient, image-common.repeat); -if (source-common.transform) +if (image-common.transform) { pixman_vector_t v; @@ -82,19 +81,19 @@ conical_gradient_get_scanline_32 (pixman_image_t *image, v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; v.vector[2] = pixman_fixed_1; - if (!pixman_transform_point_3d (source-common.transform, v)) + if (!pixman_transform_point_3d (image-common.transform, v)) return; - cx = source-common.transform-matrix[0][0] / 65536.; - cy = source-common.transform-matrix[1][0] / 65536.; - cz = source-common.transform-matrix[2][0] / 65536.; + cx = image-common.transform-matrix[0][0] / 65536.; + cy = image-common.transform-matrix[1][0] / 65536.; + cz = image-common.transform-matrix[2][0] / 65536.; rx = v.vector[0] / 65536.; ry = v.vector[1] / 65536.; rz = v.vector[2] / 65536.; affine = - source-common.transform-matrix[2][0] == 0 + image-common.transform-matrix[2][0] == 0 v.vector[2] == pixman_fixed_1; } diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c index b048e7b..1547882 100644 --- a/pixman/pixman-linear-gradient.c +++ b/pixman/pixman-linear-gradient.c @@ -38,7 +38,6 @@ linear_gradient_classify (pixman_image_t *image, int width, int height) { -source_image_t *source = (source_image_t *)image; linear_gradient_t *linear = (linear_gradient_t *)image; pixman_vector_t v; pixman_fixed_32_32_t l; @@ -48,19 +47,19 @@ linear_gradient_classify (pixman_image_t *image, class = SOURCE_IMAGE_CLASS_UNKNOWN; -if (source-common.transform) +if (image-common.transform) { /* projective transformation */ - if (source-common.transform-matrix[2][0] != 0 || - source-common.transform-matrix[2][1] != 0 || - source-common.transform-matrix[2][2] == 0) + if (image-common.transform-matrix[2][0] != 0 || + image-common.transform-matrix[2][1] != 0 || + image-common.transform-matrix[2][2] == 0) { return class; } - v.vector[0] = source-common.transform-matrix[0][1]; - v.vector[1] = source-common.transform-matrix[1][1]; - v.vector[2] = source-common.transform-matrix[2][2]; + v.vector[0] = image-common.transform-matrix[0][1]; + v.vector[1] = image-common.transform-matrix[1][1]; + v.vector[2] = image-common.transform-matrix[2][2]; } else { @@ -104,26 +103,25 @@ linear_gradient_get_scanline_32 (pixman_image_t *image, pixman_fixed_32_32_t l; pixman_fixed_48_16_t dx, dy; gradient_t *gradient = (gradient_t *)image; -source_image_t *source = (source_image_t *)image; linear_gradient_t *linear = (linear_gradient_t *)image; uint32_t *end = buffer + width; pixman_gradient_walker_t walker; -_pixman_gradient_walker_init (walker, gradient, source-common.repeat); +_pixman_gradient_walker_init (walker, gradient, image-common.repeat); /* reference point is the center of the pixel */ v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; v.vector[2] = pixman_fixed_1; -if (source-common.transform) +if (image-common.transform) { - if (!pixman_transform_point_3d (source-common.transform, v)) + if (!pixman_transform_point_3d (image-common.transform, v)) return
[Pixman] [PATCH] Add support for AltiVec detection for OpenBSD/PowerPC.
From: Brad Smith b...@comstyle.com Bug 29331. --- pixman/pixman-cpu.c | 25 - 1 files changed, 24 insertions(+), 1 deletions(-) diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c index e96b140..1b31885 100644 --- a/pixman/pixman-cpu.c +++ b/pixman/pixman-cpu.c @@ -61,6 +61,29 @@ pixman_have_vmx (void) return have_vmx; } +#elif defined (__OpenBSD__) +#include sys/param.h +#include sys/sysctl.h +#include machine/cpu.h + +static pixman_bool_t +pixman_have_vmx (void) +{ +if (!initialized) +{ + int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC }; + size_t length = sizeof(have_vmx); + int error = + sysctl (mib, 2, have_vmx, length, NULL, 0); + + if (error) + have_vmx = FALSE; + + initialized = TRUE; +} +return have_vmx; +} + #elif defined (__linux__) #include sys/types.h #include sys/stat.h @@ -123,7 +146,7 @@ pixman_have_vmx (void) return have_vmx; } -#else /* !__APPLE__ !__linux__ */ +#else /* !__APPLE__ !__OpenBSD__ !__linux__ */ #include signal.h #include setjmp.h -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] Some test suite improvements
Here is a set of patches that contain some updates to the test suite. Specifically, - gradient-crash-test is extended to test more scenarios - floating point exceptions are enabled in some cases - The argument to fence_malloc() becomes a signed integer, and it will abort() if someone tries to malloc a negative size. - A new stress-test program that tries to use various combinations of unusual features. The hope is that this will provoke crashes or irregular behavior. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Add enable_fp_exceptions() function in utils.[ch]
From: Søren Sandmann Pedersen s...@redhat.com This function enables floating point traps if possible. --- configure.ac |8 test/utils.c | 26 ++ test/utils.h |3 +++ 3 files changed, 37 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index 147e1bf..2570c84 100644 --- a/configure.ac +++ b/configure.ac @@ -639,6 +639,14 @@ if test x$have_getpagesize = xyes; then AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()]) fi +AC_CHECK_HEADER([fenv.h], + [AC_DEFINE(HAVE_FENV_H, [1], [Define to 1 if we have fenv.h])]) + +AC_CHECK_LIB(m, feenableexcept, have_feenableexcept=yes, have_feenableexcept=no) +if test x$have_feenableexcept = xyes; then + AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()]) +fi + AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no) AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no) if test x$have_gettimeofday = xyes test x$have_sys_time_h = xyes; then diff --git a/test/utils.c b/test/utils.c index f6278fe..a7c55f6 100644 --- a/test/utils.c +++ b/test/utils.c @@ -1,3 +1,5 @@ +#define _GNU_SOURCE + #include utils.h #include signal.h @@ -15,6 +17,10 @@ #include sys/mman.h #endif +#ifdef HAVE_FENV_H +#include fenv.h +#endif + /* Random number seed */ @@ -469,6 +475,26 @@ fail_after (int seconds, const char *msg) #endif } +void +enable_fp_exceptions (void) +{ +#ifdef HAVE_FENV_H +#ifdef HAVE_FEENABLEEXCEPT +/* Note: we don't enable the FE_INEXACT trap because + * that happens quite commonly. It is possible that + * over- and underflow should similarly be considered + * okay, but for now the test suite passes with them + * enabled, and it's useful to know if they start + * occuring. + */ +feenableexcept (FE_DIVBYZERO | + FE_INVALID | + FE_OVERFLOW | + FE_UNDERFLOW); +#endif +#endif +} + void * aligned_malloc (size_t align, size_t size) { diff --git a/test/utils.h b/test/utils.h index 2ea4170..bac2916 100644 --- a/test/utils.h +++ b/test/utils.h @@ -82,6 +82,9 @@ fuzzer_test_main (const char *test_name, void fail_after (int seconds, const char *msg); +/* If possible, enable traps for floating point exceptions */ +void enable_fp_exceptions(void); + /* A pair of macros which can help to detect corruption of * floating point registers after a function call. This may * happen if _mm_empty() call is forgotten in MMX/SSE2 fast -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] bits: Fix potential divide-by-zero in projective code
From: Søren Sandmann Pedersen s...@redhat.com If the homogeneous coordinate is 0, just set the coordinates to 0. --- pixman/pixman-bits-image.c | 16 1 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 95710b4..36ea0af 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -695,12 +695,20 @@ bits_image_fetch_transformed (pixman_image_t * image, { for (i = 0; i width; ++i) { - pixman_fixed_t x0, y0; - if (!mask || mask[i]) { - x0 = ((pixman_fixed_48_16_t)x 16) / w; - y0 = ((pixman_fixed_48_16_t)y 16) / w; + pixman_fixed_t x0, y0; + + if (w != 0) + { + x0 = ((pixman_fixed_48_16_t)x 16) / w; + y0 = ((pixman_fixed_48_16_t)y 16) / w; + } + else + { + x0 = 0; + y0 = 0; + } buffer[i] = bits_image_fetch_pixel_filtered (image-bits, x0, y0); -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/7] Add enable_fp_exceptions() function in utils.[ch]
From: Søren Sandmann Pedersen s...@redhat.com This function enables floating point traps if possible. --- configure.ac |8 test/utils.c | 26 ++ test/utils.h |3 +++ 3 files changed, 37 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index 147e1bf..2570c84 100644 --- a/configure.ac +++ b/configure.ac @@ -639,6 +639,14 @@ if test x$have_getpagesize = xyes; then AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()]) fi +AC_CHECK_HEADER([fenv.h], + [AC_DEFINE(HAVE_FENV_H, [1], [Define to 1 if we have fenv.h])]) + +AC_CHECK_LIB(m, feenableexcept, have_feenableexcept=yes, have_feenableexcept=no) +if test x$have_feenableexcept = xyes; then + AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()]) +fi + AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no) AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no) if test x$have_gettimeofday = xyes test x$have_sys_time_h = xyes; then diff --git a/test/utils.c b/test/utils.c index f6278fe..a7c55f6 100644 --- a/test/utils.c +++ b/test/utils.c @@ -1,3 +1,5 @@ +#define _GNU_SOURCE + #include utils.h #include signal.h @@ -15,6 +17,10 @@ #include sys/mman.h #endif +#ifdef HAVE_FENV_H +#include fenv.h +#endif + /* Random number seed */ @@ -469,6 +475,26 @@ fail_after (int seconds, const char *msg) #endif } +void +enable_fp_exceptions (void) +{ +#ifdef HAVE_FENV_H +#ifdef HAVE_FEENABLEEXCEPT +/* Note: we don't enable the FE_INEXACT trap because + * that happens quite commonly. It is possible that + * over- and underflow should similarly be considered + * okay, but for now the test suite passes with them + * enabled, and it's useful to know if they start + * occuring. + */ +feenableexcept (FE_DIVBYZERO | + FE_INVALID | + FE_OVERFLOW | + FE_UNDERFLOW); +#endif +#endif +} + void * aligned_malloc (size_t align, size_t size) { diff --git a/test/utils.h b/test/utils.h index 2ea4170..bac2916 100644 --- a/test/utils.h +++ b/test/utils.h @@ -82,6 +82,9 @@ fuzzer_test_main (const char *test_name, void fail_after (int seconds, const char *msg); +/* If possible, enable traps for floating point exceptions */ +void enable_fp_exceptions(void); + /* A pair of macros which can help to detect corruption of * floating point registers after a function call. This may * happen if _mm_empty() call is forgotten in MMX/SSE2 fast -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 3/7] Extend gradient-crash-test
From: Søren Sandmann Pedersen s...@redhat.com Test the gradients with various transformations, and test cases where the gradients are specified with two identical points. --- test/Makefile.am |5 ++- test/gradient-crash-test.c | 124 +-- 2 files changed, 87 insertions(+), 42 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index 79a1223..4f950d9 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -14,6 +14,7 @@ TESTPROGRAMS =\ trap-crasher\ alpha-loop \ scaling-crash-test \ + gradient-crash-test \ alphamap\ blitters-test \ scaling-test\ @@ -22,7 +23,6 @@ TESTPROGRAMS =\ a1_trap_test_LDADD = $(TEST_LDADD) fetch_test_LDADD = $(TEST_LDADD) -gradient_crash_test_LDADD = $(TEST_LDADD) trap_crasher_LDADD = $(TEST_LDADD) oob_test_LDADD = $(TEST_LDADD) scaling_crash_test_LDADD = $(TEST_LDADD) @@ -49,6 +49,9 @@ alpha_loop_SOURCES = alpha-loop.c utils.c utils.h composite_LDADD = $(TEST_LDADD) composite_SOURCES = composite.c utils.c utils.h +gradient_crash_test_LDADD = $(TEST_LDADD) +gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h + # GTK using test programs if HAVE_GTK diff --git a/test/gradient-crash-test.c b/test/gradient-crash-test.c index 804f83b..395c469 100644 --- a/test/gradient-crash-test.c +++ b/test/gradient-crash-test.c @@ -1,6 +1,7 @@ #include stdio.h #include stdlib.h -#include pixman.h +#include fenv.h +#include utils.h int main (int argc, char **argv) @@ -11,8 +12,14 @@ main (int argc, char **argv) uint32_t *dest = malloc (WIDTH * HEIGHT * 4); pixman_image_t *src_img; pixman_image_t *dest_img; -int i, j; +int i, j, k, p; +typedef struct +{ + pixman_point_fixed_t p0; + pixman_point_fixed_t p1; +} point_pair_t; + pixman_gradient_stop_t onestop[1] = { { pixman_int_to_fixed (1), { 0x, 0x, 0x, 0x } }, @@ -30,29 +37,56 @@ main (int argc, char **argv) { pixman_int_to_fixed (1), { 0x, 0x, 0x, 0x } } }; -pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 }; -pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH / 8.), - pixman_int_to_fixed (0) }; - -#if 0 -pixman_transform_t trans = { - { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), }, - { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), }, - { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } - } -}; -#else -pixman_transform_t trans = { - { { pixman_fixed_1, 0, 0 }, - { 0, pixman_fixed_1, 0 }, - { 0, 0, pixman_fixed_1 } } +point_pair_t point_pairs [] = + { { { pixman_double_to_fixed (0), 0 }, + { pixman_double_to_fixed (WIDTH / 8.), pixman_int_to_fixed (0) } }, + { { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) }, + { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) } } + }; + +pixman_transform_t transformations[] = { + { + { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), }, + { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), }, + { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } + } + }, + { + { { pixman_double_to_fixed (1), pixman_double_to_fixed (0), pixman_double_to_fixed (0), }, + { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, + { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } + } + }, + { + { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, + { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, + { pixman_double_to_fixed (2), pixman_double_to_fixed (1.000), pixman_double_to_fixed (1.0) } + } + }, + { + { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, + { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, + { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (0) } + } + }, + { + { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, + { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed
[Pixman] [PATCH 4/7] test: Move palette initialization to utils.[ch]
From: Søren Sandmann Pedersen s...@redhat.com --- test/blitters-test.c | 57 + test/utils.c | 54 +++ test/utils.h |3 ++ 3 files changed, 59 insertions(+), 55 deletions(-) diff --git a/test/blitters-test.c b/test/blitters-test.c index 77a26dd..21685b1 100644 --- a/test/blitters-test.c +++ b/test/blitters-test.c @@ -400,59 +400,6 @@ test_composite (int testnum, int verbose) return crc32; } -#define CONVERT_15(c, is_rgb) \ -(is_rgb? \ - c) 3) 0x001f) | \ - (((c) 6) 0x03e0) | \ - (((c) 9) 0x7c00)) : \ - (c) 16) 0xff) * 153 +\ - (((c) 8) 0xff) * 301 +\ - (((c) ) 0xff) * 58) 2)) - -static void -initialize_palette (pixman_indexed_t *palette, uint32_t mask, int is_rgb) -{ -int i; - -for (i = 0; i 32768; ++i) - palette-ent[i] = lcg_rand() mask; - -for (i = 0; i mask + 1; ++i) -{ - uint32_t rgba24; - pixman_bool_t retry; - uint32_t i15; - - /* We filled the rgb-index map with random numbers, but we -* do need the ability to round trip, that is if some indexed -* color expands to an argb24, then the 15 bit version of that -* color must map back to the index. Anything else, we don't -* care about too much. -*/ - do - { - uint32_t old_idx; - - rgba24 = lcg_rand(); - i15 = CONVERT_15 (rgba24, is_rgb); - - old_idx = palette-ent[i15]; - if (CONVERT_15 (palette-rgba[old_idx], is_rgb) == i15) - retry = 1; - else - retry = 0; - } while (retry); - - palette-rgba[i] = rgba24; - palette-ent[i15] = i; -} - -for (i = 0; i mask + 1; ++i) -{ - assert (palette-ent[CONVERT_15 (palette-rgba[i], is_rgb)] == i); -} -} - int main (int argc, const char *argv[]) { @@ -460,8 +407,8 @@ main (int argc, const char *argv[]) for (i = 1; i = 8; i++) { - initialize_palette ((rgb_palette[i]), (1 i) - 1, TRUE); - initialize_palette ((y_palette[i]), (1 i) - 1, FALSE); + initialize_palette ((rgb_palette[i]), i, TRUE); + initialize_palette ((y_palette[i]), i, FALSE); } return fuzzer_test_main(blitters, 200, diff --git a/test/utils.c b/test/utils.c index a7c55f6..4701bf6 100644 --- a/test/utils.c +++ b/test/utils.c @@ -509,3 +509,57 @@ aligned_malloc (size_t align, size_t size) return result; } + +#define CONVERT_15(c, is_rgb) \ +(is_rgb? \ + c) 3) 0x001f) | \ + (((c) 6) 0x03e0) | \ + (((c) 9) 0x7c00)) : \ + (c) 16) 0xff) * 153 +\ + (((c) 8) 0xff) * 301 +\ + (((c) ) 0xff) * 58) 2)) + +void +initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb) +{ +int i; +uint32_t mask = (1 depth) - 1; + +for (i = 0; i 32768; ++i) + palette-ent[i] = lcg_rand() mask; + +for (i = 0; i mask + 1; ++i) +{ + uint32_t rgba24; + pixman_bool_t retry; + uint32_t i15; + + /* We filled the rgb-index map with random numbers, but we +* do need the ability to round trip, that is if some indexed +* color expands to an argb24, then the 15 bit version of that +* color must map back to the index. Anything else, we don't +* care about too much. +*/ + do + { + uint32_t old_idx; + + rgba24 = lcg_rand(); + i15 = CONVERT_15 (rgba24, is_rgb); + + old_idx = palette-ent[i15]; + if (CONVERT_15 (palette-rgba[old_idx], is_rgb) == i15) + retry = 1; + else + retry = 0; + } while (retry); + + palette-rgba[i] = rgba24; + palette-ent[i15] = i; +} + +for (i = 0; i mask + 1; ++i) +{ + assert (palette-ent[CONVERT_15 (palette-rgba[i], is_rgb)] == i); +} +} diff --git a/test/utils.h b/test/utils.h index bac2916..7b33461 100644 --- a/test/utils.h +++ b/test/utils.h @@ -123,3 +123,6 @@ void enable_fp_exceptions(void); /* Try to get an aligned memory chunk */ void * aligned_malloc (size_t align, size_t size); + +void +initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb); -- 1.6.0.6
[Pixman] [PATCH 5/7] test/utils.c: Initialize palette-rgba to 0.
From: Søren Sandmann Pedersen s...@redhat.com That way it can be used with palettes that are not statically allocated, without causing valgrind issues. --- test/utils.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/test/utils.c b/test/utils.c index 4701bf6..cde9c62 100644 --- a/test/utils.c +++ b/test/utils.c @@ -528,6 +528,8 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb) for (i = 0; i 32768; ++i) palette-ent[i] = lcg_rand() mask; +memset (palette-rgba, 0, sizeof (palette-rgba)); + for (i = 0; i mask + 1; ++i) { uint32_t rgba24; -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 1/2] Add a test compositing with the various PDF operators.
From: Søren Sandmann Pedersen s...@redhat.com The test has floating point exceptions enabled, and currently fails with a divide-by-zero. --- test/Makefile.am |4 ++ test/pdf-op-test.c | 84 2 files changed, 88 insertions(+), 0 deletions(-) create mode 100644 test/pdf-op-test.c diff --git a/test/Makefile.am b/test/Makefile.am index 52e4183..3d40157 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -6,6 +6,7 @@ INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman TESTPROGRAMS = \ a1-trap-test\ + pdf-op-test \ region-test \ region-translate-test \ fetch-test \ @@ -28,6 +29,9 @@ oob_test_LDADD = $(TEST_LDADD) scaling_crash_test_LDADD = $(TEST_LDADD) region_translate_test_LDADD = $(TEST_LDADD) +pdf_op_test_LDADD = $(TEST_LDADD) +pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h + region_test_LDADD = $(TEST_LDADD) region_test_SOURCES = region-test.c utils.c utils.h diff --git a/test/pdf-op-test.c b/test/pdf-op-test.c new file mode 100644 index 000..dc7a4fd --- /dev/null +++ b/test/pdf-op-test.c @@ -0,0 +1,84 @@ +#include config.h +#include stdlib.h +#include utils.h + +static const pixman_op_t pdf_ops[] = +{ +PIXMAN_OP_MULTIPLY, +PIXMAN_OP_SCREEN, +PIXMAN_OP_OVERLAY, +PIXMAN_OP_DARKEN, +PIXMAN_OP_LIGHTEN, +PIXMAN_OP_COLOR_DODGE, +PIXMAN_OP_COLOR_BURN, +PIXMAN_OP_HARD_LIGHT, +PIXMAN_OP_SOFT_LIGHT, +PIXMAN_OP_DIFFERENCE, +PIXMAN_OP_EXCLUSION, +PIXMAN_OP_HSL_HUE, +PIXMAN_OP_HSL_SATURATION, +PIXMAN_OP_HSL_COLOR, +PIXMAN_OP_HSL_LUMINOSITY +}; + +static const uint32_t pixels[] = +{ +0x00808080, +0x80123456, +0x, +0x, +0x00ff, +0x80808080, +0x00123456, +}; + +int +main () +{ +int o, s, m, d; + +enable_fp_exceptions(); + +for (o = 0; o ARRAY_LENGTH (pdf_ops); ++o) +{ + pixman_op_t op = pdf_ops[o]; + + for (s = 0; s ARRAY_LENGTH (pixels); ++s) + { + pixman_image_t *src; + + src = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, 1, 1, (uint32_t *)(pixels[s]), 4); + + for (m = -1; m ARRAY_LENGTH (pixels); ++m) + { + pixman_image_t *msk = NULL; + if (m = 0) + { + msk = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, 1, 1, (uint32_t *)(pixels[m]), 4); + } + + for (d = 0; d ARRAY_LENGTH (pixels); ++d) + { + pixman_image_t *dst; + uint32_t dp = pixels[d]; + + dst = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, 1, 1, dp, 4); + + pixman_image_composite (op, src, msk, dst, + 0, 0, 0, 0, 0, 0, 1, 1); + + pixman_image_unref (dst); + } + if (msk) + pixman_image_unref (msk); + } + + pixman_image_unref (src); + } +} + +return 0; +} -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/2] Fix divide-by-zero in set_lum().
From: Søren Sandmann Pedersen s...@redhat.com When (l - min) or (max - l) are zero, simply set all the channels to the limit, 0 in the case of (l - min), and a in the case of (max - l). --- pixman/pixman-combine.c.template | 30 -- 1 files changed, 24 insertions(+), 6 deletions(-) diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template index 56dfb43..f5dd8e1 100644 --- a/pixman/pixman-combine.c.template +++ b/pixman/pixman-combine.c.template @@ -959,15 +959,33 @@ set_lum (comp4_t dest[3], comp4_t src[3], comp4_t sa, comp4_t lum) if (min 0) { - tmp[0] = l + (tmp[0] - l) * l / (l - min); - tmp[1] = l + (tmp[1] - l) * l / (l - min); - tmp[2] = l + (tmp[2] - l) * l / (l - min); + if (l - min == 0.0) + { + tmp[0] = 0; + tmp[1] = 0; + tmp[2] = 0; + } + else + { + tmp[0] = l + (tmp[0] - l) * l / (l - min); + tmp[1] = l + (tmp[1] - l) * l / (l - min); + tmp[2] = l + (tmp[2] - l) * l / (l - min); + } } if (max a) { - tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l); - tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l); - tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l); + if (max - l == 0.0) + { + tmp[0] = a; + tmp[1] = a; + tmp[2] = a; + } + else + { + tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l); + tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l); + tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l); + } } dest[0] = tmp[0] * MASK + 0.5; -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] sse2: Skip src pixels that are zero in sse2_composite_over_8888_n_8888()
From: Søren Sandmann Pedersen s...@redhat.com This is a big speed-up in the SVG helicopter game: http://ie.microsoft.com/testdrive/Performance/Helicopter/Default.xhtml when rendered by Firefox 4 since it is compositing big images consisting almost entirely of zeros. --- pixman/pixman-sse2.c | 75 + 1 files changed, 44 insertions(+), 31 deletions(-) diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index 5907de0..032f13b 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -3051,37 +3051,45 @@ sse2_composite_over__n_ (pixman_implementation_t *imp, while (w (unsigned long)dst 15) { uint32_t s = *src++; - uint32_t d = *dst; - - __m64 ms = unpack_32_1x64 (s); - __m64 alpha= expand_alpha_1x64 (ms); - __m64 dest = _mm_movepi64_pi64 (xmm_mask); - __m64 alpha_dst = unpack_32_1x64 (d); - - *dst++ = pack_1x64_32 ( - in_over_1x64 (ms, alpha, dest, alpha_dst)); + if (s) + { + uint32_t d = *dst; + + __m64 ms = unpack_32_1x64 (s); + __m64 alpha= expand_alpha_1x64 (ms); + __m64 dest = _mm_movepi64_pi64 (xmm_mask); + __m64 alpha_dst = unpack_32_1x64 (d); + + *dst = pack_1x64_32 ( + in_over_1x64 (ms, alpha, dest, alpha_dst)); + } + dst++; w--; } while (w = 4) { xmm_src = load_128_unaligned ((__m128i*)src); - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_src, xmm_src_lo, xmm_src_hi); - unpack_128_2x128 (xmm_dst, xmm_dst_lo, xmm_dst_hi); - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - xmm_alpha_lo, xmm_alpha_hi); - - in_over_2x128 (xmm_src_lo, xmm_src_hi, - xmm_alpha_lo, xmm_alpha_hi, - xmm_mask, xmm_mask, - xmm_dst_lo, xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); + if (!is_zero (xmm_src)) + { + xmm_dst = load_128_aligned ((__m128i*)dst); + + unpack_128_2x128 (xmm_src, xmm_src_lo, xmm_src_hi); + unpack_128_2x128 (xmm_dst, xmm_dst_lo, xmm_dst_hi); + expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, + xmm_alpha_lo, xmm_alpha_hi); + + in_over_2x128 (xmm_src_lo, xmm_src_hi, + xmm_alpha_lo, xmm_alpha_hi, + xmm_mask, xmm_mask, + xmm_dst_lo, xmm_dst_hi); + + save_128_aligned ( + (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); + } + dst += 4; src += 4; w -= 4; @@ -3090,16 +3098,21 @@ sse2_composite_over__n_ (pixman_implementation_t *imp, while (w) { uint32_t s = *src++; - uint32_t d = *dst; - __m64 ms = unpack_32_1x64 (s); - __m64 alpha = expand_alpha_1x64 (ms); - __m64 mask = _mm_movepi64_pi64 (xmm_mask); - __m64 dest = unpack_32_1x64 (d); - - *dst++ = pack_1x64_32 ( - in_over_1x64 (ms, alpha, mask, dest)); + if (s) + { + uint32_t d = *dst; + + __m64 ms = unpack_32_1x64 (s); + __m64 alpha = expand_alpha_1x64 (ms); + __m64 mask = _mm_movepi64_pi64 (xmm_mask); + __m64 dest = unpack_32_1x64 (d); + + *dst = pack_1x64_32 ( + in_over_1x64 (ms, alpha, mask, dest)); + } + dst++; w--; } } -- 1.7.3.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 03/18] Eliminate the _pixman_image_store_scanline_32/64 functions.
From: Søren Sandmann Pedersen s...@redhat.com They were only called from next_line_write_narrow/wide, so they could simply be absorbed into those functions. --- pixman/pixman-bits-image.c | 79 pixman/pixman-private.h| 17 - 2 files changed, 36 insertions(+), 60 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 33b908a..15a12da 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -35,45 +35,6 @@ #include pixman-private.h #include pixman-combine32.h -/* Store functions */ -void -_pixman_image_store_scanline_32 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ -image-store_scanline_32 (image, x, y, width, buffer); - -if (image-common.alpha_map) -{ - x -= image-common.alpha_origin_x; - y -= image-common.alpha_origin_y; - - image-common.alpha_map-store_scanline_32 ( - image-common.alpha_map, x, y, width, buffer); -} -} - -void -_pixman_image_store_scanline_64 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ -image-store_scanline_64 (image, x, y, width, buffer); - -if (image-common.alpha_map) -{ - x -= image-common.alpha_origin_x; - y -= image-common.alpha_origin_y; - - image-common.alpha_map-store_scanline_64 ( - image-common.alpha_map, x, y, width, buffer); -} -} - /* Fetch functions */ static force_inline uint32_t @@ -1369,15 +1330,47 @@ get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) static void next_line_write_narrow (pixman_iter_t *iter) { -_pixman_image_store_scanline_32 ( - iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); +bits_image_t * image = iter-image-bits; +int x = iter-x; +int y = iter-y; +int width = iter-width; +const uint32_t *buffer = iter-buffer; + +image-store_scanline_32 (image, x, y, width, buffer); + +if (image-common.alpha_map) +{ + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; + + image-common.alpha_map-store_scanline_32 ( + image-common.alpha_map, x, y, width, buffer); +} + +iter-y++; } static void next_line_write_wide (pixman_iter_t *iter) { -_pixman_image_store_scanline_64 ( - iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); +bits_image_t * image = iter-image-bits; +int x = iter-x; +int y = iter-y; +int width = iter-width; +const uint32_t *buffer = iter-buffer; + +image-store_scanline_64 (image, x, y, width, buffer); + +if (image-common.alpha_map) +{ + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; + + image-common.alpha_map-store_scanline_64 ( + image-common.alpha_map, x, y, width, buffer); +} + +iter-y++; } void diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 5e441fe..0511ade 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -254,23 +254,6 @@ _pixman_image_get_scanline_64 (pixman_image_t *image, uint32_t * buffer, const uint32_t *unused); -void -_pixman_image_store_scanline_32 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer); - -/* Even though the type of buffer is uint32_t *, the function - * actually expects a uint64_t *buffer. - */ -void -_pixman_image_store_scanline_64 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer); - pixman_image_t * _pixman_image_allocate (void); -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 06/18] Add _pixman_radial_gradient_iter_init() and call it from pixman-general.c
From: Søren Sandmann Pedersen s...@redhat.com --- pixman/pixman-general.c |5 + pixman/pixman-private.h | 11 +++ pixman/pixman-radial-gradient.c | 34 ++ 3 files changed, 50 insertions(+), 0 deletions(-) diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index a2697ef..5865143 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -91,6 +91,11 @@ iter_init (pixman_implementation_t *imp, _pixman_linear_gradient_iter_init ( image, iter, x, y, width, height, buffer, flags); } +else if (image-type == RADIAL) +{ + _pixman_radial_gradient_iter_init ( + image, iter, x, y, width, height, buffer, flags); +} else if (image-type == BITS) { _pixman_bits_image_iter_init ( diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index d22f242..1c6f041 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -232,6 +232,17 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image, uint8_t *buffer, iter_flags_t flags); void +_pixman_solid_fill_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); +void +_pixman_radial_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void _pixman_image_get_scanline_generic_64 (pixman_image_t *image, int x, int y, diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c index b595ba7..9b8c49b 100644 --- a/pixman/pixman-radial-gradient.c +++ b/pixman/pixman-radial-gradient.c @@ -377,6 +377,40 @@ radial_gradient_property_changed (pixman_image_t *image) image-common.get_scanline_64 = _pixman_image_get_scanline_generic_64; } +static uint32_t * +radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ +radial_gradient_get_scanline_32 ( + iter-image, iter-x, iter-y, iter-width, + iter-buffer, mask); + +return iter-buffer; +} + +static uint32_t * +radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ +uint32_t *buffer = radial_get_scanline_narrow (iter, NULL); + +pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter-width); + +return buffer; +} + +void +_pixman_radial_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ +if (flags ITER_NARROW) + iter-get_scanline = radial_get_scanline_narrow; +else + iter-get_scanline = radial_get_scanline_wide; + +iter-next_line = _pixman_iter_next_line_regular; +} + PIXMAN_EXPORT pixman_image_t * pixman_image_create_radial_gradient (pixman_point_fixed_t *inner, pixman_point_fixed_t *outer, -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 01/18] Add iterators in the general implementation
From: Søren Sandmann Pedersen s...@redhat.com We add a new structure called a pixman_iter_t that encapsulates the information required to read scanlines from an image. It contains two functions, get_scanline() and next_line(), where get_scanline() will generate pixels for the current scanline, and next_line() will step to the next scanline. When the iterator is initialized, it is passed this information: - The image to iterate - The rectangle to be iterated - A buffer that the iterator may use (but is not required to) - Flags indicating, - whether a8r8g8b8 or a16r16g16b16 pixels should be fetched - whether the pixels should be written back during next_line(). There are a number of (eventual) benefits to the iterators: - The initialization of the iterator can be virtualized such that implementations can plug in their own CPU specific get_scanline() and next_line() functions. - If an image is horizontal, it can simply plug in an appropriate get_scanline(). This way we can get rid of the annoying classify() virtual function. - In general, iterators can remember what they did on the last scanline, so for example a REPEAT_NONE image might reuse the same data for all the empty scanlines generated by the zero-extension. - More detailed information can be passed to iterator, allowing more specialized fetchers to be used. - We can fix the bug where destination filters and transformations are not currently being ignored as they should be. However, this initial implementation is not optimized at all. We lose several existing optimizations: - The ability to composite directly in the destination - The ability to only fetch one scanline for horizontal images - The ability to avoid fetching the src and mask for the CLEAR operator Later patches will re-introduce these optimizations. --- pixman/pixman-general.c | 287 +++ 1 files changed, 140 insertions(+), 147 deletions(-) diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 8130f16..05d97cc 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -39,6 +39,112 @@ #include pixman-combine32.h #include pixman-private.h +typedef struct pixman_iter_t pixman_iter_t; +typedef enum +{ +ITER_NARROW= (1 0), +ITER_WRITE = (1 1) +} iter_flags_t; + +struct pixman_iter_t +{ +uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask); +void (* next_line)(pixman_iter_t *iter); + +pixman_image_t *image; +uint32_t * buffer; +int x, y; +int width; +}; + +static uint32_t * +get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) +{ +return NULL; +} + +static uint32_t * +get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ +_pixman_image_get_scanline_32 ( + iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); + +return iter-buffer; +} + +static uint32_t * +get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ +_pixman_image_get_scanline_64 ( + iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); + +return iter-buffer; +} + +static void +next_line_write_narrow (pixman_iter_t *iter) +{ +_pixman_image_store_scanline_32 ( + iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); +} + +static void +next_line_write_wide (pixman_iter_t *iter) +{ +_pixman_image_store_scanline_64 ( + iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); +} + +static void +next_line_regular (pixman_iter_t *iter) +{ +iter-y++; +} + +static void +next_line_noop (pixman_iter_t *iter) +{ +} + +static void +iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ +iter-image = image; +iter-x = x; +iter-y = y; +iter-width = width; +iter-buffer = (uint32_t *)buffer; + +if (!image) +{ + iter-get_scanline = get_scanline_null; + iter-next_line = next_line_noop; +} +else if ((flags (ITER_NARROW | ITER_WRITE)) == (ITER_NARROW | ITER_WRITE)) +{ + iter-get_scanline = get_scanline_narrow; + iter-next_line = next_line_write_narrow; +} +else if (flags ITER_WRITE) +{ + iter-get_scanline = get_scanline_wide; + iter-next_line = next_line_write_wide; +} +else +{ + if (flags ITER_NARROW) + iter-get_scanline = get_scanline_narrow; + else + iter-get_scanline = get_scanline_wide; + + iter-next_line = next_line_regular; +} +} + #define SCANLINE_BUFFER_LENGTH 8192 static void @@ -59,21 +165,25 @@ general_composite_rect (pixman_implementation_t *imp, uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8]; uint8_t
[Pixman] [PATCH 10/18] Move get_scanline_32/64 to the bits part of the image struct.
From: Søren Sandmann Pedersen s...@redhat.com At this point these functions are basically a cache that the bits image uses for its fetchers, so they can be moved to the bits image. With the scanline getters only being initialized in the bits image, the _pixman_image_get_scanline_generic_64 can be moved to pixman-bits-image.c. That gets rid of the final user of _pixman_image_get_scanline_32/64, so these can be deleted. --- pixman/pixman-bits-image.c | 45 +-- pixman/pixman-conical-gradient.c |2 - pixman/pixman-image.c| 62 -- pixman/pixman-linear-gradient.c |2 - pixman/pixman-private.h | 32 ++- pixman/pixman-radial-gradient.c |2 - pixman/pixman-solid-fill.c |2 - 7 files changed, 44 insertions(+), 103 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 15a12da..9cd8b5a 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -35,6 +35,43 @@ #include pixman-private.h #include pixman-combine32.h +/* + * By default, just evaluate the image at 32bpp and expand. Individual image + * types can plug in a better scanline getter if they want to. For example + * we could produce smoother gradients by evaluating them at higher color + * depth, but that's a project for the future. + */ +static void +_pixman_image_get_scanline_generic_64 (pixman_image_t * image, + int x, + int y, + int width, + uint32_t * buffer, + const uint32_t * mask) +{ +uint32_t *mask8 = NULL; + +/* Contract the mask image, if one exists, so that the 32-bit fetch + * function can use it. + */ +if (mask) +{ + mask8 = pixman_malloc_ab (width, sizeof(uint32_t)); + if (!mask8) + return; + + pixman_contract (mask8, (uint64_t *)mask, width); +} + +/* Fetch the source image into the first half of buffer. */ +image-bits.get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8); + +/* Expand from 32bpp to 64bpp in place. */ +pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width); + +free (mask8); +} + /* Fetch functions */ static force_inline uint32_t @@ -1300,8 +1337,8 @@ bits_image_property_changed (pixman_image_t *image) if ((info-format == format || info-format == PIXMAN_any) (info-flags flags) == info-flags) { - image-common.get_scanline_32 = info-fetch_32; - image-common.get_scanline_64 = info-fetch_64; + image-bits.get_scanline_32 = info-fetch_32; + image-bits.get_scanline_64 = info-fetch_64; break; } @@ -1312,7 +1349,7 @@ bits_image_property_changed (pixman_image_t *image) static uint32_t * get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) { -iter-image-common.get_scanline_32 ( +iter-image-bits.get_scanline_32 ( iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); return iter-buffer; @@ -1321,7 +1358,7 @@ get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) static uint32_t * get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { -iter-image-common.get_scanline_64 ( +iter-image-bits.get_scanline_64 ( iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); return iter-buffer; diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c index 960ef9d..7d16b89 100644 --- a/pixman/pixman-conical-gradient.c +++ b/pixman/pixman-conical-gradient.c @@ -159,8 +159,6 @@ conical_gradient_get_scanline_32 (pixman_image_t *image, static void conical_gradient_property_changed (pixman_image_t *image) { -image-common.get_scanline_32 = conical_gradient_get_scanline_32; -image-common.get_scanline_64 = _pixman_image_get_scanline_generic_64; } static uint32_t * diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 3e17000..566a28f 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -50,43 +50,6 @@ _pixman_init_gradient (gradient_t * gradient, return TRUE; } -/* - * By default, just evaluate the image at 32bpp and expand. Individual image - * types can plug in a better scanline getter if they want to. For example - * we could produce smoother gradients by evaluating them at higher color - * depth, but that's a project for the future. - */ -void -_pixman_image_get_scanline_generic_64 (pixman_image_t * image, - int x, - int y, - int width, - uint32_t * buffer
[Pixman] [PATCH 02/18] Move initialization of iterators for bits images to pixman-bits-image.c
From: Søren Sandmann Pedersen s...@redhat.com pixman_iter_t is now defined in pixman-private.h, and iterators for bits images are being. The function next_line_regular() is needed in both pixman-general.c and pixman-bits-image.c, so rename it to _pixman_iter_next_line_regular() and move it to pixman-utils. --- pixman/pixman-bits-image.c | 59 pixman/pixman-general.c| 51 +++--- pixman/pixman-private.h| 26 +++ pixman/pixman-utils.c |6 4 files changed, 95 insertions(+), 47 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index ff2dde3..33b908a 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -1349,6 +1349,65 @@ bits_image_property_changed (pixman_image_t *image) } static uint32_t * +get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ +iter-image-common.get_scanline_32 ( + iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); + +return iter-buffer; +} + +static uint32_t * +get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ +iter-image-common.get_scanline_64 ( + iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); + +return iter-buffer; +} + +static void +next_line_write_narrow (pixman_iter_t *iter) +{ +_pixman_image_store_scanline_32 ( + iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); +} + +static void +next_line_write_wide (pixman_iter_t *iter) +{ +_pixman_image_store_scanline_64 ( + iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); +} + +void +_pixman_bits_image_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ +if ((flags (ITER_NARROW | ITER_WRITE)) == (ITER_NARROW | ITER_WRITE)) +{ + iter-get_scanline = get_scanline_narrow; + iter-next_line = next_line_write_narrow; +} +else if (flags ITER_WRITE) +{ + iter-get_scanline = get_scanline_wide; + iter-next_line = next_line_write_wide; +} +else +{ + if (flags ITER_NARROW) + iter-get_scanline = get_scanline_narrow; + else + iter-get_scanline = get_scanline_wide; + + iter-next_line = _pixman_iter_next_line_regular; +} +} + +static uint32_t * create_bits (pixman_format_code_t format, int width, int height, diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 05d97cc..a66298a 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -39,24 +39,6 @@ #include pixman-combine32.h #include pixman-private.h -typedef struct pixman_iter_t pixman_iter_t; -typedef enum -{ -ITER_NARROW= (1 0), -ITER_WRITE = (1 1) -} iter_flags_t; - -struct pixman_iter_t -{ -uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask); -void (* next_line)(pixman_iter_t *iter); - -pixman_image_t *image; -uint32_t * buffer; -int x, y; -int width; -}; - static uint32_t * get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) { @@ -82,26 +64,6 @@ get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) } static void -next_line_write_narrow (pixman_iter_t *iter) -{ -_pixman_image_store_scanline_32 ( - iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); -} - -static void -next_line_write_wide (pixman_iter_t *iter) -{ -_pixman_image_store_scanline_64 ( - iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); -} - -static void -next_line_regular (pixman_iter_t *iter) -{ -iter-y++; -} - -static void next_line_noop (pixman_iter_t *iter) { } @@ -124,15 +86,10 @@ iter_init (pixman_implementation_t *imp, iter-get_scanline = get_scanline_null; iter-next_line = next_line_noop; } -else if ((flags (ITER_NARROW | ITER_WRITE)) == (ITER_NARROW | ITER_WRITE)) -{ - iter-get_scanline = get_scanline_narrow; - iter-next_line = next_line_write_narrow; -} -else if (flags ITER_WRITE) +else if (image-type == BITS) { - iter-get_scanline = get_scanline_wide; - iter-next_line = next_line_write_wide; + _pixman_bits_image_iter_init ( + image, iter, x, y, width, height, buffer, flags); } else { @@ -141,7 +98,7 @@ iter_init (pixman_implementation_t *imp, else iter-get_scanline = get_scanline_wide; - iter-next_line = next_line_regular; + iter-next_line = _pixman_iter_next_line_regular; } } diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 383748a..5e441fe 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -193,10 +193,34
[Pixman] [PATCH 04/18] Add _pixman_linear_gradient_iter_init().
From: Søren Sandmann Pedersen s...@redhat.com Call it from pixman-general.c to initialize linear gradient iterators. --- pixman/pixman-general.c |5 pixman/pixman-linear-gradient.c | 43 +++ pixman/pixman-private.h |5 3 files changed, 53 insertions(+), 0 deletions(-) diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index a66298a..7ff2dd2 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -86,6 +86,11 @@ iter_init (pixman_implementation_t *imp, iter-get_scanline = get_scanline_null; iter-next_line = next_line_noop; } +else if (image-type == LINEAR) +{ + _pixman_linear_gradient_iter_init ( + image, iter, x, y, width, height, buffer, flags); +} else if (image-type == BITS) { _pixman_bits_image_iter_init ( diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c index 1547882..a2de693 100644 --- a/pixman/pixman-linear-gradient.c +++ b/pixman/pixman-linear-gradient.c @@ -226,6 +226,49 @@ linear_gradient_property_changed (pixman_image_t *image) image-common.get_scanline_64 = _pixman_image_get_scanline_generic_64; } +static uint32_t * +linear_gradient_get_scanline_narrow (pixman_iter_t *iter, +const uint32_t *mask) +{ +pixman_image_t *image = iter-image; +int x = iter-x; +int y = iter-y; +int width = iter-width; +uint32_t * buffer = iter-buffer; + +linear_gradient_get_scanline_32 (image, x, y, width, buffer, mask); + +return iter-buffer; +} + +static uint32_t * +linear_gradient_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ +uint32_t *buffer = linear_gradient_get_scanline_narrow (iter, NULL); + +pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter-width); + +return buffer; +} + +void +_pixman_linear_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, + int y, + int width, + int height, + uint8_t*buffer, + iter_flags_tflags) +{ +if (flags ITER_NARROW) + iter-get_scanline = linear_gradient_get_scanline_narrow; +else + iter-get_scanline = linear_gradient_get_scanline_wide; + +iter-next_line = _pixman_iter_next_line_regular; +} + PIXMAN_EXPORT pixman_image_t * pixman_image_create_linear_gradient (pixman_point_fixed_t *p1, pixman_point_fixed_t *p2, diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 0511ade..0be38ed 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -219,6 +219,11 @@ _pixman_bits_image_iter_init (pixman_image_t *image, pixman_iter_t *iter, int x, int y, int width, int height, uint8_t *buffer, iter_flags_t flags); +void +_pixman_linear_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); void _pixman_image_get_scanline_generic_64 (pixman_image_t *image, -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 05/18] Add _pixman_solid_fill_iter_init() and call it from pixman-general.c
From: Søren Sandmann Pedersen s...@redhat.com Also move next_line_noop() to pixman-utils.c since it is used in both pixman-solid-fill.c and pixman-general.c --- pixman/pixman-general.c| 12 ++-- pixman/pixman-private.h| 12 pixman/pixman-solid-fill.c | 21 + pixman/pixman-utils.c | 11 +++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 7ff2dd2..a2697ef 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -64,11 +64,6 @@ get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) } static void -next_line_noop (pixman_iter_t *iter) -{ -} - -static void iter_init (pixman_implementation_t *imp, pixman_iter_t *iter, pixman_image_t *image, @@ -84,7 +79,12 @@ iter_init (pixman_implementation_t *imp, if (!image) { iter-get_scanline = get_scanline_null; - iter-next_line = next_line_noop; + iter-next_line = _pixman_iter_next_line_noop; +} +else if (image-type == SOLID) +{ + _pixman_solid_fill_iter_init ( + image, iter, x, y, width, height, buffer, flags); } else if (image-type == LINEAR) { diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 0be38ed..d22f242 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -220,6 +220,12 @@ _pixman_bits_image_iter_init (pixman_image_t *image, int x, int y, int width, int height, uint8_t *buffer, iter_flags_t flags); void +_pixman_solid_fill_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter, int x, int y, int width, int height, @@ -541,6 +547,12 @@ _pixman_choose_implementation (void); void _pixman_iter_next_line_regular (pixman_iter_t *iter); +void +_pixman_iter_next_line_noop (pixman_iter_t *iter); + +uint32_t * +_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask); + /* These formats all have depth 0, so they * will never clash with any real ones */ diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c index 1d911e9..2f06f58 100644 --- a/pixman/pixman-solid-fill.c +++ b/pixman/pixman-solid-fill.c @@ -76,6 +76,27 @@ solid_fill_property_changed (pixman_image_t *image) image-common.get_scanline_64 = solid_fill_get_scanline_64; } +void +_pixman_solid_fill_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ +if (flags ITER_NARROW) +{ + solid_fill_get_scanline_32 ( + image, x, y, width, (uint32_t *)buffer, NULL); +} +else +{ + solid_fill_get_scanline_64 ( + image, x, y, width, (uint32_t *)buffer, NULL); +} + +iter-get_scanline = _pixman_iter_get_scanline_noop; +iter-next_line = _pixman_iter_next_line_noop; +} + static uint32_t color_to_uint32 (const pixman_color_t *color) { diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index 630c870..09e4ee0 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -173,6 +173,17 @@ _pixman_iter_next_line_regular (pixman_iter_t *iter) iter-y++; } +void +_pixman_iter_next_line_noop (pixman_iter_t *iter) +{ +} + +uint32_t * +_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask) +{ +return iter-buffer; +} + #define N_TMP_BOXES (16) pixman_bool_t -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 16/18] Skip fetching pixels when possible
From: Søren Sandmann Pedersen s...@redhat.com Add two new iterator flags, ITER_IGNORE_ALPHA and ITER_IGNORE_RGB that are set when the alpha and rgb values are not needed. If both are set, then we can skip fetching entirely and just use _pixman_iter_get_scanline_noop. --- pixman/pixman-bits-image.c | 11 +- pixman/pixman-general.c| 74 +++ pixman/pixman-implementation.c |7 pixman/pixman-private.h|4 ++- 4 files changed, 71 insertions(+), 25 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index df8d56e..7d588a9 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -1444,7 +1444,16 @@ _pixman_bits_image_iter_init (pixman_image_t *image, } else { - iter-get_scanline = get_scanline_narrow; + if ((flags (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == +(ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) + { + iter-get_scanline = _pixman_iter_get_scanline_noop; + } + else + { + iter-get_scanline = get_scanline_narrow; + } + iter-next_line = next_line_write_narrow; } } diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 84b52c2..25d1fe4 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -83,6 +83,34 @@ general_iter_init (pixman_implementation_t *imp, } } +typedef struct op_info_t op_info_t; +struct op_info_t +{ +uint8_t src, dst; +}; + +#define ITER_IGNORE_BOTH \ +(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA) + +static const op_info_t op_flags[PIXMAN_N_OPERATORS] = +{ +/* Src Dst */ +{ ITER_IGNORE_BOTH, ITER_IGNORE_BOTH }, /* CLEAR */ +{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_BOTH }, /* SRC */ +{ ITER_IGNORE_BOTH, ITER_LOCALIZED_ALPHA }, /* DST */ +{ 0, ITER_LOCALIZED_ALPHA }, /* OVER */ +{ ITER_LOCALIZED_ALPHA, 0 }, /* OVER_REVERSE */ +{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* IN */ +{ ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* IN_REVERSE */ +{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* OUT */ +{ ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* OUT_REVERSE */ +{ 0, 0 }, /* ATOP */ +{ 0, 0 }, /* ATOP_REVERSE */ +{ 0, 0 }, /* XOR */ +{ ITER_LOCALIZED_ALPHA, ITER_LOCALIZED_ALPHA }, /* ADD */ +{ 0, 0 }, /* SATURATE */ +}; + #define SCANLINE_BUFFER_LENGTH 8192 static void @@ -106,7 +134,7 @@ general_composite_rect (pixman_implementation_t *imp, pixman_iter_t src_iter, mask_iter, dest_iter; pixman_combine_32_func_t compose; pixman_bool_t component_alpha; -iter_flags_t narrow, dest_flags; +iter_flags_t narrow, src_flags; int Bpp; int i; @@ -135,39 +163,39 @@ general_composite_rect (pixman_implementation_t *imp, mask_buffer = src_buffer + width * Bpp; dest_buffer = mask_buffer + width * Bpp; +/* src iter */ +src_flags = narrow | op_flags[op].src; + _pixman_implementation_iter_init (imp-toplevel, src_iter, src, src_x, src_y, width, height, - src_buffer, narrow); - -_pixman_implementation_iter_init (imp-toplevel, mask_iter, mask, - mask_x, mask_y, width, height, - mask_buffer, narrow); - -if (op == PIXMAN_OP_CLEAR || - op == PIXMAN_OP_SRC || - op == PIXMAN_OP_DST || - op == PIXMAN_OP_OVER|| - op == PIXMAN_OP_IN_REVERSE || - op == PIXMAN_OP_OUT_REVERSE || - op == PIXMAN_OP_ADD) -{ - dest_flags = narrow | ITER_WRITE | ITER_LOCALIZED_ALPHA; -} -else + src_buffer, src_flags); + +/* mask iter */ +if ((src_flags (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == + (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) { - dest_flags = narrow | ITER_WRITE; + /* If it doesn't matter what the source is, then it doesn't matter +* what the mask is +*/ + mask = NULL; } -_pixman_implementation_iter_init (imp-toplevel, dest_iter, dest, - dest_x, dest_y, width, height, - dest_buffer, dest_flags); - component_alpha = mask mask-common.type == BITS mask-common.component_alpha PIXMAN_FORMAT_RGB (mask-bits.format); +_pixman_implementation_iter_init ( + imp
[Pixman] [PATCH 18/18] Fix destination fetching.
From: Søren Sandmann Pedersen s...@redhat.com When fetching from destinations, we need to ignore transformations, repeat and filtering. Currently we don't ignore them, which means all kinds of bad things can happen. This bug fixes this problem by separating the concepts of source and destination iterator instead of using the ITER_WRITE flag to indicate which is which. Apart from making it simple for destination iterators to plug in alternate fetchers, this also allows a small optimization where source iterators no longer have a separate next line call; instead they are supposed to prepare themselves for the next line in the get_scanline call. Destination iterators do now have a separate write_back call that is supposed to write the pixels back to the destination and prepare the iterator for the next scanline. --- pixman/pixman-bits-image.c | 107 ++--- pixman/pixman-conical-gradient.c |3 +- pixman/pixman-general.c | 59 ++-- pixman/pixman-image.c|2 +- pixman/pixman-implementation.c | 77 +++- pixman/pixman-linear-gradient.c |4 +- pixman/pixman-private.h | 60 - pixman/pixman-radial-gradient.c |3 +- pixman/pixman-solid-fill.c |1 - pixman/pixman-utils.c| 11 10 files changed, 208 insertions(+), 119 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 7d588a9..4d8c1dc 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -1350,7 +1350,7 @@ static uint32_t * get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) { iter-image-bits.get_scanline_32 ( - iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); + iter-image, iter-x, iter-y++, iter-width, iter-buffer, mask); return iter-buffer; } @@ -1359,13 +1359,59 @@ static uint32_t * get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { iter-image-bits.get_scanline_64 ( - iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); + iter-image, iter-x, iter-y++, iter-width, iter-buffer, mask); + +return iter-buffer; +} + +static uint32_t * +dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ +pixman_image_t *image = iter-image; +int x = iter-x; +int y = iter-y; +int width = iter-width; +uint32_t * buffer = iter-buffer; + +image-bits.fetch_scanline_32 (image, x, y, width, buffer, mask); +if (image-common.alpha_map) +{ + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; + + image-common.alpha_map-fetch_scanline_32 ( + (pixman_image_t *)image-common.alpha_map, + x, y, width, buffer, mask); +} + +return iter-buffer; +} + +static uint32_t * +dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ +bits_image_t * image = iter-image-bits; +int x = iter-x; +int y = iter-y; +int width = iter-width; +uint32_t * buffer = iter-buffer; + +image-fetch_scanline_64 ( + (pixman_image_t *)image, x, y, width, buffer, mask); +if (image-common.alpha_map) +{ + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; + + image-common.alpha_map-fetch_scanline_64 ( + (pixman_image_t *)image-common.alpha_map, x, y, width, buffer, mask); +} return iter-buffer; } static void -next_line_write_narrow (pixman_iter_t *iter) +write_back_narrow (pixman_iter_t *iter) { bits_image_t * image = iter-image-bits; int x = iter-x; @@ -1388,7 +1434,7 @@ next_line_write_narrow (pixman_iter_t *iter) } static void -next_line_write_wide (pixman_iter_t *iter) +write_back_wide (pixman_iter_t *iter) { bits_image_t * image = iter-image-bits; int x = iter-x; @@ -1410,25 +1456,19 @@ next_line_write_wide (pixman_iter_t *iter) iter-y++; } -static uint32_t * -get_scanline_direct_write (pixman_iter_t *iter, const uint32_t *mask) -{ -return iter-buffer; -} - static void -next_line_direct_write (pixman_iter_t *iter) +write_back_direct (pixman_iter_t *iter) { iter-buffer += iter-image-bits.rowstride; } void -_pixman_bits_image_iter_init (pixman_image_t *image, - pixman_iter_t *iter, - int x, int y, int width, int height, - uint8_t *buffer, iter_flags_t flags) +_pixman_bits_image_dest_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) { -if ((flags (ITER_NARROW | ITER_WRITE)) == (ITER_NARROW | ITER_WRITE)) +if (flags
[Pixman] [PATCH 03/15] Eliminate the _pixman_image_store_scanline_32/64 functions.
From: Søren Sandmann Pedersen s...@redhat.com They were only called from next_line_write_narrow/wide, so they could simply be absorbed into those functions. --- pixman/pixman-bits-image.c | 79 pixman/pixman-private.h| 17 - 2 files changed, 36 insertions(+), 60 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index e0a6645..0c5f4e4 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -35,45 +35,6 @@ #include pixman-private.h #include pixman-combine32.h -/* Store functions */ -void -_pixman_image_store_scanline_32 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ -image-store_scanline_32 (image, x, y, width, buffer); - -if (image-common.alpha_map) -{ - x -= image-common.alpha_origin_x; - y -= image-common.alpha_origin_y; - - image-common.alpha_map-store_scanline_32 ( - image-common.alpha_map, x, y, width, buffer); -} -} - -void -_pixman_image_store_scanline_64 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ -image-store_scanline_64 (image, x, y, width, buffer); - -if (image-common.alpha_map) -{ - x -= image-common.alpha_origin_x; - y -= image-common.alpha_origin_y; - - image-common.alpha_map-store_scanline_64 ( - image-common.alpha_map, x, y, width, buffer); -} -} - /* Fetch functions */ static force_inline uint32_t @@ -1399,15 +1360,47 @@ dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) static void dest_write_back_narrow (pixman_iter_t *iter) { -_pixman_image_store_scanline_32 ( - iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); +bits_image_t * image = iter-image-bits; +int x = iter-x; +int y = iter-y; +int width = iter-width; +const uint32_t *buffer = iter-buffer; + +image-store_scanline_32 (image, x, y, width, buffer); + +if (image-common.alpha_map) +{ + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; + + image-common.alpha_map-store_scanline_32 ( + image-common.alpha_map, x, y, width, buffer); +} + +iter-y++; } static void dest_write_back_wide (pixman_iter_t *iter) { -_pixman_image_store_scanline_64 ( - iter-image-bits, iter-x, iter-y++, iter-width, iter-buffer); +bits_image_t * image = iter-image-bits; +int x = iter-x; +int y = iter-y; +int width = iter-width; +const uint32_t *buffer = iter-buffer; + +image-store_scanline_64 (image, x, y, width, buffer); + +if (image-common.alpha_map) +{ + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; + + image-common.alpha_map-store_scanline_64 ( + image-common.alpha_map, x, y, width, buffer); +} + +iter-y++; } void diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 853fb5a..d9d19ce 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -258,23 +258,6 @@ _pixman_image_get_scanline_64 (pixman_image_t *image, uint32_t * buffer, const uint32_t *unused); -void -_pixman_image_store_scanline_32 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer); - -/* Even though the type of buffer is uint32_t *, the function - * actually expects a uint64_t *buffer. - */ -void -_pixman_image_store_scanline_64 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer); - pixman_image_t * _pixman_image_allocate (void); -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 05/15] Virtualize iterator initialization
From: Søren Sandmann Pedersen s...@redhat.com Make src_iter_init() and dest_iter_init() virtual methods in the implementation struct. This allows individual implementations to plug in their own CPU specific scanline fetchers. --- pixman/pixman-general.c| 52 +++ pixman/pixman-implementation.c | 76 +++- pixman/pixman-private.h| 35 ++- 3 files changed, 131 insertions(+), 32 deletions(-) diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 4b837fa..e2f1dc3 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -39,18 +39,12 @@ #include pixman-combine32.h #include pixman-private.h -static uint32_t * -src_get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) -{ -return NULL; -} - static void -src_iter_init (pixman_implementation_t *imp, - pixman_iter_t *iter, - pixman_image_t *image, - int x, int y, int width, int height, - uint8_t *buffer, iter_flags_t flags) +general_src_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) { iter-image = image; iter-x = x; @@ -58,11 +52,7 @@ src_iter_init (pixman_implementation_t *imp, iter-width = width; iter-buffer = (uint32_t *)buffer; -if (!image) -{ - iter-get_scanline = src_get_scanline_null; -} -else if (image-type == SOLID) +if (image-type == SOLID) { _pixman_solid_fill_iter_init ( image, iter, x, y, width, height, buffer, flags); @@ -94,11 +84,11 @@ src_iter_init (pixman_implementation_t *imp, } static void -dest_iter_init (pixman_implementation_t *imp, - pixman_iter_t *iter, - pixman_image_t *image, - int x, int y, int width, int height, - uint8_t *buffer, iter_flags_t flags) +general_dest_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) { iter-image = image; iter-x = x; @@ -169,17 +159,17 @@ general_composite_rect (pixman_implementation_t *imp, mask_buffer = src_buffer + width * Bpp; dest_buffer = mask_buffer + width * Bpp; -src_iter_init (imp-toplevel, src_iter, src, - src_x, src_y, width, height, - src_buffer, narrow); +_pixman_implementation_src_iter_init (imp-toplevel, src_iter, src, + src_x, src_y, width, height, + src_buffer, narrow); -src_iter_init (imp-toplevel, mask_iter, mask, - mask_x, mask_y, width, height, - mask_buffer, narrow); +_pixman_implementation_src_iter_init (imp-toplevel, mask_iter, mask, + mask_x, mask_y, width, height, + mask_buffer, narrow); -dest_iter_init (imp-toplevel, dest_iter, dest, - dest_x, dest_y, width, height, - dest_buffer, narrow); +_pixman_implementation_dest_iter_init (imp-toplevel, dest_iter, dest, + dest_x, dest_y, width, height, + dest_buffer, narrow); component_alpha = mask @@ -272,6 +262,8 @@ _pixman_implementation_create_general (void) imp-blt = general_blt; imp-fill = general_fill; +imp-src_iter_init = general_src_iter_init; +imp-dest_iter_init = general_dest_iter_init; return imp; } diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c index bc3749e..e633432 100644 --- a/pixman/pixman-implementation.c +++ b/pixman/pixman-implementation.c @@ -111,6 +111,36 @@ delegate_fill (pixman_implementation_t *imp, imp-delegate, bits, stride, bpp, x, y, width, height, xor); } +static void +delegate_src_iter_init (pixman_implementation_t *imp, + pixman_iter_t * iter, + pixman_image_t * image, + int x, + int y, + int width, + int height, + uint8_t *buffer, + iter_flags_t flags) +{ +_pixman_implementation_src_iter_init ( + imp-delegate, iter, image, x, y, width, height, buffer, flags); +} + +static void +delegate_dest_iter_init (pixman_implementation_t *imp, +pixman_iter_t
[Pixman] [PATCH 06/15] Use an iterator in pixman_image_get_solid().
From: Søren Sandmann Pedersen s...@redhat.com This is a step towards getting rid of the _pixman_image_get_scanline_32/64() functions. --- pixman/pixman-arm-common.h |9 ++--- pixman/pixman-fast-path.c | 22 +++--- pixman/pixman-image.c | 12 +--- pixman/pixman-mmx.c| 22 +++--- pixman/pixman-private.h|9 + pixman/pixman-sse2.c | 30 +++--- 6 files changed, 57 insertions(+), 47 deletions(-) diff --git a/pixman/pixman-arm-common.h b/pixman/pixman-arm-common.h index 66f448d..372e9f9 100644 --- a/pixman/pixman-arm-common.h +++ b/pixman/pixman-arm-common.h @@ -118,7 +118,8 @@ cputype##_composite_##name (pixman_implementation_t *imp, \ int32_tdst_stride; \ uint32_t src; \ \ -src = _pixman_image_get_solid (src_image, dst_image-bits.format); \ +src = _pixman_image_get_solid (\ + imp, src_image, dst_image-bits.format);\ \ if ((flags SKIP_ZERO_SRC) src == 0)\ return; \ @@ -164,7 +165,8 @@ cputype##_composite_##name (pixman_implementation_t *imp, \ int32_tdst_stride, mask_stride; \ uint32_t src; \ \ -src = _pixman_image_get_solid (src_image, dst_image-bits.format); \ +src = _pixman_image_get_solid (\ + imp, src_image, dst_image-bits.format);\ \ if ((flags SKIP_ZERO_SRC) src == 0)\ return; \ @@ -212,7 +214,8 @@ cputype##_composite_##name (pixman_implementation_t *imp, \ int32_tdst_stride, src_stride; \ uint32_t mask;\ \ -mask = _pixman_image_get_solid (mask_image, dst_image-bits.format);\ +mask = _pixman_image_get_solid ( \ + imp, mask_image, dst_image-bits.format); \ \ if ((flags SKIP_ZERO_MASK) mask == 0) \ return; \ diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index 37dfbae..1d12330 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -188,7 +188,7 @@ fast_composite_in_n_8_8 (pixman_implementation_t *imp, int32_t w; uint16_t t; -src = _pixman_image_get_solid (src_image, dest_image-bits.format); +src = _pixman_image_get_solid (imp, src_image, dest_image-bits.format); srca = src 24; @@ -312,7 +312,7 @@ fast_composite_over_n_8_ (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; -src = _pixman_image_get_solid (src_image, dst_image-bits.format); +src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); srca = src 24; if (src == 0) @@ -370,7 +370,7 @@ fast_composite_add_n___ca (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; -src = _pixman_image_get_solid (src_image, dst_image-bits.format); +src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); srca = src 24; if (src == 0) @@ -427,7 +427,7 @@ fast_composite_over_n___ca (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; -src = _pixman_image_get_solid (src_image, dst_image-bits.format); +src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); srca = src 24; if (src == 0) @@ -494,7 +494,7 @@ fast_composite_over_n_8_0888 (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; -src = _pixman_image_get_solid (src_image, dst_image-bits.format); +src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); srca = src 24; if (src == 0) @@ -559,7 +559,7 @@ fast_composite_over_n_8_0565 (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; -src = _pixman_image_get_solid (src_image, dst_image-bits.format); +src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); srca
[Pixman] [PATCH 14/15] Turn on testing for destination transformation
From: Søren Sandmann Pedersen s...@redhat.com --- test/alphamap.c | 11 --- 1 files changed, 4 insertions(+), 7 deletions(-) diff --git a/test/alphamap.c b/test/alphamap.c index 9fb8969..554b309 100644 --- a/test/alphamap.c +++ b/test/alphamap.c @@ -165,20 +165,17 @@ run_test (int s, int d, int sa, int da, int soff, int doff) orig_dst = create_image (df, daf, doff, doff); dst = create_image (df, daf, doff, doff); -/* Transformations on destinations should be ignored, so just set some - * random one. +/* Transformations, repeats and filters on destinations should be ignored, + * so just set some random ones. */ pixman_transform_init_identity (t1); pixman_transform_scale (t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11)); pixman_transform_rotate (t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11)); pixman_transform_translate (t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17)); -#if 0 -/* Unfortunately, this is actually broken at the moment, so we can't - * actually turn it on - */ pixman_image_set_transform (dst, t1); -#endif +pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0); +pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT); pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 15/15] Fix destination fetching.
From: Søren Sandmann Pedersen s...@redhat.com When fetching from destinations, we need to ignore transformations, repeat and filtering. Currently we don't ignore them, which means all kinds of bad things can happen. This bug fixes this problem by directly calling the scanline fetchers for destinations instead of going through the full get_scanline_32/64(). --- pixman/pixman-bits-image.c | 36 1 files changed, 32 insertions(+), 4 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index f379bb0..6c43b97 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -1379,8 +1379,22 @@ _pixman_bits_image_src_iter_init (pixman_image_t *image, static uint32_t * dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) { -iter-image-bits.get_scanline_32 ( - iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); +pixman_image_t *image = iter-image; +int x = iter-x; +int y = iter-y; +int width = iter-width; +uint32_t * buffer = iter-buffer; + +image-bits.fetch_scanline_32 (image, x, y, width, buffer, mask); +if (image-common.alpha_map) +{ + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; + + image-common.alpha_map-fetch_scanline_32 ( + (pixman_image_t *)image-common.alpha_map, + x, y, width, buffer, mask); +} return iter-buffer; } @@ -1388,8 +1402,22 @@ dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) static uint32_t * dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { -iter-image-bits.get_scanline_64 ( - iter-image, iter-x, iter-y, iter-width, iter-buffer, mask); +bits_image_t * image = iter-image-bits; +int x = iter-x; +int y = iter-y; +int width = iter-width; +uint32_t * buffer = iter-buffer; + +image-fetch_scanline_64 ( + (pixman_image_t *)image, x, y, width, buffer, mask); +if (image-common.alpha_map) +{ + x -= image-common.alpha_origin_x; + y -= image-common.alpha_origin_y; + + image-common.alpha_map-fetch_scanline_64 ( + (pixman_image_t *)image-common.alpha_map, x, y, width, buffer, mask); +} return iter-buffer; } -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Move fallback decisions from implementations into pixman-cpu.c.
From: Søren Sandmann Pedersen s...@redhat.com Instead of having each individual implementation decide which fallback to use, move it into pixman-cpu.c, where a more global decision can be made. This is accomplished by adding a fallback argument to all the pixman_implementation_create_*() implementations, and then in _pixman_choose_implementation() pass in the desired fallback. --- pixman/pixman-arm-neon.c |7 +-- pixman/pixman-arm-simd.c |5 ++--- pixman/pixman-cpu.c | 30 +++--- pixman/pixman-fast-path.c |5 ++--- pixman/pixman-mmx.c |5 ++--- pixman/pixman-private.h | 12 ++-- pixman/pixman-sse2.c |7 +-- pixman/pixman-vmx.c |5 ++--- 8 files changed, 35 insertions(+), 41 deletions(-) diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c index c28c481..7d6c837 100644 --- a/pixman/pixman-arm-neon.c +++ b/pixman/pixman-arm-neon.c @@ -414,13 +414,8 @@ BIND_COMBINE_U (add) BIND_COMBINE_U (out_reverse) pixman_implementation_t * -_pixman_implementation_create_arm_neon (void) +_pixman_implementation_create_arm_neon (pixman_implementation_t *fallback) { -#ifdef USE_ARM_SIMD -pixman_implementation_t *fallback = _pixman_implementation_create_arm_simd (); -#else -pixman_implementation_t *fallback = _pixman_implementation_create_fast_path (); -#endif pixman_implementation_t *imp = _pixman_implementation_create (fallback, arm_neon_fast_paths); diff --git a/pixman/pixman-arm-simd.c b/pixman/pixman-arm-simd.c index dc2f471..6bbc109 100644 --- a/pixman/pixman-arm-simd.c +++ b/pixman/pixman-arm-simd.c @@ -415,10 +415,9 @@ static const pixman_fast_path_t arm_simd_fast_paths[] = }; pixman_implementation_t * -_pixman_implementation_create_arm_simd (void) +_pixman_implementation_create_arm_simd (pixman_implementation_t *fallback) { -pixman_implementation_t *general = _pixman_implementation_create_fast_path (); -pixman_implementation_t *imp = _pixman_implementation_create (general, arm_simd_fast_paths); +pixman_implementation_t *imp = _pixman_implementation_create (fallback, arm_simd_fast_paths); return imp; } diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c index 70253d1..0e14ecb 100644 --- a/pixman/pixman-cpu.c +++ b/pixman/pixman-cpu.c @@ -576,28 +576,36 @@ pixman_have_sse2 (void) pixman_implementation_t * _pixman_choose_implementation (void) { -#ifdef USE_SSE2 -if (pixman_have_sse2 ()) - return _pixman_implementation_create_sse2 (); -#endif +pixman_implementation_t *imp; + +imp = _pixman_implementation_create_general(); +imp = _pixman_implementation_create_fast_path (imp); + #ifdef USE_MMX if (pixman_have_mmx ()) - return _pixman_implementation_create_mmx (); + imp = _pixman_implementation_create_mmx (imp); #endif -#ifdef USE_ARM_NEON -if (pixman_have_arm_neon ()) - return _pixman_implementation_create_arm_neon (); +#ifdef USE_SSE2 +if (pixman_have_sse2 ()) + imp = _pixman_implementation_create_sse2 (imp); #endif + #ifdef USE_ARM_SIMD if (pixman_have_arm_simd ()) - return _pixman_implementation_create_arm_simd (); + imp = _pixman_implementation_create_arm_simd (imp); +#endif + +#ifdef USE_ARM_NEON +if (pixman_have_arm_neon ()) + imp = _pixman_implementation_create_arm_neon (imp); #endif + #ifdef USE_VMX if (pixman_have_vmx ()) - return _pixman_implementation_create_vmx (); + imp = _pixman_implementation_create_vmx (imp); #endif -return _pixman_implementation_create_fast_path (); +return imp; } diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index 868175f..8c71371 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1926,10 +1926,9 @@ fast_path_fill (pixman_implementation_t *imp, } pixman_implementation_t * -_pixman_implementation_create_fast_path (void) +_pixman_implementation_create_fast_path (pixman_implementation_t *fallback) { -pixman_implementation_t *general = _pixman_implementation_create_general (); -pixman_implementation_t *imp = _pixman_implementation_create (general, c_fast_paths); +pixman_implementation_t *imp = _pixman_implementation_create (fallback, c_fast_paths); imp-fill = fast_path_fill; diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c index 6daa364..0272347 100644 --- a/pixman/pixman-mmx.c +++ b/pixman/pixman-mmx.c @@ -3340,10 +3340,9 @@ mmx_fill (pixman_implementation_t *imp, } pixman_implementation_t * -_pixman_implementation_create_mmx (void) +_pixman_implementation_create_mmx (pixman_implementation_t *fallback) { -pixman_implementation_t *general = _pixman_implementation_create_fast_path (); -pixman_implementation_t *imp = _pixman_implementation_create (general, mmx_fast_paths); +pixman_implementation_t *imp = _pixman_implementation_create (fallback, mmx_fast_paths); imp-combine_32
[Pixman] [PATCH 1/5] Add a test for over_x888_8_0565 in lowlevel_blt_bench().
From: Søren Sandmann Pedersen s...@redhat.com The next few commits will speed this up quite a bit. Current output: --- reference memcpy speed = 2217.5MB/s (554.4MP/s for 32bpp fills) --- over_x888_8_0565 = L1: 54.67 L2: 54.01 M: 52.33 ( 18.88%) HT: 37.19 VT: 35.54 R: 29.40 RT: 13.63 ( 162Kops/s) --- test/lowlevel-blt-bench.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/test/lowlevel-blt-bench.c b/test/lowlevel-blt-bench.c index f7ebb1f..67c845f 100644 --- a/test/lowlevel-blt-bench.c +++ b/test/lowlevel-blt-bench.c @@ -618,6 +618,7 @@ tests_tbl[] = { over_n_1555, PIXMAN_a8r8g8b8,1, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_a1r5g5b5 }, { over__0565,PIXMAN_a8r8g8b8,0, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_r5g6b5 }, { over__x888,PIXMAN_a8r8g8b8,0, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_x8r8g8b8 }, +{ over_x888_8_0565, PIXMAN_x8r8g8b8,0, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_r5g6b5 }, { over_n_8_0565, PIXMAN_a8r8g8b8,1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_r5g6b5 }, { over_n_8_1555, PIXMAN_a8r8g8b8,1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_a1r5g5b5 }, { over_n_8_, PIXMAN_a8r8g8b8,1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_a4r4g4b4 }, -- 1.7.3.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/5] Add SSE2 fetcher for x8r8g8b8
From: Søren Sandmann Pedersen s...@redhat.com New output of lowlevel-blt-bench over_x888_8_0565: over_x888_8_0565 = L1: 55.68 L2: 55.11 M: 52.83 ( 19.04%) HT: 39.62 VT: 37.70 R: 30.88 RT: 14.62 ( 174Kops/s) The fetcher is looked up in a table, so that other fetchers can easily be added. --- pixman/pixman-private.h | 18 ++--- pixman/pixman-sse2.c| 90 +++ 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 664260b..f5d0ba1 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -183,6 +183,9 @@ union pixman_image }; typedef struct pixman_iter_t pixman_iter_t; +typedef uint32_t *(* pixman_iter_get_scanline_t) (pixman_iter_t *iter, const uint32_t *mask); +typedef void (* pixman_iter_write_back_t) (pixman_iter_t *iter); + typedef enum { ITER_NARROW = (1 0), @@ -209,13 +212,16 @@ typedef enum struct pixman_iter_t { -uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask); -void (* write_back) (pixman_iter_t *iter); +pixman_iter_get_scanline_t get_scanline; +pixman_iter_write_back_t write_back; + +pixman_image_t * image; +uint32_t * buffer; +intx, y; +intwidth; -pixman_image_t *image; -uint32_t * buffer; -int x, y; -int width; +uint8_t * bits; +intstride; }; void diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index ae55456..10a3dd0 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -5953,6 +5953,94 @@ sse2_fill (pixman_implementation_t *imp, return TRUE; } +static uint32_t * +sse2_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask) +{ +int w = iter-width; +__m128i ff00 = mask_ff00; +uint32_t *dst = iter-buffer; +uint32_t *src = (uint32_t *)iter-bits; + +iter-bits += iter-stride; + +while (w ((unsigned long)dst) 0x0f) +{ + *dst++ = (*src++) | 0xff00; + w--; +} + +while (w = 4) +{ + save_128_aligned ( + (__m128i *)dst, _mm_or_si128 ( + load_128_unaligned ((__m128i *)src), ff00)); + + dst += 4; + src += 4; + w -= 4; +} + +while (w) +{ + *dst++ = (*src++) | 0xff00; + w--; +} + +return iter-buffer; +} + +typedef struct +{ +pixman_format_code_t format; +pixman_iter_get_scanline_t get_scanline; +} fetcher_info_t; + +static const fetcher_info_t fetchers[] = +{ +{ PIXMAN_x8r8g8b8, sse2_fetch_x8r8g8b8 }, +{ PIXMAN_null } +}; + +static void +sse2_src_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ +#define FLAGS \ +(FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM) + +if ((flags ITER_NARROW) + (image-common.flags FLAGS) == FLAGS + x = 0 y = 0 + x + width = image-bits.width + y + height = image-bits.height) +{ + const fetcher_info_t *f; + + for (f = fetchers[0]; f-format != PIXMAN_null; f++) + { + if (image-common.extended_format_code == f-format) + { + uint8_t *b = (uint8_t *)image-bits.bits; + int s = image-bits.rowstride * 4; + + iter-bits = b + s * y + x * PIXMAN_FORMAT_BPP (f-format) / 8; + iter-stride = s; + iter-width = width; + iter-buffer = (uint32_t *)buffer; + + iter-get_scanline = f-get_scanline; + return; + } + } +} + +_pixman_implementation_src_iter_init ( + imp-delegate, iter, image, x, y, width, height, buffer, flags); +} + #if defined(__GNUC__) !defined(__x86_64__) !defined(__amd64__) __attribute__((__force_align_arg_pointer__)) #endif @@ -6020,6 +6108,8 @@ _pixman_implementation_create_sse2 (pixman_implementation_t *fallback) imp-blt = sse2_blt; imp-fill = sse2_fill; +imp-src_iter_init = sse2_src_iter_init; + return imp; } -- 1.7.3.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 4/5] Improve performance of sse2_combine_over_u()
From: Søren Sandmann Pedersen s...@redhat.com Split this function into two, one that has a mask, and one that doesn't. This is a fairly substantial speed-up in many cases. New output of lowlevel-blt-bench over_x888_8_0565: over_x888_8_0565 = L1: 63.76 L2: 62.75 M: 59.37 ( 21.55%) HT: 45.89 VT: 43.55 R: 34.51 RT: 16.80 ( 201Kops/s) --- pixman/pixman-sse2.c | 168 ++--- 1 files changed, 130 insertions(+), 38 deletions(-) diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index d5ea14b..e28b986 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -610,82 +610,174 @@ combine4 (const __m128i *ps, const __m128i *pm) } static force_inline void -core_combine_over_u_sse2 (uint32_t* pd, - const uint32_t* ps, - const uint32_t* pm, - int w) +core_combine_over_u_sse2_mask (uint32_t *pd, + const uint32_t*ps, + const uint32_t*pm, + intw) { uint32_t s, d; -__m128i xmm_dst_lo, xmm_dst_hi; -__m128i xmm_src_lo, xmm_src_hi; -__m128i xmm_alpha_lo, xmm_alpha_hi; - /* Align dst on a 16-byte boundary */ while (w ((unsigned long)pd 15)) { d = *pd; s = combine1 (ps, pm); - *pd++ = core_combine_over_u_pixel_sse2 (s, d); + if (s) + *pd = core_combine_over_u_pixel_sse2 (s, d); + pd++; ps++; - if (pm) - pm++; + pm++; w--; } while (w = 4) { - /* I'm loading unaligned because I'm not sure about -* the address alignment. -*/ - xmm_src_hi = combine4 ((__m128i*)ps, (__m128i*)pm); + __m128i mask = load_128_unaligned ((__m128i *)pm); - if (is_opaque (xmm_src_hi)) + if (!is_zero (mask)) { - save_128_aligned ((__m128i*)pd, xmm_src_hi); - } - else if (!is_zero (xmm_src_hi)) - { - xmm_dst_hi = load_128_aligned ((__m128i*) pd); + __m128i src; + __m128i src_hi, src_lo; + __m128i mask_hi, mask_lo; + __m128i alpha_hi, alpha_lo; - unpack_128_2x128 (xmm_src_hi, xmm_src_lo, xmm_src_hi); - unpack_128_2x128 (xmm_dst_hi, xmm_dst_lo, xmm_dst_hi); + src = load_128_unaligned ((__m128i *)ps); - expand_alpha_2x128 ( - xmm_src_lo, xmm_src_hi, xmm_alpha_lo, xmm_alpha_hi); + if (is_opaque (_mm_and_si128 (src, mask))) + { + save_128_aligned ((__m128i *)pd, src); + } + else + { + __m128i dst = load_128_aligned ((__m128i *)pd); + __m128i dst_hi, dst_lo; - over_2x128 (xmm_src_lo, xmm_src_hi, - xmm_alpha_lo, xmm_alpha_hi, - xmm_dst_lo, xmm_dst_hi); + unpack_128_2x128 (mask, mask_lo, mask_hi); + unpack_128_2x128 (src, src_lo, src_hi); - /* rebuid the 4 pixel data and save*/ - save_128_aligned ((__m128i*)pd, - pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); + expand_alpha_2x128 (mask_lo, mask_hi, mask_lo, mask_hi); + pix_multiply_2x128 (src_lo, src_hi, + mask_lo, mask_hi, + src_lo, src_hi); + + unpack_128_2x128 (dst, dst_lo, dst_hi); + + expand_alpha_2x128 (src_lo, src_hi, + alpha_lo, alpha_hi); + + over_2x128 (src_lo, src_hi, alpha_lo, alpha_hi, + dst_lo, dst_hi); + + save_128_aligned ( + (__m128i *)pd, + pack_2x128_128 (dst_lo, dst_hi)); + } } - w -= 4; + pm += 4; ps += 4; pd += 4; - if (pm) - pm += 4; + w -= 4; } - while (w) { d = *pd; s = combine1 (ps, pm); - *pd++ = core_combine_over_u_pixel_sse2 (s, d); + if (s) + *pd = core_combine_over_u_pixel_sse2 (s, d); + pd++; ps++; - if (pm) - pm++; + pm++; w--; } } static force_inline void +core_combine_over_u_sse2_no_mask (uint32_t * pd, + const uint32_t*ps, + intw) +{ +uint32_t s, d; + +/* Align dst on a 16-byte boundary */ +while (w ((unsigned long)pd 15)) +{ + d = *pd; + s = *ps; + + if (s) + *pd = core_combine_over_u_pixel_sse2 (s, d); + pd++; + ps++; + w--; +} + +while (w = 4) +{ + __m128i src; + __m128i src_hi, src_lo, dst_hi, dst_lo; + __m128i alpha_hi, alpha_lo; + + src
[Pixman] [PATCH 5/5] Add SSE2 fetcher for 0565
From: Søren Sandmann Pedersen s...@redhat.com Before: add_0565_0565 = L1: 61.08 L2: 61.03 M: 60.57 ( 10.95%) HT: 46.85 VT: 45.25 R: 39.99 RT: 20.41 ( 233Kops/s) After: add_0565_0565 = L1: 77.84 L2: 76.25 M: 75.38 ( 13.71%) HT: 55.99 VT: 54.56 R: 45.41 RT: 21.95 ( 255Kops/s) --- pixman/pixman-sse2.c | 47 +++ 1 files changed, 47 insertions(+), 0 deletions(-) diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index e28b986..91adc05 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -6082,6 +6082,52 @@ sse2_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask) } static uint32_t * +sse2_fetch_r5g6b5 (pixman_iter_t *iter, const uint32_t *mask) +{ +int w = iter-width; +uint32_t *dst = iter-buffer; +uint16_t *src = (uint16_t *)iter-bits; +__m128i ff00 = mask_ff00; + +iter-bits += iter-stride; + +while (w ((unsigned long)dst) 0x0f) +{ + uint16_t s = *src++; + + *dst++ = CONVERT_0565_TO_ (s); + w--; +} + +while (w = 8) +{ + __m128i lo, hi, s; + + s = _mm_loadu_si128 ((__m128i *)src); + + lo = unpack_565_to_ (_mm_unpacklo_epi16 (s, _mm_setzero_si128 ())); + hi = unpack_565_to_ (_mm_unpackhi_epi16 (s, _mm_setzero_si128 ())); + + save_128_aligned ((__m128i *)(dst + 0), _mm_or_si128 (lo, ff00)); + save_128_aligned ((__m128i *)(dst + 4), _mm_or_si128 (hi, ff00)); + + dst += 8; + src += 8; + w -= 8; +} + +while (w) +{ + uint16_t s = *src++; + + *dst++ = CONVERT_0565_TO_ (s); + w--; +} + +return iter-buffer; +} + +static uint32_t * sse2_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask) { int w = iter-width; @@ -6136,6 +6182,7 @@ typedef struct static const fetcher_info_t fetchers[] = { { PIXMAN_x8r8g8b8, sse2_fetch_x8r8g8b8 }, +{ PIXMAN_r5g6b5, sse2_fetch_r5g6b5 }, { PIXMAN_a8, sse2_fetch_a8 }, { PIXMAN_null } }; -- 1.7.3.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/3] Add @TESTPROGS_EXTRA_LDFLAGS@ to AM_LDFLAGS
From: Søren Sandmann Pedersen s...@redhat.com Instead of explicitly adding it to each test program. --- test/Makefile.am | 18 +- 1 files changed, 1 insertions(+), 17 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index 92ee8fd..0f03153 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,5 +1,5 @@ AM_CFLAGS = @OPENMP_CFLAGS@ -AM_LDFLAGS = @OPENMP_CFLAGS@ +AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@ TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la -lm INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman @@ -23,61 +23,45 @@ TESTPROGRAMS = \ composite a1_trap_test_LDADD = $(TEST_LDADD) -a1_trap_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ fetch_test_LDADD = $(TEST_LDADD) -fetch_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ trap_crasher_LDADD = $(TEST_LDADD) -trap_crasher_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ oob_test_LDADD = $(TEST_LDADD) -oob_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ scaling_crash_test_LDADD = $(TEST_LDADD) -scaling_crash_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ region_translate_test_LDADD = $(TEST_LDADD) -region_translate_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ pdf_op_test_LDADD = $(TEST_LDADD) -pdf_op_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h region_test_LDADD = $(TEST_LDADD) -region_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ region_test_SOURCES = region-test.c utils.c utils.h blitters_test_LDADD = $(TEST_LDADD) -blitters_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ blitters_test_SOURCES = blitters-test.c utils.c utils.h scaling_test_LDADD = $(TEST_LDADD) -scaling_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ scaling_test_SOURCES = scaling-test.c utils.c utils.h affine_test_LDADD = $(TEST_LDADD) -affine_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ affine_test_SOURCES = affine-test.c utils.c utils.h alphamap_LDADD = $(TEST_LDADD) -alphamap_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ alphamap_SOURCES = alphamap.c utils.c utils.h alpha_loop_LDADD = $(TEST_LDADD) -alpha_loop_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ alpha_loop_SOURCES = alpha-loop.c utils.c utils.h composite_LDADD = $(TEST_LDADD) -composite_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ composite_SOURCES = composite.c utils.c utils.h gradient_crash_test_LDADD = $(TEST_LDADD) -gradient_crash_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h stress_test_LDADD = $(TEST_LDADD) -stress_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@ stress_test_SOURCES = stress-test.c utils.c utils.h # Benchmarks -- 1.7.3.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 3/3] test/Makefile.am: Move all the TEST_LDADD into a new global LDADD.
From: Søren Sandmann Pedersen s...@redhat.com This gets rid of a bunch of replicated *_LDADD clauses --- test/Makefile.am | 35 +-- 1 files changed, 1 insertions(+), 34 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index 0f03153..3ce466e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,7 +1,6 @@ AM_CFLAGS = @OPENMP_CFLAGS@ AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@ - -TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la -lm +LDADD = $(top_builddir)/pixman/libpixman-1.la -lm INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman TESTPROGRAMS = \ @@ -22,46 +21,15 @@ TESTPROGRAMS = \ affine-test \ composite -a1_trap_test_LDADD = $(TEST_LDADD) - -fetch_test_LDADD = $(TEST_LDADD) - -trap_crasher_LDADD = $(TEST_LDADD) - -oob_test_LDADD = $(TEST_LDADD) - -scaling_crash_test_LDADD = $(TEST_LDADD) - -region_translate_test_LDADD = $(TEST_LDADD) - -pdf_op_test_LDADD = $(TEST_LDADD) pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h - -region_test_LDADD = $(TEST_LDADD) region_test_SOURCES = region-test.c utils.c utils.h - -blitters_test_LDADD = $(TEST_LDADD) blitters_test_SOURCES = blitters-test.c utils.c utils.h - -scaling_test_LDADD = $(TEST_LDADD) scaling_test_SOURCES = scaling-test.c utils.c utils.h - -affine_test_LDADD = $(TEST_LDADD) affine_test_SOURCES = affine-test.c utils.c utils.h - -alphamap_LDADD = $(TEST_LDADD) alphamap_SOURCES = alphamap.c utils.c utils.h - -alpha_loop_LDADD = $(TEST_LDADD) alpha_loop_SOURCES = alpha-loop.c utils.c utils.h - -composite_LDADD = $(TEST_LDADD) composite_SOURCES = composite.c utils.c utils.h - -gradient_crash_test_LDADD = $(TEST_LDADD) gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h - -stress_test_LDADD = $(TEST_LDADD) stress_test_SOURCES = stress-test.c utils.c utils.h # Benchmarks @@ -70,7 +38,6 @@ BENCHMARKS = \ lowlevel-blt-bench lowlevel_blt_bench_SOURCES = lowlevel-blt-bench.c utils.c utils.h -lowlevel_blt_bench_LDADD = $(TEST_LDADD) noinst_PROGRAMS = $(TESTPROGRAMS) $(BENCHMARKS) -- 1.7.3.1 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 1/3] In delegate_{src, dest}_iter_init() call delegate directly.
From: Søren Sandmann Pedersen s...@redhat.com There is no reason to go through _pixman_implementation_{src,dest}_iter_init(), especially since _pixman_implementation_src_iter_init() is doing various other checks that only need to be done once. Also call delegate-src_iter_init() directly in pixman-sse2.c --- pixman/pixman-implementation.c |4 ++-- pixman/pixman-sse2.c |2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c index adaf9c6..892767e 100644 --- a/pixman/pixman-implementation.c +++ b/pixman/pixman-implementation.c @@ -122,7 +122,7 @@ delegate_src_iter_init (pixman_implementation_t *imp, uint8_t *buffer, iter_flags_t flags) { -_pixman_implementation_src_iter_init ( +imp-delegate-src_iter_init ( imp-delegate, iter, image, x, y, width, height, buffer, flags); } @@ -137,7 +137,7 @@ delegate_dest_iter_init (pixman_implementation_t *imp, uint8_t *buffer, iter_flags_t flags) { -_pixman_implementation_dest_iter_init ( +imp-delegate-dest_iter_init ( imp-delegate, iter, image, x, y, width, height, buffer, flags); } diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index 696005f..d4a34e9 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -6013,7 +6013,7 @@ sse2_src_iter_init (pixman_implementation_t *imp, } } -_pixman_implementation_src_iter_init ( +imp-delegate-src_iter_init ( imp-delegate, iter, image, x, y, width, height, buffer, flags); } -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 3/3] Simplify the prototype for iterator initializers.
From: Søren Sandmann Pedersen s...@redhat.com All of the information previously passed to the iterator initializers is now available in the iterator itself, so there is no need to pass it as arguments anymore. --- pixman/pixman-bits-image.c | 20 +- pixman/pixman-conical-gradient.c |7 +--- pixman/pixman-general.c | 52 -- pixman/pixman-implementation.c | 30 - pixman/pixman-linear-gradient.c | 16 +++ pixman/pixman-private.h | 40 ++--- pixman/pixman-radial-gradient.c |7 +--- pixman/pixman-solid-fill.c | 17 +--- pixman/pixman-sse2.c | 25 + 9 files changed, 61 insertions(+), 153 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index a865d71..835ecfb 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -1362,12 +1362,9 @@ src_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) } void -_pixman_bits_image_src_iter_init (pixman_image_t *image, - pixman_iter_t *iter, - int x, int y, int width, int height, - uint8_t *buffer, iter_flags_t flags) +_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) { -if (flags ITER_NARROW) +if (iter-flags ITER_NARROW) iter-get_scanline = src_get_scanline_narrow; else iter-get_scanline = src_get_scanline_wide; @@ -1472,28 +1469,25 @@ dest_write_back_direct (pixman_iter_t *iter) } void -_pixman_bits_image_dest_iter_init (pixman_image_t *image, - pixman_iter_t *iter, - int x, int y, int width, int height, - uint8_t *buffer, iter_flags_t flags) +_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) { -if (flags ITER_NARROW) +if (iter-flags ITER_NARROW) { if (((image-common.flags (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) == (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) (image-bits.format == PIXMAN_a8r8g8b8 || (image-bits.format == PIXMAN_x8r8g8b8 - (flags ITER_LOCALIZED_ALPHA + (iter-flags ITER_LOCALIZED_ALPHA { - iter-buffer = image-bits.bits + y * image-bits.rowstride + x; + iter-buffer = image-bits.bits + iter-y * image-bits.rowstride + iter-x; iter-get_scanline = _pixman_iter_get_scanline_noop; iter-write_back = dest_write_back_direct; } else { - if ((flags (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == + if ((iter-flags (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) { iter-get_scanline = _pixman_iter_get_scanline_noop; diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c index 9d7d2e8..791d4f3 100644 --- a/pixman/pixman-conical-gradient.c +++ b/pixman/pixman-conical-gradient.c @@ -171,12 +171,9 @@ conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) } void -_pixman_conical_gradient_iter_init (pixman_image_t *image, - pixman_iter_t *iter, - int x, int y, int width, int height, - uint8_t *buffer, iter_flags_t flags) +_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) { -if (flags ITER_NARROW) +if (iter-flags ITER_NARROW) iter-get_scanline = conical_get_scanline_narrow; else iter-get_scanline = conical_get_scanline_wide; diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 1a0fa7c..727affc 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -38,60 +38,30 @@ #include pixman-private.h static void -general_src_iter_init (pixman_implementation_t *imp, - pixman_iter_t *iter, - pixman_image_t *image, - int x, int y, int width, int height, - uint8_t *buffer, iter_flags_t flags) +general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { +pixman_image_t *image = iter-image; + if (image-type == SOLID) -{ - _pixman_solid_fill_iter_init ( - image, iter, x, y, width, height, buffer, flags); -} + _pixman_solid_fill_iter_init (image, iter); else if (image-type == LINEAR) -{ - _pixman_linear_gradient_iter_init ( - image, iter, x, y, width, height, buffer, flags); -} + _pixman_linear_gradient_iter_init (image, iter); else if (image-type == RADIAL) -{ - _pixman_radial_gradient_iter_init ( - image, iter, x, y
[Pixman] [PATCH 2/3] Fill out parts of iters in _pixman_implementation_{src, dest}_iter_init()
From: Søren Sandmann Pedersen s...@redhat.com This makes _pixman_implementation_{src,dest}_iter_init() responsible for filling parts of the information in the iterators. Specifically, the information passed as arguments is stored in the iterator. Also add a height field to pixman_iter_t(). --- pixman/pixman-general.c|6 -- pixman/pixman-implementation.c | 16 pixman/pixman-private.h| 11 --- pixman/pixman-sse2.c |2 -- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 872fb7e..1a0fa7c 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -44,12 +44,6 @@ general_src_iter_init (pixman_implementation_t *imp, int x, int y, int width, int height, uint8_t *buffer, iter_flags_t flags) { -iter-image = image; -iter-x = x; -iter-y = y; -iter-width = width; -iter-buffer = (uint32_t *)buffer; - if (image-type == SOLID) { _pixman_solid_fill_iter_init ( diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c index 892767e..bdd4543 100644 --- a/pixman/pixman-implementation.c +++ b/pixman/pixman-implementation.c @@ -274,6 +274,14 @@ _pixman_implementation_src_iter_init (pixman_implementation_t *imp, uint8_t *buffer, iter_flags_t flags) { +iter-image = image; +iter-buffer = (uint32_t *)buffer; +iter-x = x; +iter-y = y; +iter-width = width; +iter-height = height; +iter-flags = flags; + if (!image) { iter-get_scanline = get_scanline_null; @@ -301,6 +309,14 @@ _pixman_implementation_dest_iter_init (pixman_implementation_t *imp, uint8_t *buffer, iter_flags_t flags) { +iter-image = image; +iter-buffer = (uint32_t *)buffer; +iter-x = x; +iter-y = y; +iter-width = width; +iter-height = height; +iter-flags = flags; + (*imp-dest_iter_init) ( imp, iter, image, x, y, width, height, buffer, flags); } diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 1473dc4..ea9545f 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -212,14 +212,19 @@ typedef enum struct pixman_iter_t { -pixman_iter_get_scanline_t get_scanline; -pixman_iter_write_back_t write_back; - +/* These are initialized by _pixman_implementation_{src,dest}_init */ pixman_image_t * image; uint32_t * buffer; intx, y; intwidth; +intheight; +iter_flags_t flags; + +/* These function pointers are initialized by the implementation */ +pixman_iter_get_scanline_t get_scanline; +pixman_iter_write_back_t write_back; +/* These fields are scratch data that implementations can use */ uint8_t * bits; intstride; }; diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index d4a34e9..43a6bf2 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -6004,8 +6004,6 @@ sse2_src_iter_init (pixman_implementation_t *imp, iter-bits = b + s * y + x * PIXMAN_FORMAT_BPP (f-format) / 8; iter-stride = s; - iter-width = width; - iter-buffer = (uint32_t *)buffer; iter-get_scanline = f-get_scanline; return; -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] test: Randomize some tests if PIXMAN_RANDOMIZE_TESTS is set
From: Søren Sandmann Pedersen s...@redhat.com This patch makes so that composite and stress-test will start from a random seed if the PIXMAN_RANDOMIZE_TESTS environment variable is set. Running the test suite in this mode is useful to get more test coverage. Also, in stress-test.c make it so that setting the initial seed causes threads to be turned off. This makes it much easier to see when something fails. --- test/composite.c | 17 - test/stress-test.c | 37 ++--- test/utils.c | 10 ++ test/utils.h |3 +++ 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/test/composite.c b/test/composite.c index a86e5ed..e6d52b9 100644 --- a/test/composite.c +++ b/test/composite.c @@ -868,7 +868,7 @@ main (int argc, char **argv) { #define N_TESTS (8 * 1024 * 1024) int result = 0; -int i; +uint32_t i; if (argc 1) { @@ -890,15 +890,22 @@ main (int argc, char **argv) } } +uint32_t seed; + +if (getenv (PIXMAN_RANDOMIZE_TESTS)) + seed = get_random_seed(); +else + seed = 1; + #ifdef USE_OPENMP -# pragma omp parallel for default(none) shared(result) shared(argv) +# pragma omp parallel for default(none) shared(result, argv, seed) #endif -for (i = 1; i = N_TESTS; ++i) +for (i = seed; i = N_TESTS; ++i) { if (!result !run_test (i)) { - printf (Test %d failed.\n, i); - + printf (Test 0x%08X failed.\n, i); + result = i; } } diff --git a/test/stress-test.c b/test/stress-test.c index 166dc6d..d496f93 100644 --- a/test/stress-test.c +++ b/test/stress-test.c @@ -1,4 +1,6 @@ +#include stdio.h #include utils.h +#include sys/types.h #if 0 #define fence_malloc malloc @@ -730,11 +732,17 @@ static const pixman_op_t op_list[] = }; static void -run_test (uint32_t seed) +run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod) { pixman_image_t *source, *mask, *dest; pixman_op_t op; +if (verbose) +{ + if (mod == 0 || (seed % mod) == 0) + printf (Seed 0x%08x\n, seed); +} + lcg_srand (seed); source = create_random_image (); @@ -787,6 +795,7 @@ main (int argc, char **argv) uint32_t seed = 1; uint32_t n_tests = 0x; uint32_t mod = 0; +pixman_bool_t use_threads = TRUE; uint32_t i; pixman_disable_out_of_bounds_workaround (); @@ -811,6 +820,7 @@ main (int argc, char **argv) else if (strcmp (argv[i], -s) == 0 i + 1 argc) { get_int (argv[i + 1], seed); + use_threads = FALSE; i++; } else if (strcmp (argv[i], -n) == 0 i + 1 argc) @@ -825,7 +835,7 @@ main (int argc, char **argv) printf (Options:\n\n -n numberNumber of tests to run\n - -s seed Seed of first test\n + -s seed Seed of first test (ignored if PIXMAN_RANDOMIZE_TESTS is set)\n -v Print out seeds\n -v n Print out every n'th seed\n\n); @@ -836,19 +846,24 @@ main (int argc, char **argv) if (n_tests == 0x) n_tests = 8000; -/* FIXME: seed 2005763 fails in set_lum() with divide by zero */ +if (getenv (PIXMAN_RANDOMIZE_TESTS)) +{ + seed = get_random_seed(); + printf (First seed: 0x%08x\n, seed); +} + +if (use_threads) +{ #ifdef USE_OPENMP # pragma omp parallel for default(none) shared(verbose, n_tests, mod, seed) #endif -for (i = seed; i seed + n_tests; ++i) + for (i = seed; i seed + n_tests; ++i) + run_test (i, verbose, mod); +} +else { - if (verbose) - { - if (mod == 0 || (i % mod) == 0) - printf (Seed %d\n, i); - } - - run_test (i); + for (i = seed; i seed + n_tests; ++i) + run_test (i, verbose, mod); } return 0; diff --git a/test/utils.c b/test/utils.c index 4bf02e1..56701c4 100644 --- a/test/utils.c +++ b/test/utils.c @@ -455,6 +455,16 @@ gettime (void) #endif } +uint32_t +get_random_seed (void) +{ +double d = gettime(); + +lcg_srand (*(uint32_t *)d); + +return lcg_rand_u32 (); +} + static const char *global_msg; static void diff --git a/test/utils.h b/test/utils.h index a5183f7..615ad78 100644 --- a/test/utils.h +++ b/test/utils.h @@ -79,6 +79,9 @@ make_random_bytes (int n_bytes); double gettime (void); +uint32_t +get_random_seed (void); + /* main body of the fuzzer test */ int fuzzer_test_main (const char *test_name, -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 1/3] mmx: Delete some unused variables
From: Søren Sandmann Pedersen ssp@hp-sandybridge.(none) --- pixman/pixman-mmx.c | 17 +++-- 1 files changed, 3 insertions(+), 14 deletions(-) diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c index 0272347..62a73d6 100644 --- a/pixman/pixman-mmx.c +++ b/pixman/pixman-mmx.c @@ -1267,7 +1267,7 @@ mmx_composite_over_n___ca (pixman_implementation_t *imp, int32_t width, int32_t height) { -uint32_t src, srca; +uint32_t src; uint32_t*dst_line; uint32_t*mask_line; int dst_stride, mask_stride; @@ -1277,7 +1277,6 @@ mmx_composite_over_n___ca (pixman_implementation_t *imp, src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); -srca = src 24; if (src == 0) return; @@ -1377,7 +1376,6 @@ mmx_composite_over__n_ (pixman_implementation_t *imp, __m64 vmask; int dst_stride, src_stride; int32_t w; -__m64 srca; CHECKPOINT (); @@ -1388,7 +1386,6 @@ mmx_composite_over__n_ (pixman_implementation_t *imp, mask = 0xff00; mask = mask | mask 8 | mask 16 | mask 24; vmask = load (mask); -srca = MC (4x00ff); while (height--) { @@ -2033,7 +2030,7 @@ mmx_composite_src_n_8_ (pixman_implementation_t *imp, uint8_t *mask_line, *mask; int dst_stride, mask_stride; int32_t w; -__m64 vsrc, vsrca; +__m64 vsrc; uint64_t srcsrc; CHECKPOINT (); @@ -2055,7 +2052,6 @@ mmx_composite_src_n_8_ (pixman_implementation_t *imp, PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); vsrc = load (src); -vsrca = expand_alpha (vsrc); while (height--) { @@ -2101,11 +2097,8 @@ mmx_composite_src_n_8_ (pixman_implementation_t *imp, } else if (m0 | m1) { - __m64 vdest; __m64 dest0, dest1; - vdest = *(__m64 *)dst; - dest0 = in (vsrc, expand_alpha_rev (to_m64 (m0))); dest1 = in (vsrc, expand_alpha_rev (to_m64 (m1))); @@ -2524,7 +2517,7 @@ mmx_composite_over_n__0565_ca (pixman_implementation_t *imp, int32_t width, int32_t height) { -uint32_t src, srca; +uint32_t src; uint16_t*dst_line; uint32_t*mask_line; int dst_stride, mask_stride; @@ -2534,7 +2527,6 @@ mmx_composite_over_n__0565_ca (pixman_implementation_t *imp, src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); -srca = src 24; if (src == 0) return; @@ -2663,12 +2655,9 @@ mmx_composite_in_n_8_8 (pixman_implementation_t *imp, { while (w = 4) { - uint32_t m; __m64 vmask; __m64 vdest; - m = 0; - vmask = load (*(uint32_t *)mask); vdest = load (*(uint32_t *)dst); -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/3] sse2: Delete some unused variables
From: Søren Sandmann Pedersen ssp@hp-sandybridge.(none) --- pixman/pixman-mmx.c |2 +- pixman/pixman-sse2.c | 18 -- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c index 62a73d6..0185df6 100644 --- a/pixman/pixman-mmx.c +++ b/pixman/pixman-mmx.c @@ -2660,7 +2660,7 @@ mmx_composite_in_n_8_8 (pixman_implementation_t *imp, vmask = load (*(uint32_t *)mask); vdest = load (*(uint32_t *)dst); - + *(uint32_t *)dst = store (in (in (vsrca, vmask), vdest)); dst += 4; diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index 533b858..1fd66bf 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -2537,20 +2537,19 @@ sse2_composite_add_n___ca (pixman_implementation_t *imp, int32_t width, int32_t height) { -uint32_t src, srca; +uint32_t src; uint32_t*dst_line, d; uint32_t*mask_line, m; uint32_t pack_cmp; int dst_stride, mask_stride; -__m128i xmm_src, xmm_alpha; +__m128i xmm_src; __m128i xmm_dst; __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; -__m128i mmx_src, mmx_alpha, mmx_mask, mmx_dest; +__m128i mmx_src, mmx_mask, mmx_dest; src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); -srca = src 24; if (src == 0) return; @@ -2562,9 +2561,7 @@ sse2_composite_add_n___ca (pixman_implementation_t *imp, xmm_src = _mm_unpacklo_epi8 ( create_mask_2x32_128 (src, src), _mm_setzero_si128 ()); -xmm_alpha = expand_alpha_1x128 (xmm_src); mmx_src = xmm_src; -mmx_alpha = xmm_alpha; while (height--) { @@ -3628,7 +3625,7 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t *imp, int32_t width, int32_t height) { -uint32_t src, srca; +uint32_t src; uint16_t*dst_line, *dst, d; uint8_t *mask_line, *mask; int dst_stride, mask_stride; @@ -3642,7 +3639,6 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t *imp, src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); -srca = src 24; if (src == 0) return; @@ -4143,7 +4139,6 @@ sse2_composite_in_n_8_8 (pixman_implementation_t *imp, int dst_stride, mask_stride; uint32_t d, m; uint32_t src; -uint8_t sa; int32_t w; __m128i xmm_alpha; @@ -4157,8 +4152,6 @@ sse2_composite_in_n_8_8 (pixman_implementation_t *imp, src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); -sa = src 24; - xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src)); while (height--) @@ -4415,7 +4408,6 @@ sse2_composite_add_n_8_8 (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; uint32_t src; -uint8_t sa; uint32_t m, d; __m128i xmm_alpha; @@ -4429,8 +4421,6 @@ sse2_composite_add_n_8_8 (pixman_implementation_t *imp, src = _pixman_image_get_solid (imp, src_image, dst_image-bits.format); -sa = src 24; - xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src)); while (height--) -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 3/3] demos: Comment out some unused variables
From: Søren Sandmann Pedersen ssp@hp-sandybridge.(none) --- demos/alpha-test.c|4 +++- demos/gradient-test.c |4 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/demos/alpha-test.c b/demos/alpha-test.c index 92c2081..54e30fa 100644 --- a/demos/alpha-test.c +++ b/demos/alpha-test.c @@ -40,10 +40,12 @@ main (int argc, char **argv) }; #endif +#if 0 pixman_point_fixed_t c_inner; pixman_point_fixed_t c_outer; pixman_fixed_t r_inner; pixman_fixed_t r_outer; +#endif for (i = 0; i WIDTH * HEIGHT; ++i) alpha[i] = 0x4f4f; /* pale blue */ @@ -69,6 +71,7 @@ main (int argc, char **argv) src, WIDTH * 4); +#if 0 c_inner.x = pixman_double_to_fixed (50.0); c_inner.y = pixman_double_to_fixed (50.0); c_outer.x = pixman_double_to_fixed (50.0); @@ -76,7 +79,6 @@ main (int argc, char **argv) r_inner = 0; r_outer = pixman_double_to_fixed (50.0); -#if 0 grad_img = pixman_image_create_conical_gradient (c_inner, r_inner, stops, 2); #endif diff --git a/demos/gradient-test.c b/demos/gradient-test.c index fc84844..20f78a6 100644 --- a/demos/gradient-test.c +++ b/demos/gradient-test.c @@ -36,10 +36,12 @@ main (int argc, char **argv) }; #endif +#if 0 pixman_point_fixed_t c_inner; pixman_point_fixed_t c_outer; pixman_fixed_t r_inner; pixman_fixed_t r_outer; +#endif for (i = 0; i WIDTH * HEIGHT; ++i) dest[i] = 0x4f4f; /* pale blue */ @@ -49,6 +51,7 @@ main (int argc, char **argv) dest, WIDTH * 4); +#if 0 c_inner.x = pixman_double_to_fixed (50.0); c_inner.y = pixman_double_to_fixed (50.0); c_outer.x = pixman_double_to_fixed (50.0); @@ -58,6 +61,7 @@ main (int argc, char **argv) src_img = pixman_image_create_conical_gradient (c_inner, r_inner, stops, 2); +#endif #if 0 src_img = pixman_image_create_conical_gradient (c_inner, r_inner, stops, 2); -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/2] ARM: Fix two bugs in neon_composite_over_n_8888_0565_ca().
The first bug is that a vmull.u8 instruction would store its result in the q1 register, clobbering the d2 register used later on. The second is that a vraddhn instruction would overwrite d25, corrupting the q12 register used later. Fixing the second bug caused a pipeline bubble where the d18 register would be unavailable for a clock cycle. This is fixed by swapping the instruction with its successor. --- pixman/pixman-arm-neon-asm.S |8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pixman/pixman-arm-neon-asm.S b/pixman/pixman-arm-neon-asm.S index 833f18c..7cddf7e 100644 --- a/pixman/pixman-arm-neon-asm.S +++ b/pixman/pixman-arm-neon-asm.S @@ -1514,11 +1514,11 @@ generate_composite_function \ * output: updated src in {d0, d1, d2 } [B, G, R] * updated mask in {d24, d25, d26} [B, G, R] */ -vmull.u8q1, d25, d9 +vmull.u8q6, d26, d10 vqadd.u8q8, q0, q8 vmull.u8q0, d24, d8 vqadd.u8d22, d2, d22 -vmull.u8q6, d26, d10 +vmull.u8q1, d25, d9 /* * convert the result in d16, d17, d22 to r5g6b5 and store * it into {d28, d29} @@ -1541,6 +1541,7 @@ generate_composite_function \ vrshr.u16 q11, q12, #8 vrshr.u16 q8, q9, #8 vrshr.u16 q6, q13, #8 +vraddhn.u16 d24, q12, q11 vraddhn.u16 d25, q9, q8 /* * convert 8 r5g6b5 pixel data from {d4, d5} to planar @@ -1549,11 +1550,10 @@ generate_composite_function \ */ vshrn.u16 d17, q2, #3 vshrn.u16 d18, q2, #8 -vraddhn.u16 d24, q12, q11 vraddhn.u16 d26, q13, q6 vsli.u16q2, q2, #5 -vsri.u8 d18, d18, #5 vsri.u8 d17, d17, #6 +vsri.u8 d18, d18, #5 /* * 'combine_over_ca' replacement * -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 1/2] blitters-test: Make common formats more likely to be tested.
From: Søren Sandmann Pedersen s...@redhat.com Move the eight most common formats to the top of the list of image formats and make create_random_image() much more likely to select one of those eight formats. This should help catch more bugs in SIMD optimized operations. --- test/blitters-test.c | 22 ++ 1 files changed, 14 insertions(+), 8 deletions(-) diff --git a/test/blitters-test.c b/test/blitters-test.c index 3ecfb09..594ec54 100644 --- a/test/blitters-test.c +++ b/test/blitters-test.c @@ -14,6 +14,11 @@ static pixman_indexed_t rgb_palette[9]; static pixman_indexed_t y_palette[9]; +/* The first eight format in the list are by far the most widely + * used formats, so we test those more than the others + */ +#define N_MOST_LIKELY_FORMATS 8 + /* Create random image for testing purposes */ static pixman_image_t * create_random_image (pixman_format_code_t *allowed_formats, @@ -29,6 +34,9 @@ create_random_image (pixman_format_code_t *allowed_formats, while (allowed_formats[n] != PIXMAN_null) n++; + +if (n N_MOST_LIKELY_FORMATS lcg_rand_n (4) != 0) + n = N_MOST_LIKELY_FORMATS; fmt = allowed_formats[lcg_rand_n (n)]; width = lcg_rand_n (max_width) + 1; @@ -177,12 +185,14 @@ static pixman_op_t op_list[] = { static pixman_format_code_t img_fmt_list[] = { PIXMAN_a8r8g8b8, +PIXMAN_a8b8g8r8, PIXMAN_x8r8g8b8, +PIXMAN_x8b8g8r8, PIXMAN_r5g6b5, -PIXMAN_r3g3b2, +PIXMAN_b5g6r5, PIXMAN_a8, -PIXMAN_a8b8g8r8, -PIXMAN_x8b8g8r8, +PIXMAN_a1, +PIXMAN_r3g3b2, PIXMAN_b8g8r8a8, PIXMAN_b8g8r8x8, PIXMAN_r8g8b8a8, @@ -190,8 +200,6 @@ static pixman_format_code_t img_fmt_list[] = { PIXMAN_x14r6g6b6, PIXMAN_r8g8b8, PIXMAN_b8g8r8, -PIXMAN_r5g6b5, -PIXMAN_b5g6r5, PIXMAN_x2r10g10b10, PIXMAN_a2r10g10b10, PIXMAN_x2b10g10r10, @@ -204,7 +212,6 @@ static pixman_format_code_t img_fmt_list[] = { PIXMAN_x4r4g4b4, PIXMAN_a4b4g4r4, PIXMAN_x4b4g4r4, -PIXMAN_a8, PIXMAN_r3g3b2, PIXMAN_b2g3r3, PIXMAN_a2r2g2b2, @@ -222,7 +229,6 @@ static pixman_format_code_t img_fmt_list[] = { PIXMAN_b1g2r1, PIXMAN_a1r1g1b1, PIXMAN_a1b1g1r1, -PIXMAN_a1, PIXMAN_null }; @@ -417,6 +423,6 @@ main (int argc, const char *argv[]) } return fuzzer_test_main(blitters, 200, - 0x265CDFEB, + 0xB610300B, test_composite, argc, argv); } -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] Speed up pixman_region_contains_{rectangle,point}
This patch series contains a speed-up for the two functions pixman_region_contains_rectangle() and pixman_region_contains_point(). The main usecase is when you select some text in Firefox and drag it, a shaped window with a complicated shape will be created, and the X server will call pixman_region_contains_rectangle() a bunch of times on each mouse movement. The speed up is to use a binary search to look for the first rectangle in the region that could possible intersect the searched-for rectangle. There is also a regression test to verify that nothing broke, and a bug fix for lcg_rand_u32() which only generated 30 random bits, not 32. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 4/4] Use find_box_for_y in pixman_region_contains_point() too
From: Søren Sandmann Pedersen s...@redhat.com The same binary search from the previous commit can be used in this function too. --- pixman/pixman-region.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c index a199405..35fefc4 100644 --- a/pixman/pixman-region.c +++ b/pixman/pixman-region.c @@ -2376,9 +2376,12 @@ PREFIX (_contains_point) (region_type_t * region, return(TRUE); } -for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects; -pbox != pbox_end; -pbox++) +pbox = PIXREGION_BOXPTR (region); +pbox_end = pbox + numRects; + +pbox = find_box_for_y (pbox, pbox_end, y); + +for (;pbox != pbox_end; pbox++) { if (y = pbox-y2) continue; /* not there yet */ -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 2/4] New test of pixman_region_contains_{rectangle, point}
From: Søren Sandmann Pedersen s...@redhat.com This test generates random regions and checks whether random boxes and points are contained within them. The results are combined and a CRC32 value is computed and compared to a known-correct one. --- test/Makefile.am|2 + test/region-contains-test.c | 169 +++ test/utils.c| 11 +++- test/utils.h|4 + 4 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 test/region-contains-test.c diff --git a/test/Makefile.am b/test/Makefile.am index 9dc7219..9f61fc9 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -15,6 +15,7 @@ TESTPROGRAMS =\ scaling-crash-test \ scaling-helpers-test\ gradient-crash-test \ + region-contains-test\ alphamap\ stress-test \ composite-traps-test\ @@ -26,6 +27,7 @@ TESTPROGRAMS =\ pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h region_test_SOURCES = region-test.c utils.c utils.h blitters_test_SOURCES = blitters-test.c utils.c utils.h +region_contains_test_SOURCES = region-contains-test.c utils.c utils.h composite_traps_test_SOURCES = composite-traps-test.c utils.c utils.h scaling_test_SOURCES = scaling-test.c utils.c utils.h affine_test_SOURCES = affine-test.c utils.c utils.h diff --git a/test/region-contains-test.c b/test/region-contains-test.c new file mode 100644 index 000..d1cb1d8 --- /dev/null +++ b/test/region-contains-test.c @@ -0,0 +1,169 @@ +#include assert.h +#include stdlib.h +#include stdio.h +#include utils.h + +static void +make_random_region (pixman_region32_t *region) +{ +int n_boxes; + +pixman_region32_init (region); + +n_boxes = lcg_rand_n (64); +while (n_boxes--) +{ + int32_t x1, y1, x2, y2; + + x1 = (int32_t)lcg_rand_u32(); + y1 = (int32_t)lcg_rand_u32(); + x2 = (int32_t)lcg_rand_u32(); + y2 = (int32_t)lcg_rand_u32(); + + pixman_region32_union_rect (region, region, x1, y1, x2, y2); +} +} + +static void +print_box (pixman_box32_t *box) +{ +printf (%d %d %d %d\n, box-x1, box-y1, box-x2, box-y2); +} + +static int32_t +random_coord (pixman_region32_t *region, pixman_bool_t x) +{ +pixman_box32_t *b, *bb; +int n_boxes; +int begin, end; + +if (lcg_rand_n (14)) +{ + bb = pixman_region32_rectangles (region, n_boxes); + if (n_boxes == 0) + goto use_extent; + b = bb + lcg_rand_n (n_boxes); +} +else +{ +use_extent: + b = pixman_region32_extents (region); + n_boxes = 1; +} + +if (x) +{ + begin = b-x1; + end = b-x2; +} +else +{ + begin = b-y1; + end = b-y2; +} + +switch (lcg_rand_n (5)) +{ +case 0: + return begin - lcg_rand_u32(); +case 1: + return end + lcg_rand_u32 (); +case 2: + return end; +case 3: + return begin; +default: + return (begin + end) / 2; +} +return 0; +} + +static uint32_t +compute_crc32_u32 (uint32_t crc32, uint32_t v) +{ +if (!is_little_endian()) +{ + v = ((v 0xff00) 24)| + ((v 0x00ff) 8) | + ((v 0xff00) 8) | + ((v 0x00ff) 24); +} + +return compute_crc32 (crc32, v, sizeof (int32_t)); +} + +static uint32_t +crc32_box32 (uint32_t crc32, pixman_box32_t *box) +{ +crc32 = compute_crc32_u32 (crc32, box-x1); +crc32 = compute_crc32_u32 (crc32, box-y1); +crc32 = compute_crc32_u32 (crc32, box-x2); +crc32 = compute_crc32_u32 (crc32, box-y2); + +return crc32; +} + +static uint32_t +test_region_contains_rectangle (int i, int verbose) +{ +pixman_box32_t box; +pixman_box32_t rbox = { 0, 0, 0, 0 }; +pixman_region32_t region; +uint32_t r, r1, r2, r3, r4, crc32; + +lcg_srand (i); + +make_random_region (region); + +box.x1 = random_coord (region, TRUE); +box.x2 = box.x1 + lcg_rand_u32 (); +box.y1 = random_coord (region, FALSE); +box.y2 = box.y1 + lcg_rand_u32 (); + +if (verbose) +{ + int n_rects; + pixman_box32_t *boxes; + + boxes = pixman_region32_rectangles (region, n_rects); + + printf (region:\n); + while (n_rects--) + print_box (boxes++); + printf (box:\n); + print_box (box); +} + +crc32 = 0; + +r1 = pixman_region32_contains_point (region, box.x1, box.y1, rbox); +crc32 = crc32_box32 (crc32, rbox); +r2 = pixman_region32_contains_point (region, box.x1, box.y2, rbox); +crc32 = crc32_box32 (crc32, rbox); +r3 = pixman_region32_contains_point (region, box.x2, box.y1, rbox); +crc32 = crc32_box32 (crc32, rbox); +r4 = pixman_region32_contains_point (region, box.x2, box.y2, rbox); +crc32 = crc32_box32 (crc32, rbox); + +r
[Pixman] [PATCH 4/4] Use find_box_for_y() in pixman_region_contains_point() too
From: Søren Sandmann Pedersen s...@redhat.com The same binary search from the previous commit can be used in this function too. V2: Remove check from loop that is not needed anymore, pointed out by Andrea Canciani. --- pixman/pixman-region.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c index 71995fd..9ff5157 100644 --- a/pixman/pixman-region.c +++ b/pixman/pixman-region.c @@ -2378,13 +2378,13 @@ PREFIX (_contains_point) (region_type_t * region, return(TRUE); } -for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects; -pbox != pbox_end; -pbox++) -{ -if (y = pbox-y2) - continue; /* not there yet */ +pbox = PIXREGION_BOXPTR (region); +pbox_end = pbox + numRects; + +pbox = find_box_for_y (pbox, pbox_end, y); +for (;pbox != pbox_end; pbox++) +{ if ((y pbox-y1) || (x pbox-x1)) break; /* missed it */ -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] In pixman_image_create_bits() allow images larger than 2GB
From: Søren Sandmann Pedersen s...@redhat.com There is no reason for pixman_image_create_bits() to check that the image size fits in int32_t. The correct check is against size_t since that is what the argument to calloc() is. This patch fixes this by adding a new _pixman_multiply_overflows_size() and using it in create_bits(). Also prepend an underscore to the names of other similar functions since they are internal to pixman. --- pixman/pixman-bits-image.c | 14 +++--- pixman/pixman-private.h|7 +-- pixman/pixman-utils.c | 12 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 4e9ed14..d8abeac 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -1488,12 +1488,12 @@ _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) static uint32_t * create_bits (pixman_format_code_t format, - int width, - int height, - int *rowstride_bytes) + ssize_t width, + ssize_t height, + int * rowstride_bytes) { int stride; -int buf_size; +size_t buf_size; int bpp; /* what follows is a long-winded way, avoiding any possibility of integer @@ -1502,11 +1502,11 @@ create_bits (pixman_format_code_t format, */ bpp = PIXMAN_FORMAT_BPP (format); -if (pixman_multiply_overflows_int (width, bpp)) +if (_pixman_multiply_overflows_int (width, bpp)) return NULL; stride = width * bpp; -if (pixman_addition_overflows_int (stride, 0x1f)) +if (_pixman_addition_overflows_int (stride, 0x1f)) return NULL; stride += 0x1f; @@ -1514,7 +1514,7 @@ create_bits (pixman_format_code_t format, stride *= sizeof (uint32_t); -if (pixman_multiply_overflows_int (height, stride)) +if (_pixman_multiply_overflows_size (height, stride)) return NULL; buf_size = height * stride; diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 6a3935e..a25897d 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -691,10 +691,13 @@ void * pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c); pixman_bool_t -pixman_multiply_overflows_int (unsigned int a, unsigned int b); +_pixman_multiply_overflows_size (size_t a, size_t b); pixman_bool_t -pixman_addition_overflows_int (unsigned int a, unsigned int b); +_pixman_multiply_overflows_int (unsigned int a, unsigned int b); + +pixman_bool_t +_pixman_addition_overflows_int (unsigned int a, unsigned int b); /* Compositing utilities */ void diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index cb4e621..49e3488 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -31,15 +31,19 @@ #include pixman-private.h pixman_bool_t -pixman_multiply_overflows_int (unsigned int a, - unsigned int b) +_pixman_multiply_overflows_size (size_t a, size_t b) +{ +return a = SIZE_MAX / b; +} + +pixman_bool_t +_pixman_multiply_overflows_int (unsigned int a, unsigned int b) { return a = INT32_MAX / b; } pixman_bool_t -pixman_addition_overflows_int (unsigned int a, - unsigned int b) +_pixman_addition_overflows_int (unsigned int a, unsigned int b) { return a INT32_MAX - b; } -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] Consolidate some inlined functions
These three patches rename pixman-fast-path.h to pixman-inlines.h, since this file is not really specific to the fast path implementation, and then it moves some code from the general implementation into that file: the repeat functionality, which was duplicated, and the bilinear interpolation code. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 0/11] Use macros to generate fetchers
This patch series change pixman-access.c to generate most accessors with macros and inline functions instead of writing out the code for all the functions. This is a fairly significant saving in terms of lines of code: pixman-access.c | 3159 +++ pixman-private.h | 43 pixman-utils.c | 34 3 files changed, 724 insertions(+), 2512 deletions(-) but the main motivation is that will eventually make it easier to add floating point fetchers so that we can add a floating point pipeline. Comments welcome. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 01/11] Add a generic unorm_to_unorm() conversion utility
From: Søren Sandmann Pedersen s...@redhat.com This function can convert between normalized numbers of different depths. When converting to higher bit depths, it will replicate the existing bits, when converting to lower bit depths, it will simply truncate. This function replaces the expand16() function in pixman-utils.c --- pixman/pixman-private.h | 43 +++ pixman/pixman-utils.c | 34 +- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index a25897d..90d9011 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -783,6 +783,49 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst, # define SCREEN_SHIFT_RIGHT(x,n) ((x) (n)) #endif +static force_inline uint32_t +unorm_to_unorm (uint32_t val, int from_bits, int to_bits) +{ +uint32_t result; + +if (from_bits == 0) + return 0; + +/* Delete any extra bits */ +val = ((1 from_bits) - 1); + +if (from_bits = to_bits) + return val (from_bits - to_bits); + +/* Start out with the high bit of val in the high bit of result. */ +result = val (to_bits - from_bits); + +/* Copy the bits in result, doubling the number of bits each time, until + * we fill all to_bits. Unrolled manually because from_bits and to_bits + * are usually known statically, so the compiler can turn all of this + * into a few shifts. + */ +#define REPLICATE()\ +do \ +{ \ + if (from_bits to_bits)\ + { \ + result |= result from_bits; \ + \ + from_bits *= 2; \ + } \ +} \ +while (0) + +REPLICATE(); +REPLICATE(); +REPLICATE(); +REPLICATE(); +REPLICATE(); + +return result; +} + /* * Various debugging code */ diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index 49e3488..768ca1b 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -72,31 +72,6 @@ pixman_malloc_abc (unsigned int a, } /* - * Helper routine to expand a color component from 0 n = 8 bits to 16 - * bits by replication. - */ -static inline uint64_t -expand16 (const uint8_t val, int nbits) -{ -/* Start out with the high bit of val in the high bit of result. */ -uint16_t result = (uint16_t)val (16 - nbits); - -if (nbits == 0) - return 0; - -/* Copy the bits in result, doubling the number of bits each time, until - * we fill all 16 bits. - */ -while (nbits 16) -{ - result |= result nbits; - nbits *= 2; -} - -return result; -} - -/* * This function expands images from ARGB8 format to ARGB16. To preserve * precision, it needs to know the original source format. For example, if the * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then @@ -137,10 +112,11 @@ pixman_expand (uint64_t * dst, r = (pixel r_shift) r_mask, g = (pixel g_shift) g_mask, b = (pixel b_shift) b_mask; - const uint64_t a16 = a_size ? expand16 (a, a_size) : 0x, - r16 = expand16 (r, r_size), - g16 = expand16 (g, g_size), - b16 = expand16 (b, b_size); + const uint64_t + a16 = a_size ? unorm_to_unorm (a, a_size, 16) : 0x, + r16 = unorm_to_unorm (r, r_size, 16), + g16 = unorm_to_unorm (g, g_size, 16), + b16 = unorm_to_unorm (b, b_size, 16); dst[i] = a16 48 | r16 32 | g16 16 | b16; } -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 02/11] Add general pixel converter
From: Søren Sandmann Pedersen s...@redhat.com This function can convert between any = 32 bpp formats. Nothing uses it yet. --- pixman/pixman-access.c | 100 1 files changed, 100 insertions(+), 0 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 32c4d8b..2e9e536 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -86,6 +86,106 @@ ((uint8_t *) ((bits) + offset0 +\ ((stride) 1) * ((line) 1))) +/* Misc. helpers */ + +static force_inline void +get_shifts (pixman_format_code_t format, + int *a, + int *r, + int *g, + int *b) +{ +switch (PIXMAN_FORMAT_TYPE (format)) +{ +case PIXMAN_TYPE_A: + *b = 0; + *g = 0; + *r = 0; + *a = 0; + break; + +case PIXMAN_TYPE_ARGB: + *b = 0; + *g = *b + PIXMAN_FORMAT_B (format); + *r = *g + PIXMAN_FORMAT_G (format); + *a = *r + PIXMAN_FORMAT_R (format); + break; + +case PIXMAN_TYPE_ABGR: + *r = 0; + *g = *r + PIXMAN_FORMAT_R (format); + *b = *g + PIXMAN_FORMAT_G (format); + *a = *b + PIXMAN_FORMAT_B (format); + break; + +case PIXMAN_TYPE_BGRA: + /* With BGRA formats we start counting at the high end of the pixel */ + *b = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format); + *g = *b - PIXMAN_FORMAT_B (format); + *r = *g - PIXMAN_FORMAT_G (format); + *a = *r - PIXMAN_FORMAT_R (format); + break; + +case PIXMAN_TYPE_RGBA: + /* With BGRA formats we start counting at the high end of the pixel */ + *r = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format); + *g = *r - PIXMAN_FORMAT_R (format); + *b = *g - PIXMAN_FORMAT_G (format); + *a = *b - PIXMAN_FORMAT_B (format); + break; + +default: + assert (0); + break; +} +} + +static force_inline uint32_t +convert_channel (uint32_t pixel, uint32_t def_value, +int n_from_bits, int from_shift, +int n_to_bits, int to_shift) +{ +uint32_t v; + +if (n_from_bits n_to_bits) + v = unorm_to_unorm (pixel from_shift, n_from_bits, n_to_bits); +else if (n_to_bits) + v = def_value; +else + v = 0; + +return (v ((1 n_to_bits) - 1)) to_shift; +} + +static force_inline uint32_t +convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel) +{ +int a_from_shift, r_from_shift, g_from_shift, b_from_shift; +int a_to_shift, r_to_shift, g_to_shift, b_to_shift; +uint32_t a, r, g, b; + +get_shifts (from, a_from_shift, r_from_shift, g_from_shift, b_from_shift); +get_shifts (to, a_to_shift, r_to_shift, g_to_shift, b_to_shift); + +a = convert_channel (pixel, ~0, +PIXMAN_FORMAT_A (from), a_from_shift, +PIXMAN_FORMAT_A (to), a_to_shift); + +r = convert_channel (pixel, 0, +PIXMAN_FORMAT_R (from), r_from_shift, +PIXMAN_FORMAT_R (to), r_to_shift); + +g = convert_channel (pixel, 0, +PIXMAN_FORMAT_G (from), g_from_shift, +PIXMAN_FORMAT_G (to), g_to_shift); + +b = convert_channel (pixel, 0, +PIXMAN_FORMAT_B (from), b_from_shift, +PIXMAN_FORMAT_B (to), b_to_shift); + +return a | r | g | b; +} + /** Fetch / static void -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH 04/11] Use MAKE_ACCESSORS() to generate all the 32 bit accessors
From: Søren Sandmann Pedersen s...@redhat.com Add support for 32bpp formats in fetch_and_convert_pixel() and convert_and_store_pixel(), then use MAKE_ACCESSORS() to generate accessors for all the 32 bpp formats: a8r8g8b8 x8r8g8b8 a8b8g8r8 x8b8g8r8 x14r6g6b6 b8g8r8a8 b8g8r8x8 r8g8b8x8 r8g8b8a8 --- pixman/pixman-access.c | 483 ++-- 1 files changed, 17 insertions(+), 466 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index e8356e9..f8d6082 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -207,6 +207,10 @@ fetch_and_convert_pixel (pixman_image_t* image, switch (PIXMAN_FORMAT_BPP (format)) { +case 32: + pixel = READ (image, (uint32_t *)bits); + break; + default: pixel = 0x00ff; /* As ugly as possible to detect the bug */ break; @@ -225,6 +229,10 @@ convert_and_store_pixel (bits_image_t *image, switch (PIXMAN_FORMAT_BPP (format)) { +case 32: + WRITE (image, (uint32_t *)dest, converted); + break; + default: *dest = 0x0; break; @@ -299,196 +307,18 @@ convert_and_store_pixel (bits_image_t * image, \ static const void *const __dummy__ ## format +MAKE_ACCESSORS(a8r8g8b8); +MAKE_ACCESSORS(x8r8g8b8); +MAKE_ACCESSORS(a8b8g8r8); +MAKE_ACCESSORS(x8b8g8r8); +MAKE_ACCESSORS(x14r6g6b6); +MAKE_ACCESSORS(b8g8r8a8); +MAKE_ACCESSORS(b8g8r8x8); +MAKE_ACCESSORS(r8g8b8x8); +MAKE_ACCESSORS(r8g8b8a8); /** Fetch / -static void -fetch_scanline_a8r8g8b8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; - -MEMCPY_WRAPPED (image, -buffer, (const uint32_t *)bits + x, -width * sizeof(uint32_t)); -} - -static void -fetch_scanline_x8r8g8b8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint32_t *pixel = (const uint32_t *)bits + x; -const uint32_t *end = pixel + width; - -while (pixel end) - *buffer++ = READ (image, pixel++) | 0xff00; -} - -static void -fetch_scanline_a8b8g8r8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint32_t *pixel = (uint32_t *)bits + x; -const uint32_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - - *buffer++ = (p 0xff00ff00)| - ((p 16) 0xff) | - ((p 0xff) 16); -} -} - -static void -fetch_scanline_x8b8g8r8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint32_t *pixel = (uint32_t *)bits + x; -const uint32_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - - *buffer++ = 0xff00 | - (p 0xff00)| - ((p 16) 0xff) | - ((p 0xff) 16); -} -} - -static void -fetch_scanline_b8g8r8a8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint32_t *pixel = (uint32_t *)bits + x; -const uint32_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - - *buffer++ = (((p 0xff00) 24) | -((p 0x00ff) 8)| -((p 0xff00) 8)| -((p 0x00ff) 24)); -} -} - -static void -fetch_scanline_b8g8r8x8
[Pixman] [PATCH 05/11] Use MAKE_ACCESSORS() to generate accessors for all the 16bpp formats
From: Søren Sandmann Pedersen s...@redhat.com Add support for 16bpp pixels to fetch_and_convert_pixel() and convert_and_store_pixel(), then use MAKE_ACCESSORS() to generate accessors for all the 16bpp formats: r5g6b5 b5g6r5 a1r5g5b5 x1r5g5b5 a1b5g5r5 x1b5g5r5 a4r4g4b4 x4r4g4b4 a4b4g4r4 x4b4g4r4 --- pixman/pixman-access.c | 658 ++-- 1 files changed, 18 insertions(+), 640 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index f8d6082..7295a22 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -207,6 +207,10 @@ fetch_and_convert_pixel (pixman_image_t* image, switch (PIXMAN_FORMAT_BPP (format)) { +case 16: + pixel = READ (image, (uint16_t *)bits); + break; + case 32: pixel = READ (image, (uint32_t *)bits); break; @@ -229,6 +233,10 @@ convert_and_store_pixel (bits_image_t *image, switch (PIXMAN_FORMAT_BPP (format)) { +case 16: + WRITE (image, (uint16_t *)dest, converted 0x); + break; + case 32: WRITE (image, (uint32_t *)dest, converted); break; @@ -316,6 +324,16 @@ MAKE_ACCESSORS(b8g8r8a8); MAKE_ACCESSORS(b8g8r8x8); MAKE_ACCESSORS(r8g8b8x8); MAKE_ACCESSORS(r8g8b8a8); +MAKE_ACCESSORS(r5g6b5); +MAKE_ACCESSORS(b5g6r5); +MAKE_ACCESSORS(a1r5g5b5); +MAKE_ACCESSORS(x1r5g5b5); +MAKE_ACCESSORS(a1b5g5r5); +MAKE_ACCESSORS(x1b5g5r5); +MAKE_ACCESSORS(a4r4g4b4); +MAKE_ACCESSORS(x4r4g4b4); +MAKE_ACCESSORS(a4b4g4r4); +MAKE_ACCESSORS(x4b4g4r4); /** Fetch / @@ -506,261 +524,6 @@ fetch_scanline_b8g8r8 (pixman_image_t *image, } static void -fetch_scanline_r5g6b5 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint16_t *pixel = (const uint16_t *)bits + x; -const uint16_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - uint32_t r = (((p) 3) 0xf8) | - (((p) 5) 0xfc00) | - (((p) 8) 0xf8); - - r |= (r 5) 0x70007; - r |= (r 6) 0x300; - - *buffer++ = 0xff00 | r; -} -} - -static void -fetch_scanline_b5g6r5 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint16_t *pixel = (const uint16_t *)bits + x; -const uint16_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - uint32_t r, g, b; - - b = ((p 0xf800) | ((p 0xe000) 5)) 8; - g = ((p 0x07e0) | ((p 0x0600) 6)) 5; - r = ((p 0x001c) | ((p 0x001f) 5)) 14; - - *buffer++ = 0xff00 | r | g | b; -} -} - -static void -fetch_scanline_a1r5g5b5 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint16_t *pixel = (const uint16_t *)bits + x; -const uint16_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - uint32_t r, g, b, a; - - a = (uint32_t) ((uint8_t) (0 - ((p 0x8000) 15))) 24; - r = ((p 0x7c00) | ((p 0x7000) 5)) 9; - g = ((p 0x03e0) | ((p 0x0380) 5)) 6; - b = ((p 0x001c) | ((p 0x001f) 5)) 2; - - *buffer++ = a | r | g | b; -} -} - -static void -fetch_scanline_x1r5g5b5 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint16_t *pixel = (const uint16_t *)bits + x; -const uint16_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - uint32_t r, g, b; - - r = ((p 0x7c00) | ((p 0x7000) 5)) 9; - g = ((p 0x03e0) | ((p 0x0380) 5)) 6; - b = ((p 0x001c) | ((p 0x001f) 5)) 2; - - *buffer++ = 0xff00 | r | g | b; -} -} - -static void
[Pixman] [PATCH 06/11] Use MAKE_ACCESSORS() to generate accessors for 8bpp RGB formats
From: Søren Sandmann Pedersen s...@redhat.com Add support for 8 bpp formats to fetch_and_convert_pixel() and convert_and_store_pixel(), then use MAKE_ACCESSORS() to generate the accessors for all the 8 bpp formats, except g8 and c8, which are indexed: a8 r3g3b2 b2g3r3 a2r2g2b2 a2b2g2r2 x4a4 --- pixman/pixman-access.c | 396 ++-- 1 files changed, 14 insertions(+), 382 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 7295a22..b0e27ee 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -207,6 +207,10 @@ fetch_and_convert_pixel (pixman_image_t* image, switch (PIXMAN_FORMAT_BPP (format)) { +case 8: + pixel = READ (image, bits); + break; + case 16: pixel = READ (image, (uint16_t *)bits); break; @@ -233,6 +237,10 @@ convert_and_store_pixel (bits_image_t *image, switch (PIXMAN_FORMAT_BPP (format)) { +case 8: + WRITE (image, dest, converted 0xff); + break; + case 16: WRITE (image, (uint16_t *)dest, converted 0x); break; @@ -334,6 +342,12 @@ MAKE_ACCESSORS(a4r4g4b4); MAKE_ACCESSORS(x4r4g4b4); MAKE_ACCESSORS(a4b4g4r4); MAKE_ACCESSORS(x4b4g4r4); +MAKE_ACCESSORS(a8); +MAKE_ACCESSORS(r3g3b2); +MAKE_ACCESSORS(b2g3r3); +MAKE_ACCESSORS(a2r2g2b2); +MAKE_ACCESSORS(a2b2g2r2); +MAKE_ACCESSORS(x4a4); /** Fetch / @@ -524,138 +538,6 @@ fetch_scanline_b8g8r8 (pixman_image_t *image, } static void -fetch_scanline_a8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint8_t *pixel = (const uint8_t *)bits + x; -const uint8_t *end = pixel + width; - -while (pixel end) - *buffer++ = READ (image, pixel++) 24; -} - -static void -fetch_scanline_r3g3b2 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint8_t *pixel = (const uint8_t *)bits + x; -const uint8_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - uint32_t r, g, b; - - r = ((p 0xe0) | ((p 0xe0) 3) | ((p 0xc0) 6)) 16; - g = ((p 0x1c) | ((p 0x18) 3) | ((p 0x1c) 3)) 8; - b = (((p 0x03) ) | -((p 0x03) 2) | -((p 0x03) 4) | -((p 0x03) 6)); - - *buffer++ = 0xff00 | r | g | b; -} -} - -static void -fetch_scanline_b2g3r3 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint8_t *pixel = (const uint8_t *)bits + x; -const uint8_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - uint32_t r, g, b; - - b = p 0xc0; - b |= b 2; - b |= b 4; - b = 0xff; - - g = (p 0x38) 10; - g |= g 3; - g |= g 6; - g = 0xff00; - - r = (p 0x7) 21; - r |= r 3; - r |= r 6; - r = 0xff; - - *buffer++ = 0xff00 | r | g | b; -} -} - -static void -fetch_scanline_a2r2g2b2 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint8_t *pixel = (const uint8_t *)bits + x; -const uint8_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - uint32_t a, r, g, b; - - a = ((p 0xc0) * 0x55) 18; - r = ((p 0x30) * 0x55) 12; - g = ((p 0x0c) * 0x55) 6; - b = ((p 0x03) * 0x55); - - *buffer++ = a | r | g | b; -} -} - -static void -fetch_scanline_a2b2g2r2 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits
[Pixman] [PATCH 08/11] Use MAKE_ACCESSORS() to generate accessors for 24bpp formats
From: Søren Sandmann Pedersen s...@redhat.com Add FETCH_24 and STORE_24 macros and use them to add support for 24bpp pixels in fetch_and_convert_pixel() and convert_and_store_pixel(). Then use MAKE_ACCESSORS() to generate accessors for the 24 bpp formats: r8g8b8 b8g8r8 --- pixman/pixman-access.c | 199 +++- 1 files changed, 46 insertions(+), 153 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index b107d3b..30544e4 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -66,6 +66,18 @@ (((4 * (o)) 4) ? (FETCH_8 (img, l, 4 * (o)) 4) : (FETCH_8 (img, l, (4 * (o))) 0xf)) #endif +#ifdef WORDS_BIGENDIAN +#define FETCH_24(img,l,o) \ +((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) 16)| \ + (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) 8) | \ + (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) 0)) +#else +#define FETCH_24(img,l,o) \ +((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) 0) | \ + (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) 8) | \ + (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) 16)) +#endif + /* Store macros */ #define STORE_8(img,l,o,v) (WRITE (img, (uint8_t *)(l) + ((o) 3), (v))) @@ -96,6 +108,30 @@ } while (0) #endif +#ifdef WORDS_BIGENDIAN +#define STORE_24(img,l,o,v)\ +do \ +{ \ + uint8_t *__tmp = (l) + 3 * (o);\ + \ + WRITE ((img), __tmp++, ((v) 0x00ff) 16); \ + WRITE ((img), __tmp++, ((v) 0xff00) 8); \ + WRITE ((img), __tmp++, ((v) 0x00ff) 0); \ +} \ +while (0) +#else +#define STORE_24(img,l,o,v)\ +do \ +{ \ + uint8_t *__tmp = (l) + 3 * (o);\ + \ + WRITE ((img), __tmp++, ((v) 0x00ff) 0); \ + WRITE ((img), __tmp++, ((v) 0xff00) 8); \ + WRITE ((img), __tmp++, ((v) 0x00ff) 16); \ +} \ +while (0) +#endif + /* * YV12 setup and access macros */ @@ -262,6 +298,10 @@ fetch_and_convert_pixel (pixman_image_t* image, pixel = READ (image, ((uint16_t *)bits + offset)); break; +case 24: + pixel = FETCH_24 (image, bits, offset); + break; + case 32: pixel = READ (image, ((uint32_t *)bits + offset)); break; @@ -297,6 +337,10 @@ convert_and_store_pixel (bits_image_t *image, WRITE (image, ((uint16_t *)dest + offset), converted 0x); break; +case 24: + STORE_24 (image, dest, offset, converted); + break; + case 32: WRITE (image, ((uint32_t *)dest + offset), converted); break; @@ -368,6 +412,8 @@ MAKE_ACCESSORS(b8g8r8a8); MAKE_ACCESSORS(b8g8r8x8); MAKE_ACCESSORS(r8g8b8x8); MAKE_ACCESSORS(r8g8b8a8); +MAKE_ACCESSORS(r8g8b8); +MAKE_ACCESSORS(b8g8r8); MAKE_ACCESSORS(r5g6b5); MAKE_ACCESSORS(b5g6r5); MAKE_ACCESSORS(a1r5g5b5); @@ -521,64 +567,6 @@ fetch_scanline_x2b10g10r10 (pixman_image_t *image, } static void -fetch_scanline_r8g8b8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const uint8_t *pixel = (const uint8_t *)bits + 3 * x; -const uint8_t *end = pixel + 3 * width; - -while (pixel end) -{ - uint32_t b = 0xff00; - -#ifdef WORDS_BIGENDIAN - b |= (READ (image, pixel++) 16); - b |= (READ (image, pixel++) 8); - b |= (READ (image, pixel++)); -#else - b |= (READ (image, pixel++)); - b |= (READ (image, pixel++) 8); - b |= (READ (image, pixel++) 16); -#endif - - *buffer++ = b; -} -} - -static void -fetch_scanline_b8g8r8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask
[Pixman] [PATCH 09/11] Use MAKE_ACCESSORS() to generate accessors for the a1 format.
From: Søren Sandmann Pedersen s...@redhat.com Add FETCH_1 and STORE_1 macros and use them to add support for 1bpp pixels to fetch_and_convert_pixel() and convert_and_store_pixel(), then use MAKE_ACCESSORS() to generate the accessors for the a1 format. (Not the g1 format as it is indexed). --- pixman/pixman-access.c | 125 ++-- 1 files changed, 46 insertions(+), 79 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 30544e4..d7e0d08 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -56,6 +56,14 @@ /* Fetch macros */ +#ifdef WORDS_BIGENDIAN +#define FETCH_1(img,l,o) \ +(((READ ((img), ((uint32_t *)(l)) + ((o) 5))) (0x1f - ((o) 0x1f))) 0x1) +#else +#define FETCH_1(img,l,o) \ +READ ((img), ((uint32_t *)(l)) + ((o) 5))) ((o) 0x1f))) 0x1) +#endif + #define FETCH_8(img,l,o)(READ (img, (((uint8_t *)(l)) + ((o) 3 #ifdef WORDS_BIGENDIAN @@ -80,6 +88,34 @@ /* Store macros */ +#ifdef WORDS_BIGENDIAN +#define STORE_1(img,l,o,v) \ +do \ +{ \ + uint32_t *__d = ((uint32_t *)(l)) + ((o) 5);\ + uint32_t __m, __v; \ + \ + __m = 1 (0x1f - ((o) 0x1f)); \ + __v = (v)? __m : 0; \ + \ + WRITE((img), __d, (READ((img), __d) ~__m) | __v); \ +} \ +while (0) +#else +#define STORE_1(img,l,o,v) \ +do \ +{ \ + uint32_t *__d = ((uint32_t *)(l)) + ((o) 5);\ + uint32_t __m, __v; \ + \ + __m = 1 ((o) 0x1f);\ + __v = (v)? __m : 0; \ + \ + WRITE((img), __d, (READ((img), __d) ~__m) | __v); \ +} \ +while (0) +#endif + #define STORE_8(img,l,o,v) (WRITE (img, (uint8_t *)(l) + ((o) 3), (v))) #ifdef WORDS_BIGENDIAN @@ -128,7 +164,7 @@ WRITE ((img), __tmp++, ((v) 0x00ff) 0); \ WRITE ((img), __tmp++, ((v) 0xff00) 8); \ WRITE ((img), __tmp++, ((v) 0x00ff) 16); \ -} \ +} \ while (0) #endif @@ -286,6 +322,10 @@ fetch_and_convert_pixel (pixman_image_t* image, switch (PIXMAN_FORMAT_BPP (format)) { +case 1: + pixel = FETCH_1 (image, bits, offset); + break; + case 4: pixel = FETCH_4 (image, bits, offset); break; @@ -325,6 +365,10 @@ convert_and_store_pixel (bits_image_t *image, switch (PIXMAN_FORMAT_BPP (format)) { +case 1: + STORE_1 (image, dest, offset, converted 0x01); + break; + case 4: STORE_4 (image, dest, offset, converted 0xf); break; @@ -435,6 +479,7 @@ MAKE_ACCESSORS(r1g2b1); MAKE_ACCESSORS(b1g2r1); MAKE_ACCESSORS(a1r1g1b1); MAKE_ACCESSORS(a1b1g1r1); +MAKE_ACCESSORS(a1); /** Fetch / @@ -608,36 +653,6 @@ fetch_scanline_c4 (pixman_image_t *image, } static void -fetch_scanline_a1 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -int i; - -for (i = 0; i width; ++i) -{ - uint32_t p = READ (image, bits + ((i + x) 5)); - uint32_t a; - -#ifdef WORDS_BIGENDIAN - a = p (0x1f - ((i + x) 0x1f)); -#else - a = p ((i + x) 0x1f); -#endif - a = a 1; - a |= a 1; - a |= a 2; - a |= a 4; - - *buffer++ = a 24; -} -} - -static void fetch_scanline_g1 (pixman_image_t *image, int x
[Pixman] [PATCH 10/11] Use MAKE_ACCESSORS() to generate accessors for paletted formats
From: Søren Sandmann Pedersen s...@redhat.com Add support in convert_pixel_from_a8r8g8b8() and convert_pixel_to_a8r8g8b8() for conversion to/from paletted formats, then use MAKE_ACCESSORS() to generate accessors for the indexed formats: c8, g8, g4, c4, g1 --- pixman/pixman-access.c | 276 1 files changed, 46 insertions(+), 230 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index d7e0d08..189b191 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -301,15 +301,41 @@ convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixe } static force_inline uint32_t -convert_pixel_from_a8r8g8b8 (pixman_format_code_t format, uint32_t pixel) +convert_pixel_to_a8r8g8b8 (pixman_image_t *image, + pixman_format_code_t format, + uint32_t pixel) { -return convert_pixel (PIXMAN_a8r8g8b8, format, pixel); +if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY|| + PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR) +{ + return image-bits.indexed-rgba[pixel]; +} +else +{ + return convert_pixel (format, PIXMAN_a8r8g8b8, pixel); +} } static force_inline uint32_t -convert_pixel_to_a8r8g8b8 (pixman_format_code_t format, uint32_t pixel) +convert_pixel_from_a8r8g8b8 (pixman_image_t *image, +pixman_format_code_t format, uint32_t pixel) { -return convert_pixel (format, PIXMAN_a8r8g8b8, pixel); +if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY) +{ + pixel = CONVERT_RGB24_TO_Y15 (pixel); + + return image-bits.indexed-ent[pixel 0x7fff]; +} +else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR) +{ + pixel = convert_pixel (PIXMAN_a8r8g8b8, PIXMAN_x1r5g5b5, pixel); + + return image-bits.indexed-ent[pixel 0x7fff]; +} +else +{ + return convert_pixel (PIXMAN_a8r8g8b8, format, pixel); +} } static force_inline uint32_t @@ -351,7 +377,7 @@ fetch_and_convert_pixel (pixman_image_t * image, break; } -return convert_pixel_to_a8r8g8b8 (format, pixel); +return convert_pixel_to_a8r8g8b8 (image, format, pixel); } static force_inline void @@ -361,7 +387,8 @@ convert_and_store_pixel (bits_image_t * image, pixman_format_code_t format, uint32_t pixel) { -uint32_t converted = convert_pixel_from_a8r8g8b8 (format, pixel); +uint32_t converted = convert_pixel_from_a8r8g8b8 ( + (pixman_image_t *)image, format, pixel); switch (PIXMAN_FORMAT_BPP (format)) { @@ -469,17 +496,22 @@ MAKE_ACCESSORS(x4r4g4b4); MAKE_ACCESSORS(a4b4g4r4); MAKE_ACCESSORS(x4b4g4r4); MAKE_ACCESSORS(a8); +MAKE_ACCESSORS(c8); +MAKE_ACCESSORS(g8); MAKE_ACCESSORS(r3g3b2); MAKE_ACCESSORS(b2g3r3); MAKE_ACCESSORS(a2r2g2b2); MAKE_ACCESSORS(a2b2g2r2); MAKE_ACCESSORS(x4a4); MAKE_ACCESSORS(a4); +MAKE_ACCESSORS(g4); +MAKE_ACCESSORS(c4); MAKE_ACCESSORS(r1g2b1); MAKE_ACCESSORS(b1g2r1); MAKE_ACCESSORS(a1r1g1b1); MAKE_ACCESSORS(a1b1g1r1); MAKE_ACCESSORS(a1); +MAKE_ACCESSORS(g1); /** Fetch / @@ -612,75 +644,6 @@ fetch_scanline_x2b10g10r10 (pixman_image_t *image, } static void -fetch_scanline_c8 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const pixman_indexed_t * indexed = image-bits.indexed; -const uint8_t *pixel = (const uint8_t *)bits + x; -const uint8_t *end = pixel + width; - -while (pixel end) -{ - uint32_t p = READ (image, pixel++); - - *buffer++ = indexed-rgba[p]; -} -} - -static void -fetch_scanline_c4 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const pixman_indexed_t * indexed = image-bits.indexed; -int i; - -for (i = 0; i width; ++i) -{ - uint32_t p = FETCH_4 (image, bits, i + x); - - *buffer++ = indexed-rgba[p]; -} -} - -static void -fetch_scanline_g1 (pixman_image_t *image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ -const uint32_t *bits = image-bits.bits + y * image-bits.rowstride; -const pixman_indexed_t * indexed = image-bits.indexed; -int i
[Pixman] [PATCH 11/11] Add some fast paths to convert_pixel()
From: Søren Sandmann Pedersen s...@redhat.com All the inlining going on makes gcc generate slightly suboptimal code, so add some special cases for the common formats a8r8g8b8, x8r8g8b8, a8, and r5g6b5. --- pixman/pixman-access.c | 53 1 files changed, 53 insertions(+), 0 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 189b191..9ebcc1f 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -271,6 +271,56 @@ convert_channel (uint32_t pixel, uint32_t def_value, return (v ((1 n_to_bits) - 1)) to_shift; } +static force_inline pixman_bool_t +convert_special_cases (pixman_format_code_t from, pixman_format_code_t to, uint32_t *pixel) +{ +/* A couple of special cases for performance */ +if ((from == to) || (from == PIXMAN_a8r8g8b8 to == PIXMAN_x8r8g8b8)) +{ + return TRUE; +} +else if (from == PIXMAN_x8r8g8b8 to == PIXMAN_a8r8g8b8) +{ + *pixel |= 0xff00; + return TRUE; +} +else if (from == PIXMAN_a8 to == PIXMAN_a8r8g8b8) +{ + *pixel = 24; + return TRUE; +} +else if (from == PIXMAN_r5g6b5 to == PIXMAN_a8r8g8b8) +{ + uint32_t r; + + r = ((*pixel 3) 0xf8) | + ((*pixel 5) 0xfc00) | + ((*pixel 8) 0xf8); + + r |= (r 5) 0x70007; + r |= (r 6) 0x300; + + *pixel = r | 0xff00; + return TRUE; +} +else if (from == PIXMAN_a8r8g8b8 to == PIXMAN_a8) +{ + *pixel = 24; + return TRUE; +} +else if (from == PIXMAN_a8r8g8b8 to == PIXMAN_r5g6b5) +{ + *pixel = + ((*pixel 3) 0x001f) | + ((*pixel 5) 0x07e0) | + ((*pixel 8) 0xf800); + + return TRUE; +} + +return FALSE; +} + static force_inline uint32_t convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel) { @@ -278,6 +328,9 @@ convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixe int a_to_shift, r_to_shift, g_to_shift, b_to_shift; uint32_t a, r, g, b; +if (convert_special_cases (from, to, pixel)) + return pixel; + get_shifts (from, a_from_shift, r_from_shift, g_from_shift, b_from_shift); get_shifts (to, a_to_shift, r_to_shift, g_to_shift, b_to_shift); -- 1.7.4 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] test: New function to save a pixman image to .png
From: Søren Sandmann Pedersen s...@redhat.com When debugging it is often very useful to be able to save an image as a png file. This commit adds a function write_png() that does that. If libpng is not available, then the function becomes a noop. --- configure.ac | 11 + test/Makefile.am |2 +- test/utils.c | 112 ++ test/utils.h |3 + 4 files changed, 127 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index 4c62102..a936a6d 100644 --- a/configure.ac +++ b/configure.ac @@ -801,6 +801,17 @@ fi AC_MSG_RESULT($support_for_attribute_constructor) AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR) +dnl == +dnl libpng + +AC_CHECK_LIB([png], [png_write_info], [have_libpng=yes], [have_libpng=no]) + +if test x$have_libpng = xyes; then +AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng]) +fi + +AC_SUBST(HAVE_LIBPNG) + AC_OUTPUT([pixman-1.pc pixman-1-uninstalled.pc Makefile diff --git a/test/Makefile.am b/test/Makefile.am index 9f61fc9..52ef8ad 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,6 @@ AM_CFLAGS = @OPENMP_CFLAGS@ AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@ -LDADD = $(top_builddir)/pixman/libpixman-1.la -lm +LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman TESTPROGRAMS = \ diff --git a/test/utils.c b/test/utils.c index 44188ea..adabd75 100644 --- a/test/utils.c +++ b/test/utils.c @@ -21,6 +21,10 @@ #include fenv.h #endif +#ifdef HAVE_LIBPNG +#include png.h +#endif + /* Random number seed */ @@ -335,6 +339,114 @@ make_random_bytes (int n_bytes) return bytes; } +#ifdef HAVE_LIBPNG + +static void +pngify_pixels (uint32_t *pixels, int n_pixels) +{ +int i; + +for (i = 0; i n_pixels; ++i) +{ + uint32_t p = pixels[i]; + uint8_t *out = (uint8_t *)(pixels[i]); + uint8_t a, r, g, b; + + a = (p 0xff00) 24; + r = (p 0x00ff) 16; + g = (p 0xff00) 8; + b = (p 0x00ff) 0; + + if (a != 0) + { + r = (r * 255) / a; + g = (g * 255) / a; + b = (b * 255) / a; + } + + *out++ = r; + *out++ = g; + *out++ = b; + *out++ = a; +} +} + +pixman_bool_t +write_png (pixman_image_t *image, const char *filename) +{ +int width = pixman_image_get_width (image); +int height = pixman_image_get_height (image); +int stride = width * 4; +uint32_t *data = malloc (height * stride); +pixman_image_t *copy; +png_struct *write_struct; +png_info *info_struct; +pixman_bool_t result = FALSE; +FILE *f = fopen (filename, wb); +png_bytep *row_pointers; +int i; + +if (!f) + return FALSE; + +row_pointers = malloc (height * sizeof (png_bytep)); + +copy = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, width, height, data, stride); + +pixman_image_composite32 ( + PIXMAN_OP_SRC, image, NULL, copy, 0, 0, 0, 0, 0, 0, width, height); + +pngify_pixels (data, height * width); + +for (i = 0; i height; ++i) + row_pointers[i] = (png_bytep)(data + i * width); + +if (!(write_struct = png_create_write_struct ( + PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) + goto out1; + +if (!(info_struct = png_create_info_struct (write_struct))) + goto out2; + +png_init_io (write_struct, f); + +png_set_IHDR (write_struct, info_struct, width, height, + 8, PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + +png_write_info (write_struct, info_struct); + +png_write_image (write_struct, row_pointers); + +png_write_end (write_struct, NULL); + +result = TRUE; + +out2: +png_destroy_write_struct (write_struct, info_struct); + +out1: +if (fclose (f) != 0) + result = FALSE; + +pixman_image_unref (copy); +free (row_pointers); +free (data); +return result; +} + +#else /* no libpng */ + +pixman_bool_t +write_png (pixman_image_t *image, const char *filename) +{ +return FALSE; +} + +#endif + /* * A function, which can be used as a core part of the test programs, * intended to detect various problems with the help of fuzzing input diff --git a/test/utils.h b/test/utils.h index f0c9c30..3790483 100644 --- a/test/utils.h +++ b/test/utils.h @@ -105,6 +105,9 @@ fail_after (int seconds, const char *msg); /* If possible, enable traps for floating point exceptions */ void enable_fp_exceptions(void); +pixman_bool_t +write_png (pixman_image_t *image, const char *filename); + /* A pair of macros which can help to detect corruption of * floating point registers after a function call. This may * happen if _mm_empty() call is forgotten in MMX/SSE2 fast -- 1.6.0.6
[Pixman] [PATCH] Eliminate compute_sample_extents() function
From: Søren Sandmann Pedersen s...@redhat.com In analyze_extents(), instead of calling compute_sample_extents() twice, just call compute_transformed_extents() once. Instead of calling compute_sample_extents() for the destination rectangle expanded by one, just call compute_transformed_extents() and expand the returned rectangle by adding the absolute values of the 00 and 10 entries in the transformation, then check if the results fit in 16 bits. This is a little bit more conservative than necessary, but only corner cases where we are already close to the limit of the 16 bit coordinate space are affected. The rest of the compute_sample_extents() function can now just be inlined into analyze_extents(), and compute_sample_extents() can be deleted. --- pixman/pixman.c | 94 +-- 1 files changed, 36 insertions(+), 58 deletions(-) diff --git a/pixman/pixman.c b/pixman/pixman.c index 264a56b..3ecd311 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -514,45 +514,9 @@ compute_transformed_extents (pixman_transform_t *transform, return TRUE; } -static pixman_bool_t -compute_sample_extents (pixman_transform_t *transform, - pixman_box32_t *extents, - pixman_fixed_t x_off, pixman_fixed_t y_off, - pixman_fixed_t width, pixman_fixed_t height) -{ -box_48_16_t transformed; - -if (!compute_transformed_extents (transform, extents, transformed)) - return FALSE; - -/* Expand the source area by a tiny bit so account of different rounding that - * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from - * 0.5 so this won't cause the area computed to be overly pessimistic. - */ -transformed.x1 += x_off - 8 * pixman_fixed_e; -transformed.y1 += y_off - 8 * pixman_fixed_e; -transformed.x2 += x_off + width + 8 * pixman_fixed_e; -transformed.y2 += y_off + height + 8 * pixman_fixed_e; - -if (transformed.x1 pixman_min_fixed_48_16 || transformed.x1 pixman_max_fixed_48_16 || - transformed.y1 pixman_min_fixed_48_16 || transformed.y1 pixman_max_fixed_48_16 || - transformed.x2 pixman_min_fixed_48_16 || transformed.x2 pixman_max_fixed_48_16 || - transformed.y2 pixman_min_fixed_48_16 || transformed.y2 pixman_max_fixed_48_16) -{ - return FALSE; -} -else -{ - extents-x1 = pixman_fixed_to_int (transformed.x1); - extents-y1 = pixman_fixed_to_int (transformed.y1); - extents-x2 = pixman_fixed_to_int (transformed.x2) + 1; - extents-y2 = pixman_fixed_to_int (transformed.y2) + 1; - - return TRUE; -} -} - #define IS_16BIT(x) (((x) = INT16_MIN) ((x) = INT16_MAX)) +#define ABS(f) (((f) 0)? (-(f)) : (f)) +#define IS_16_16(f) (((f) = pixman_min_fixed_48_16 ((f) = pixman_max_fixed_48_16))) static pixman_bool_t analyze_extent (pixman_image_t *image, @@ -563,7 +527,8 @@ analyze_extent (pixman_image_t *image, pixman_fixed_t *params; pixman_fixed_t x_off, y_off; pixman_fixed_t width, height; -pixman_box32_t ex; +pixman_fixed_t m00, m10; +box_48_16_t transformed; if (!image) return TRUE; @@ -633,17 +598,6 @@ analyze_extent (pixman_image_t *image, default: return FALSE; } - - /* Check whether the non-expanded, transformed extent is entirely within -* the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is. -*/ - ex = *extents; - if (compute_sample_extents (transform, ex, x_off, y_off, width, height) - ex.x1 = 0 ex.y1 = 0 - ex.x2 = image-bits.width ex.y2 = image-bits.height) - { - *flags |= FAST_PATH_SAMPLES_COVER_CLIP; - } } else { @@ -653,17 +607,41 @@ analyze_extent (pixman_image_t *image, height = 0; } -/* Check that the extents expanded by one don't overflow. This ensures that - * compositing functions can simply walk the source space using 16.16 - * variables without worrying about overflow. +if (!compute_transformed_extents (transform, extents, transformed)) + return FALSE; + +/* Expand the source area by a tiny bit so account of different rounding that + * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from + * 0.5 so this won't cause the area computed to be overly pessimistic. + */ +transformed.x1 += x_off - 8 * pixman_fixed_e; +transformed.y1 += y_off - 8 * pixman_fixed_e; +transformed.x2 += x_off + width + 8 * pixman_fixed_e; +transformed.y2 += y_off + height + 8 * pixman_fixed_e; + +/* Check we don't overflow when the destination extents are expanded by one. + * This ensures that compositing functions can simply walk the source space + * using 16.16 variables without worrying about overflow. */ -ex.x1 = extents-x1 - 1; -ex.y1
[Pixman] [PATCH] Split computation of sample area into own function
From: Søren Sandmann Pedersen s...@redhat.com compute_sample_extents() have two parts: one that computes the transformed extents, and one that checks whether the computed extents fit within the 16.16 coordinate space. Split the first part into its own function compute_transformed_extents(). --- pixman/pixman.c | 138 ++- 1 files changed, 76 insertions(+), 62 deletions(-) diff --git a/pixman/pixman.c b/pixman/pixman.c index 9af6e2f..264a56b 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -446,93 +446,107 @@ update_cache: return TRUE; } +typedef struct +{ +pixman_fixed_48_16_t x1; +pixman_fixed_48_16_t y1; +pixman_fixed_48_16_t x2; +pixman_fixed_48_16_t y2; +} box_48_16_t; + static pixman_bool_t -compute_sample_extents (pixman_transform_t *transform, - pixman_box32_t *extents, - pixman_fixed_t x_off, pixman_fixed_t y_off, - pixman_fixed_t width, pixman_fixed_t height) +compute_transformed_extents (pixman_transform_t *transform, +const pixman_box32_t *extents, +box_48_16_t *transformed) { -pixman_fixed_t x1, y1, x2, y2; pixman_fixed_48_16_t tx1, ty1, tx2, ty2; +pixman_fixed_t x1, y1, x2, y2; +int i; -/* We have checked earlier that (extents-x1 - x) etc. fit in a pixman_fixed_t */ -x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents-x1) + pixman_fixed_1 / 2; -y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents-y1) + pixman_fixed_1 / 2; -x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents-x2) - pixman_fixed_1 / 2; -y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents-y2) - pixman_fixed_1 / 2; +x1 = pixman_int_to_fixed (extents-x1) + pixman_fixed_1 / 2; +y1 = pixman_int_to_fixed (extents-y1) + pixman_fixed_1 / 2; +x2 = pixman_int_to_fixed (extents-x2) - pixman_fixed_1 / 2; +y2 = pixman_int_to_fixed (extents-y2) - pixman_fixed_1 / 2; if (!transform) { - tx1 = (pixman_fixed_48_16_t)x1; - ty1 = (pixman_fixed_48_16_t)y1; - tx2 = (pixman_fixed_48_16_t)x2; - ty2 = (pixman_fixed_48_16_t)y2; + transformed-x1 = x1; + transformed-y1 = y1; + transformed-x2 = x2; + transformed-y2 = y2; + + return TRUE; } -else + +tx1 = ty1 = INT64_MAX; +tx2 = ty2 = INT64_MIN; + +for (i = 0; i 4; ++i) { - int i; + pixman_fixed_48_16_t tx, ty; + pixman_vector_t v; - /* Silence GCC */ - tx1 = ty1 = tx2 = ty2 = 0; + v.vector[0] = (i 0x01)? x1 : x2; + v.vector[1] = (i 0x02)? y1 : y2; + v.vector[2] = pixman_fixed_1; - for (i = 0; i 4; ++i) - { - pixman_fixed_48_16_t tx, ty; - pixman_vector_t v; + if (!pixman_transform_point (transform, v)) + return FALSE; - v.vector[0] = (i 0x01)? x1 : x2; - v.vector[1] = (i 0x02)? y1 : y2; - v.vector[2] = pixman_fixed_1; + tx = (pixman_fixed_48_16_t)v.vector[0]; + ty = (pixman_fixed_48_16_t)v.vector[1]; + + if (tx tx1) + tx1 = tx; + if (ty ty1) + ty1 = ty; + if (tx tx2) + tx2 = tx; + if (ty ty2) + ty2 = ty; +} - if (!pixman_transform_point (transform, v)) - return FALSE; +transformed-x1 = tx1; +transformed-y1 = ty1; +transformed-x2 = tx2; +transformed-y2 = ty2; - tx = (pixman_fixed_48_16_t)v.vector[0]; - ty = (pixman_fixed_48_16_t)v.vector[1]; +return TRUE; +} - if (i == 0) - { - tx1 = tx; - ty1 = ty; - tx2 = tx; - ty2 = ty; - } - else - { - if (tx tx1) - tx1 = tx; - if (ty ty1) - ty1 = ty; - if (tx tx2) - tx2 = tx; - if (ty ty2) - ty2 = ty; - } - } -} +static pixman_bool_t +compute_sample_extents (pixman_transform_t *transform, + pixman_box32_t *extents, + pixman_fixed_t x_off, pixman_fixed_t y_off, + pixman_fixed_t width, pixman_fixed_t height) +{ +box_48_16_t transformed; + +if (!compute_transformed_extents (transform, extents, transformed)) + return FALSE; /* Expand the source area by a tiny bit so account of different rounding that * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from * 0.5 so this won't cause the area computed to be overly pessimistic. */ -tx1 += x_off - 8 * pixman_fixed_e; -ty1 += y_off - 8 * pixman_fixed_e; -tx2 += x_off + width + 8 * pixman_fixed_e; -ty2 += y_off + height + 8 * pixman_fixed_e; - -if (tx1
[Pixman] [PATCH] test: better coverage for BILINEAR-NEAREST filter optimization
From: Siarhei Siamashka siarhei.siamas...@nokia.com The upcoming optimization which is going to be able to replace BILINEAR filter with NEAREST where appropriate needs to analyze the transformation matrix and not to make any mistakes. The changes to affine-test include: 1. Higher chance of using the same scale factor for x and y axes. This can help to stress some special cases (for example the case when both x and y scale factors are integer). The same applies to x/y translation. 2. Introduced a small chance for corrupting transformation matrix by flipping random bits. This supposedly can help to identify the cases when some of the fast paths or other code logic is wrongly activated due to insufficient checks. --- test/affine-test.c | 36 ++-- 1 files changed, 30 insertions(+), 6 deletions(-) diff --git a/test/affine-test.c b/test/affine-test.c index ed8000c..ddeca56 100644 --- a/test/affine-test.c +++ b/test/affine-test.c @@ -100,13 +100,22 @@ test_composite (int testnum, pixman_transform_init_identity (transform); -if (lcg_rand_n (8) 0) +if (lcg_rand_n (3) 0) { - scale_x = -32768 * 3 + lcg_rand_N (65536 * 5); - scale_y = -32768 * 3 + lcg_rand_N (65536 * 5); - translate_x = lcg_rand_N (65536); - translate_y = lcg_rand_N (65536); + scale_x = -65536 * 3 + lcg_rand_N (65536 * 6); + if (lcg_rand_n (2)) + scale_y = -65536 * 3 + lcg_rand_N (65536 * 6); + else + scale_y = scale_x; pixman_transform_init_scale (transform, scale_x, scale_y); +} +if (lcg_rand_n (3) 0) +{ + translate_x = -65536 * 3 + lcg_rand_N (6 * 65536); + if (lcg_rand_n (2)) + translate_y = -65536 * 3 + lcg_rand_N (6 * 65536); + else + translate_y = translate_x; pixman_transform_translate (transform, NULL, translate_x, translate_y); } @@ -144,6 +153,21 @@ test_composite (int testnum, pixman_transform_translate (transform, NULL, tx, ty); } +if (lcg_rand_n (8) == 0) +{ + /* Flip random bits */ + int maxflipcount = 8; + while (maxflipcount--) + { + int i = lcg_rand_n (2); + int j = lcg_rand_n (3); + int bitnum = lcg_rand_n (32); + transform.matrix[i][j] ^= 1 bitnum; + if (lcg_rand_n (2)) + break; + } +} + pixman_image_set_transform (src_img, transform); switch (lcg_rand_n (4)) @@ -282,6 +306,6 @@ main (int argc, const char *argv[]) { pixman_disable_out_of_bounds_workaround (); -return fuzzer_test_main (affine, 800, 0x4B5D1852, +return fuzzer_test_main (affine, 800, 0x02A33034, test_composite, argc, argv); } -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] BILINEAR-NEAREST filter optimization for simple rotation and translation
From: Siarhei Siamashka siarhei.siamas...@nokia.com Simple rotation and translation are the additional cases when BILINEAR filter can be safely reduced to NEAREST. --- pixman/pixman-image.c | 39 ++- 1 files changed, 38 insertions(+), 1 deletions(-) diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 88262f7..a3bb9b6 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -251,9 +251,46 @@ compute_image_info (pixman_image_t *image) case PIXMAN_FILTER_BEST: flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); - /* Reduce BILINEAR to NEAREST for identity transforms */ + /* Here we have a chance to optimize BILINEAR filter to NEAREST if +* they are equivalent for the currently used transformation matrix. +*/ if (flags FAST_PATH_ID_TRANSFORM) + { flags |= FAST_PATH_NEAREST_FILTER; + } + else if ( + /* affine and integer translation components in matrix ... */ + ((flags FAST_PATH_AFFINE_TRANSFORM) +!pixman_fixed_frac (image-common.transform-matrix[0][2] | +image-common.transform-matrix[1][2])) + ( + /* ... combined with a simple rotation */ + (flags (FAST_PATH_ROTATE_90_TRANSFORM | + FAST_PATH_ROTATE_180_TRANSFORM | + FAST_PATH_ROTATE_270_TRANSFORM)) || + /* ... or combined with a simple non-rotated translation */ + (image-common.transform-matrix[0][0] == pixman_fixed_1 +image-common.transform-matrix[1][1] == pixman_fixed_1 +image-common.transform-matrix[0][1] == 0 +image-common.transform-matrix[1][0] == 0) + ) + ) + { + /* FIXME: there are some affine-test failures, showing that +* handling of BILINEAR and NEAREST filter is not quite +* equivalent when getting close to 32K for the translation +* components of the matrix. That's likely some bug, but for +* now just skip BILINEAR-NEAREST optimization in this case. +*/ + pixman_fixed_t magic_limit = pixman_int_to_fixed (3); + if (image-common.transform-matrix[0][2] = magic_limit + image-common.transform-matrix[1][2] = magic_limit + image-common.transform-matrix[0][2] = -magic_limit + image-common.transform-matrix[1][2] = -magic_limit) + { + flags |= FAST_PATH_NEAREST_FILTER; + } + } break; case PIXMAN_FILTER_CONVOLUTION: -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Strength-reduce BILINEAR filter to NEAREST filter for identity transforms
From: Søren Sandmann Pedersen s...@redhat.com An image with a bilinear filter and an identity transform is equivalent to one with a nearest filter, so there is no reason the standard fast paths shouldn't be usable. But because a BILINEAR filter samples a 2x2 pixel block in the source image, FAST_PATH_SAMPLES_COVER_CLIP can't be set in the case where the source area is the entire image, because some compositing operations might then read pixels outside the image. This patch fixes the problem by splitting the FAST_PATH_SAMPLES_COVER_CLIP flag into two separate flags FAST_PATH_SAMPLES_COVER_CLIP_NEAREST and FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR that indicate that the clip covers the samples taking into account NEAREST/BILINEAR filters respectively. All the existing compositing operations that require FAST_PATH_SAMPLES_COVER_CLIP then have their flags modified to pick either COVER_CLIP_NEAREST or COVER_CLIP_BILINEAR depending on which filter they depend on. In compute_image_info() both COVER_CILP_NEAREST and COVER_CLIP_BILINEAR can be set depending on how much room there is around the clip rectangle. Finally, images with an identity transform and a bilinear filter get FAST_PATH_NEAREST_FILTER set as well as FAST_PATH_BILINEAR_FILTER. Performance measurementas with render_bench against Xephyr: Before *** ROUND 1 *** --- Test: Test Xrender doing non-scaled Over blends Time: 5.720 sec. --- Test: Test Xrender (offscreen) doing non-scaled Over blends Time: 5.149 sec. --- Test: Test Imlib2 doing non-scaled Over blends Time: 6.237 sec. After: *** ROUND 1 *** --- Test: Test Xrender doing non-scaled Over blends Time: 4.947 sec. --- Test: Test Xrender (offscreen) doing non-scaled Over blends Time: 4.487 sec. --- Test: Test Imlib2 doing non-scaled Over blends Time: 6.235 sec. --- pixman/pixman-fast-path.c |2 +- pixman/pixman-image.c |4 ++ pixman/pixman-inlines.h | 12 pixman/pixman-private.h | 19 ++-- pixman/pixman.c | 69 5 files changed, 65 insertions(+), 41 deletions(-) diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index bbdc8e8..033efd7 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1764,7 +1764,7 @@ static const pixman_fast_path_t c_fast_paths[] = #define SIMPLE_ROTATE_FLAGS(angle) \ (FAST_PATH_ROTATE_ ## angle ## _TRANSFORM | \ FAST_PATH_NEAREST_FILTER | \ - FAST_PATH_SAMPLES_COVER_CLIP | \ + FAST_PATH_SAMPLES_COVER_CLIP_NEAREST | \ FAST_PATH_STANDARD_FLAGS) #define SIMPLE_ROTATE_FAST_PATH(op,s,d,suffix) \ diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 84bacf8..88262f7 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -250,6 +250,10 @@ compute_image_info (pixman_image_t *image) case PIXMAN_FILTER_GOOD: case PIXMAN_FILTER_BEST: flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); + + /* Reduce BILINEAR to NEAREST for identity transforms */ + if (flags FAST_PATH_ID_TRANSFORM) + flags |= FAST_PATH_NEAREST_FILTER; break; case PIXMAN_FILTER_CONVOLUTION: diff --git a/pixman/pixman-inlines.h b/pixman/pixman-inlines.h index f1e0cbd..3532867 100644 --- a/pixman/pixman-inlines.h +++ b/pixman/pixman-inlines.h @@ -585,7 +585,7 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, #define SIMPLE_NEAREST_FAST_PATH_COVER(op,s,d,func)\ { PIXMAN_OP_ ## op, \ PIXMAN_ ## s, \ - SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP,\ + SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST,\ PIXMAN_null, 0, \ PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op,\ @@ -627,7 +627,7 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, #define SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER(op,s,d,func)\ { PIXMAN_OP_ ## op, \ PIXMAN_ ## s, \ - SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP
[Pixman] [PATCH] Only link with -lpng when libpng is actually available
From: Søren Sandmann Pedersen s...@redhat.com Fixes build on systems that don't have libpng --- configure.ac |1 + test/Makefile.am |5 - 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index 21613e1..fdb2521 100644 --- a/configure.ac +++ b/configure.ac @@ -811,6 +811,7 @@ if test x$have_libpng = xyes; then fi AC_SUBST(HAVE_LIBPNG) +AM_CONDITIONAL(HAVE_LIBPNG, test $have_libpng = yes) AC_OUTPUT([pixman-1.pc pixman-1-uninstalled.pc diff --git a/test/Makefile.am b/test/Makefile.am index 52ef8ad..7bd826e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,9 @@ AM_CFLAGS = @OPENMP_CFLAGS@ AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@ -LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng +LDADD = $(top_builddir)/pixman/libpixman-1.la -lm +if HAVE_LIBPNG +LDADD += -lpng +endif INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman TESTPROGRAMS = \ -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
Re: [Pixman] [PATCH] Only link with -lpng when libpng is actually available
How about using pkg-config to detect the availability of libpng and the flags required to use it? Good idea. New patch to follow. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
[Pixman] [PATCH] Use pkg-config to determine the flags to use with libpng
From: Søren Sandmann Pedersen s...@redhat.com Previously we would unconditionally link with -lpng leading to build failures on systems without libpng. --- configure.ac |2 +- test/Makefile.am |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 21613e1..dc523df 100644 --- a/configure.ac +++ b/configure.ac @@ -804,7 +804,7 @@ AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR) dnl == dnl libpng -AC_CHECK_LIB([png], [png_write_info], [have_libpng=yes], [have_libpng=no]) +PKG_CHECK_MODULES(PNG, [libpng], have_libpng=yes, have_libpng=no) if test x$have_libpng = xyes; then AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng]) diff --git a/test/Makefile.am b/test/Makefile.am index 52ef8ad..6687bed 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,7 +1,7 @@ AM_CFLAGS = @OPENMP_CFLAGS@ AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@ -LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng -INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman +LDADD = $(top_builddir)/pixman/libpixman-1.la -lm @PNG_LIBS@ +INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman @PNG_CFLAGS@ TESTPROGRAMS = \ a1-trap-test\ -- 1.6.0.6 ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
Re: [Pixman] [PATCH 1/3] Add CLEAR and SRC linear interpolation operators
Chris Wilson ch...@chris-wilson.co.uk writes: Cairo, for instance, has a subtly different interpretation of how to use the mask in combination with the Porter-Duff operators. In particular, it has the notion of a clip mask, for which pixman has no parallel. Quoting Soeren: Another aspect is that cairo uses a different rendering equation in some cases. The two equations used are: unbounded: [(src IN shape) OP dest ] LERP_clip dest bounded: [(src OP dest) LERP_shape dest ] LERP_clip dest With shaped clips, the LERP_clip part is taken care of, and the first equation is already directly supported by pixman. The second one could be supported by adding new op_LERP operators that would use the (src OP dest) LERP_shape dest equation. For cairo's purposes, all we need is CLEAR_LERP and SRC_LERP, but I think it could be useful to have the full set of LERP operators. Did you see Taekyun Kim's reply to this? He proposes this API: pixman_image_composite_xrender(op, src, shape, clip, dst) pixman_image_composite_bounded(op, src, shape, clip, dst) pixman_image_composite_simple(op, src, shape, clip, dst) instead, which would add direct one-pass support for all of cairo's compositing schemes, including clip masks. See: http://lists.freedesktop.org/archives/pixman/2011-August/001420.html Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
Re: [Pixman] [PATCH 1/3] Add CLEAR and SRC linear interpolation operators
Chris Wilson ch...@chris-wilson.co.uk writes: Did you see Taekyun Kim's reply to this? He proposes this API: pixman_image_composite_xrender(op, src, shape, clip, dst) pixman_image_composite_bounded(op, src, shape, clip, dst) pixman_image_composite_simple(op, src, shape, clip, dst) instead, which would add direct one-pass support for all of cairo's compositing schemes, including clip masks. You're encoding operator semantics into the function call and adding parameters for the rest? Yes, basically. It's more or less a direct translation of the three compositing equations that cairo uses into function calls. Although pixman could benefit from faster methods of rendering polygons, I do not see this as actually reducing the amount of code inside Cairo as GL is effectively the lowest common demoniator. (Though we desparately need a change in the Render protocol so that we can feed polygons to the server more cheaply and that in turn merits similar changes in pixman.) My gut feeling is that interface is too restrictive. You may as well skip polygon images and go to paths and boolean geometry. In the meantime providing an interface that matches what Cairo uses today is also going to be useful for when you replicate Cairo inside pixman. The proposed interface is basically orthogonal to the question of polygons in pixman. Even without polygons or spans in pixman, the proposed interface is a superset of what cairo needs today in order to implement fill() and stroke() in one pass (after rasterizing the polygons). The polygon question is just about how the shape and clip images could be given in a more efficient manner. The three compositing equations that cairo uses are still the same in either case. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
Re: [Pixman] [PATCH 1/3] Add CLEAR and SRC linear interpolation operators
Chris Wilson ch...@chris-wilson.co.uk writes: On Thu, 15 Sep 2011 13:26:09 +0200, sandm...@cs.au.dk (=?utf-8?Q?S=C3=B8ren?= Sandmann) wrote: Chris Wilson ch...@chris-wilson.co.uk writes: Did you see Taekyun Kim's reply to this? He proposes this API: pixman_image_composite_xrender(op, src, shape, clip, dst) pixman_image_composite_bounded(op, src, shape, clip, dst) pixman_image_composite_simple(op, src, shape, clip, dst) instead, which would add direct one-pass support for all of cairo's compositing schemes, including clip masks. You're encoding operator semantics into the function call and adding parameters for the rest? Yes, basically. It's more or less a direct translation of the three compositing equations that cairo uses into function calls. But why three functions when the difference is the semantics of the operator. Just allow Cairo to pick the operator that corresponds to Cairo's interpretation of op + mask + clip. I guess that makes sense. I'll take a look at the patch sometime next week. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
Re: [Pixman] [PATCH] Fix build on cygwin after commit efdf65c0c4fff551fb3cd9104deda9adb6261e22
Jon TURNEY jon.tur...@dronecode.org.uk writes: libutils depends on pixman and so needs to preceed it in the link order Found by tinderbox, see [1] [1] http://tinderbox.freedesktop.org/builds/2011-09-15-0005/logs/pixman/#build Pushed. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
Re: [Pixman] [PATCH 5/5] Simple repeat: Extend too short source scanlines into temporary buffer
Hi, From: Taekyun Kim tkq@samsung.com Too short scanlines can cause repeat handling overhead and optimized pixman composite functions usually process a bunch of pixels in a single loop iteration it might be beneficial to pre-extend source scanlines. The temporary buffers will usually reside in cache, so accessing them should be quite efficient. Generally, this looks good, and it's certainly a big performance improvement. I do have some comments though. The main thing I dislike is that it allocates an image on the stack and then only fills out some of the fields. The problem is if a fast path some day starts making use of say the flags in the image, then this code will start to siliently fail. A solution might be to refactor the image allocation code such that we can support stack allocated images internally. This could be done by changing adding _pixman_image_init () and _pixman_bits_image_init() functions, and then changing _pixman_image_allocate() and _pixman_bits_image_create() to call those functions. We would need the corresponding _fini() functions also. Another possibility might be to call the combiner functions instead of calling the fast path. Ie., calling _pixman_implementation_combine_32 (pixman_implementation_t *imp, pixman_op_t op, uint32_t * dest, const uint32_t * src, const uint32_t * mask, int width); instead of the fast path. If we are going to composite scanline by scanline anyway, then it doesn't seem like there should be any advantage to the fast paths over the combiners. The important architectures have SIMD variations of the combiners already. The potential issue, as Siarhei has pointed out several times, is that there is currently a bit of overhead from going through all the implementation-implementation-implementation indirections. Maybe its time to fix that. A simple fix would be to change the _pixman_implementation_combine_* functions into _pixman_implementation_lookup_combine_* functions that would return the desired combiner instead of calling it. This would speed up the general path as well. Also, a few formatting nit-picks: static void fast_composite_tiled_repeat (pixman_implementation_t *imp, pixman_composite_info_t *info) @@ -1223,27 +1225,114 @@ fast_composite_tiled_repeat (pixman_implementation_t *imp, int32_t sx, sy; int32_t width_remain; int32_t num_pixels; + int32_t src_width; + int32_t i, j; + pixman_image_t extended_src_image; + uint32_t extended_src[REPEAT_MIN_WIDTH*2]; We generally put spaces around * when it is used as a binary operator. + if (need_src_extension) + { + if (src_bpp == 32) + { + PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint32_t, src_stride, src_line, 1); + + for (i=0; isrc_width; ) + { + for (j=0; jsrc_image-bits.width; j++, i++) There are some missing spaces here as well (i=0, j=0, isrc_width etc.) + { + extended_src[i] = src_line[j]; + } Generally braces should only be used when the body is more than one line, or if the other branch of an if statement has them. They should not be used if the body is only one line. Thanks, Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
Re: [Pixman] [PATCH] fill: Special-case single pixel wide lines
Chris Wilson ch...@chris-wilson.co.uk writes: A common condition (in benchmarks at least) are single pixel wide vertical lines. This is the worst-cast behaviour for the fast-paths like SSE2 which require long runs in order to offset the ramp up cost of aligning and using the SIMD registers. For example, box-outline consists of drawing a single aligned box with a hairline outline: before: 2327 (stroke), 2509 (fill) after: 674 (stroke), 843 (fill) [measured in *ns* on an i7-640] (Double-pixel wide lines, such as a stroke-width 1 outline of a misaligned box are also very common, but cannot hit pixman_fill(), so rapidly diminishing returns for optimising other widths.) Looks good to me. Generally, if nobody has said anything for some reasonable length of time, feel free to push. Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman
Re: [Pixman] [PATCH] mmx: fix formats in commented code
Matt Turner matts...@gmail.com writes: b8r8g8 is apparently no longer supported sometime since this code was commented. All three patches look good to me. If you were benchmarking the over_x888_8_() operation, is it still slower than the general code? Soren ___ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman