aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/xorg-lib
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/xorg-lib')
-rw-r--r--recipes/xorg-lib/pixman/0001-ARM-NEON-optimized-pixman_blt.patch104
-rw-r--r--recipes/xorg-lib/pixman/0002-Test-program-for-pixman_blt-function.patch178
-rw-r--r--recipes/xorg-lib/pixman/0003-Generic-C-implementation-of-pixman_blt-with-overlapp.patch114
-rw-r--r--recipes/xorg-lib/pixman/0004-Support-of-overlapping-src-dst-for-pixman_blt_mmx.patch91
-rw-r--r--recipes/xorg-lib/pixman/0005-Support-of-overlapping-src-dst-for-pixman_blt_sse2.patch91
-rw-r--r--recipes/xorg-lib/pixman/0006-Support-of-overlapping-src-dst-for-pixman_blt_neon.patch93
-rw-r--r--recipes/xorg-lib/pixman_git.bb11
7 files changed, 680 insertions, 2 deletions
diff --git a/recipes/xorg-lib/pixman/0001-ARM-NEON-optimized-pixman_blt.patch b/recipes/xorg-lib/pixman/0001-ARM-NEON-optimized-pixman_blt.patch
new file mode 100644
index 0000000000..ed2b68d782
--- /dev/null
+++ b/recipes/xorg-lib/pixman/0001-ARM-NEON-optimized-pixman_blt.patch
@@ -0,0 +1,104 @@
+From e94b8057370a430eb91b914ed4c0050f72e9fa37 Mon Sep 17 00:00:00 2001
+From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
+Date: Wed, 18 Nov 2009 04:26:18 +0200
+Subject: [PATCH 1/6] ARM: NEON optimized pixman_blt
+
+---
+ pixman/pixman-arm-neon.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 67 insertions(+), 0 deletions(-)
+
+diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
+index 2ed8b4b..495fda4 100644
+--- a/pixman/pixman-arm-neon.c
++++ b/pixman/pixman-arm-neon.c
+@@ -292,6 +292,43 @@ pixman_fill_neon (uint32_t *bits,
+ }
+ }
+
++static pixman_bool_t
++pixman_blt_neon (uint32_t *src_bits,
++ uint32_t *dst_bits,
++ int src_stride,
++ int dst_stride,
++ int src_bpp,
++ int dst_bpp,
++ int src_x,
++ int src_y,
++ int dst_x,
++ int dst_y,
++ int width,
++ int height)
++{
++ switch (src_bpp)
++ {
++ case 16:
++ pixman_composite_src_0565_0565_asm_neon (
++ width, height,
++ (uint16_t *)(((char *) dst_bits) +
++ dst_y * dst_stride * 4 + dst_x * 2), dst_stride * 2,
++ (uint16_t *)(((char *) src_bits) +
++ src_y * src_stride * 4 + src_x * 2), src_stride * 2);
++ return TRUE;
++ case 32:
++ pixman_composite_src_8888_8888_asm_neon (
++ width, height,
++ (uint32_t *)(((char *) dst_bits) +
++ dst_y * dst_stride * 4 + dst_x * 4), dst_stride,
++ (uint32_t *)(((char *) src_bits) +
++ src_y * src_stride * 4 + src_x * 4), src_stride);
++ return TRUE;
++ default:
++ return FALSE;
++ }
++}
++
+ static const pixman_fast_path_t arm_neon_fast_path_array[] =
+ {
+ { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_0565_0565 },
+@@ -361,6 +398,35 @@ arm_neon_composite (pixman_implementation_t *imp,
+ }
+
+ static pixman_bool_t
++arm_neon_blt (pixman_implementation_t *imp,
++ uint32_t * src_bits,
++ uint32_t * dst_bits,
++ int src_stride,
++ int dst_stride,
++ int src_bpp,
++ int dst_bpp,
++ int src_x,
++ int src_y,
++ int dst_x,
++ int dst_y,
++ int width,
++ int height)
++{
++ if (!pixman_blt_neon (
++ src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
++ src_x, src_y, dst_x, dst_y, width, height))
++
++ {
++ return _pixman_implementation_blt (
++ imp->delegate,
++ src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
++ src_x, src_y, dst_x, dst_y, width, height);
++ }
++
++ return TRUE;
++}
++
++static pixman_bool_t
+ arm_neon_fill (pixman_implementation_t *imp,
+ uint32_t * bits,
+ int stride,
+@@ -385,6 +451,7 @@ _pixman_implementation_create_arm_neon (void)
+ pixman_implementation_t *imp = _pixman_implementation_create (general);
+
+ imp->composite = arm_neon_composite;
++ imp->blt = arm_neon_blt;
+ imp->fill = arm_neon_fill;
+
+ return imp;
+--
+1.6.2.4
+
diff --git a/recipes/xorg-lib/pixman/0002-Test-program-for-pixman_blt-function.patch b/recipes/xorg-lib/pixman/0002-Test-program-for-pixman_blt-function.patch
new file mode 100644
index 0000000000..143e79dabf
--- /dev/null
+++ b/recipes/xorg-lib/pixman/0002-Test-program-for-pixman_blt-function.patch
@@ -0,0 +1,178 @@
+From 364406e03f9651aacb1bc684de6c00a27f9df66d Mon Sep 17 00:00:00 2001
+From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
+Date: Mon, 19 Oct 2009 20:32:55 +0300
+Subject: [PATCH 2/6] Test program for pixman_blt function
+
+It can do some basic correctness tests and also check whether
+overlapping of source and destination images is supported.
+---
+ test/Makefile.am | 2 +
+ test/overlapped-blt-test.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 138 insertions(+), 0 deletions(-)
+ create mode 100644 test/overlapped-blt-test.c
+
+diff --git a/test/Makefile.am b/test/Makefile.am
+index 89d32e9..40c305f 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -9,6 +9,7 @@ TESTPROGRAMS = \
+ fetch-test \
+ oob-test \
+ window-test \
++ overlapped-blt-test \
+ trap-crasher
+
+ fetch_test_LDADD = $(TEST_LDADD)
+@@ -17,6 +18,7 @@ composite_LDADD = $(TEST_LDADD)
+ trap_crasher_LDADD = $(TEST_LDADD)
+ oob_test_LDADD = $(TEST_LDADD)
+ window_test_LDADD = $(TEST_LDADD)
++overlapped_blt_test_LDADD = $(TEST_LDADD)
+
+ blitters_test_LDADD = $(TEST_LDADD)
+ blitters_test_SOURCES = blitters-test.c utils.c utils.h
+diff --git a/test/overlapped-blt-test.c b/test/overlapped-blt-test.c
+new file mode 100644
+index 0000000..95fbc54
+--- /dev/null
++++ b/test/overlapped-blt-test.c
+@@ -0,0 +1,136 @@
++/*
++ * A small test program which can check whether pixman_blt function
++ * can support overlapping of source and destination images.
++ * Efficient blit with overlapping is useful for scrolling.
++ */
++
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include "pixman.h"
++
++/* reference implementation (slow) */
++static void
++trivial_copy8_2d (
++ uint8_t *dst, int dst_stride,
++ uint8_t *src, int src_stride,
++ int dx, int dy, int sx, int sy,
++ int w, int h)
++{
++ int x, y;
++ uint8_t *tmp = malloc (src_stride * (sy + h));
++ memcpy (tmp, src, src_stride * (sy + h));
++ for (y = 0; y < h; y++)
++ {
++ for (x = 0; x < w; x++)
++ {
++ *(dst + (dy + y) * dst_stride + dx + x) =
++ *(tmp + (sy + y) * src_stride + sx + x);
++ }
++ }
++ free (tmp);
++}
++
++static void
++trivial_copy_2d (
++ uint8_t *dst, int dst_stride,
++ uint8_t *src, int src_stride,
++ int dx, int dy, int sx, int sy,
++ int w, int h, int bpp)
++{
++ trivial_copy8_2d (dst, dst_stride, src, src_stride,
++ dx * (bpp / 8), dy, sx * (bpp / 8), sy, w * (bpp / 8), h);
++}
++
++/* now the test itself */
++
++#define ST_UNSUPPORTED 1
++#define ST_NORMAL_BUG 2
++#define ST_OVERLAPPED_BUG 4
++
++#define MAX_SIZE_X 64
++#define MAX_SIZE_Y 64
++
++static void print_result(int bpp, int flags)
++{
++ printf("bpp=%d, supported=%d, normal_ok=%d, overlapped_ok=%d\n",
++ bpp,
++ !(flags & ST_UNSUPPORTED),
++ !(flags & ST_NORMAL_BUG),
++ !(flags & ST_OVERLAPPED_BUG));
++}
++
++int main()
++{
++ int c = 100000, r;
++ int bpp_st[33] = {0};
++ srand(0);
++ while (c-- > 0)
++ {
++ uint8_t *src1, *src2, *src3;
++ int i;
++ int sizex = rand() % MAX_SIZE_X + 1;
++ int sizey = rand() % MAX_SIZE_Y + 1;
++ int sx = rand() % sizex;
++ int sy = rand() % sizey;
++ int dx = rand() % sizex;
++ int dy = rand() % sizey;
++ int w = rand() % sizex;
++ int h = rand() % sizex;
++ int bpp = 8 * (1 << (rand() % 3));
++ int stride_delta = rand() % 8;
++ int bufsize;
++ if ((sizex + stride_delta) % 4)
++ stride_delta += 4 - ((sizex + stride_delta) % 4);
++ bufsize = (sizex + stride_delta) * sizey * bpp / 8;
++ src1 = malloc (bufsize);
++ src2 = malloc (bufsize);
++ src3 = malloc (bufsize);
++ for (i = 0; i < bufsize; i++)
++ src1[i] = rand();
++ memcpy (src2, src1, bufsize);
++ memcpy (src3, src1, bufsize);
++ if (sx + w > sizex)
++ w = sizex - sx;
++ if (dx + w > sizex)
++ w = sizex - dx;
++ if (sy + h > sizey)
++ h = sizey - sy;
++ if (dy + h > sizey)
++ h = sizey - dy;
++ /* get reference result */
++ trivial_copy_2d (src1, (sizex + stride_delta) * bpp / 8,
++ src1, (sizex + stride_delta) * bpp / 8,
++ dx, dy, sx, sy, w, h, bpp);
++ /* check nonoverlapped pixman result */
++ r = pixman_blt ((uint32_t *)src3, (uint32_t *)src2,
++ (sizex + stride_delta) * bpp / 8 / 4,
++ (sizex + stride_delta) * bpp / 8 / 4,
++ bpp, bpp, sx, sy, dx, dy, w, h);
++ if (!r)
++ bpp_st[bpp] |= ST_UNSUPPORTED;
++ if (memcmp (src1, src2, bufsize) != 0)
++ bpp_st[bpp] |= ST_NORMAL_BUG;
++ /* check overlapped pixman result */
++ r = pixman_blt ((uint32_t *)src3, (uint32_t *)src3,
++ (sizex + stride_delta) * bpp / 8 / 4,
++ (sizex + stride_delta) * bpp / 8 / 4,
++ bpp, bpp, sx, sy, dx, dy, w, h);
++ if (!r)
++ bpp_st[bpp] |= ST_UNSUPPORTED;
++ if (memcmp (src1, src3, bufsize) != 0)
++ bpp_st[bpp] |= ST_OVERLAPPED_BUG;
++ /* free buffers */
++ free (src1);
++ free (src2);
++ free (src3);
++ }
++
++ /* report results */
++ print_result (8, bpp_st[8]);
++ print_result (16, bpp_st[16]);
++ print_result (32, bpp_st[32]);
++
++ return 0;
++}
+--
+1.6.2.4
+
diff --git a/recipes/xorg-lib/pixman/0003-Generic-C-implementation-of-pixman_blt-with-overlapp.patch b/recipes/xorg-lib/pixman/0003-Generic-C-implementation-of-pixman_blt-with-overlapp.patch
new file mode 100644
index 0000000000..25ce7ee3b8
--- /dev/null
+++ b/recipes/xorg-lib/pixman/0003-Generic-C-implementation-of-pixman_blt-with-overlapp.patch
@@ -0,0 +1,114 @@
+From c29c9fa826b7112156fd6150b5f1564227935c05 Mon Sep 17 00:00:00 2001
+From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
+Date: Thu, 22 Oct 2009 05:27:33 +0300
+Subject: [PATCH 3/6] Generic C implementation of pixman_blt with overlapping support
+
+Uses memcpy/memmove functions to copy pixels, can handle the
+case when both source and destination areas are in the same
+image (this is useful for scrolling).
+
+It is assumed that copying direction is only important when
+using the same image for both source and destination (and
+src_stride == dst_stride). Copying direction is undefined
+for the images with different source and destination stride
+which happen to be in the overlapped areas (but this is an
+unrealistic case anyway).
+---
+ pixman/pixman-general.c | 21 ++++++++++++++++++---
+ pixman/pixman-private.h | 43 +++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 61 insertions(+), 3 deletions(-)
+
+diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
+index c96a3f9..d71a299 100644
+--- a/pixman/pixman-general.c
++++ b/pixman/pixman-general.c
+@@ -300,9 +300,24 @@ general_blt (pixman_implementation_t *imp,
+ int width,
+ int height)
+ {
+- /* We can't blit unless we have sse2 or mmx */
+-
+- return FALSE;
++ uint8_t *dst_bytes = (uint8_t *)dst_bits;
++ uint8_t *src_bytes = (uint8_t *)src_bits;
++ int bpp;
++
++ if (src_bpp != dst_bpp || src_bpp & 7)
++ return FALSE;
++
++ bpp = src_bpp >> 3;
++ width *= bpp;
++ src_stride *= 4;
++ dst_stride *= 4;
++ pixman_blt_helper (src_bytes + src_y * src_stride + src_x * bpp,
++ dst_bytes + dst_y * dst_stride + dst_x * bpp,
++ src_stride,
++ dst_stride,
++ width,
++ height);
++ return TRUE;
+ }
+
+ static pixman_bool_t
+diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
+index 5000f91..8c5d4fd 100644
+--- a/pixman/pixman-private.h
++++ b/pixman/pixman-private.h
+@@ -10,6 +10,7 @@
+
+ #include "pixman.h"
+ #include <time.h>
++#include <string.h>
+ #include <assert.h>
+
+ #include "pixman-compiler.h"
+@@ -794,4 +795,46 @@ void pixman_timer_register (pixman_timer_t *timer);
+
+ #endif /* PIXMAN_TIMERS */
+
++/* a helper function, can blit 8-bit images with src/dst overlapping support */
++static inline void
++pixman_blt_helper (uint8_t *src_bytes,
++ uint8_t *dst_bytes,
++ int src_stride,
++ int dst_stride,
++ int width,
++ int height)
++{
++ /*
++ * The second part of this check is not strictly needed, but it prevents
++ * unnecessary upside-down processing of areas which belong to different
++ * images. Upside-down processing can be slower with fixed-distance-ahead
++ * prefetch and perceived as having more tearing.
++ */
++ if (src_bytes < dst_bytes + width &&
++ src_bytes + src_stride * height > dst_bytes)
++ {
++ src_bytes += src_stride * height - src_stride;
++ dst_bytes += dst_stride * height - dst_stride;
++ dst_stride = -dst_stride;
++ src_stride = -src_stride;
++ /* Horizontal scrolling to the left needs memmove */
++ if (src_bytes + width > dst_bytes)
++ {
++ while (--height >= 0)
++ {
++ memmove (dst_bytes, src_bytes, width);
++ dst_bytes += dst_stride;
++ src_bytes += src_stride;
++ }
++ return;
++ }
++ }
++ while (--height >= 0)
++ {
++ memcpy (dst_bytes, src_bytes, width);
++ dst_bytes += dst_stride;
++ src_bytes += src_stride;
++ }
++}
++
+ #endif /* PIXMAN_PRIVATE_H */
+--
+1.6.2.4
+
diff --git a/recipes/xorg-lib/pixman/0004-Support-of-overlapping-src-dst-for-pixman_blt_mmx.patch b/recipes/xorg-lib/pixman/0004-Support-of-overlapping-src-dst-for-pixman_blt_mmx.patch
new file mode 100644
index 0000000000..74c7b45bc4
--- /dev/null
+++ b/recipes/xorg-lib/pixman/0004-Support-of-overlapping-src-dst-for-pixman_blt_mmx.patch
@@ -0,0 +1,91 @@
+From 7ca32542c957ff308a6ca7e3715e6552a65ae395 Mon Sep 17 00:00:00 2001
+From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
+Date: Thu, 22 Oct 2009 05:45:47 +0300
+Subject: [PATCH 4/6] Support of overlapping src/dst for pixman_blt_mmx
+
+---
+ pixman/pixman-mmx.c | 55 +++++++++++++++++++++++++++++---------------------
+ 1 files changed, 32 insertions(+), 23 deletions(-)
+
+diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
+index 819e3a0..dcccadb 100644
+--- a/pixman/pixman-mmx.c
++++ b/pixman/pixman-mmx.c
+@@ -3002,34 +3002,43 @@ pixman_blt_mmx (uint32_t *src_bits,
+ {
+ uint8_t * src_bytes;
+ uint8_t * dst_bytes;
+- int byte_width;
++ int bpp;
+
+- if (src_bpp != dst_bpp)
++ if (src_bpp != dst_bpp || src_bpp & 7)
+ return FALSE;
+
+- if (src_bpp == 16)
+- {
+- src_stride = src_stride * (int) sizeof (uint32_t) / 2;
+- dst_stride = dst_stride * (int) sizeof (uint32_t) / 2;
+- src_bytes = (uint8_t *)(((uint16_t *)src_bits) + src_stride * (src_y) + (src_x));
+- dst_bytes = (uint8_t *)(((uint16_t *)dst_bits) + dst_stride * (dst_y) + (dst_x));
+- byte_width = 2 * width;
+- src_stride *= 2;
+- dst_stride *= 2;
+- }
+- else if (src_bpp == 32)
++ bpp = src_bpp >> 3;
++ width *= bpp;
++ src_stride *= 4;
++ dst_stride *= 4;
++ src_bytes = (uint8_t *)src_bits + src_y * src_stride + src_x * bpp;
++ dst_bytes = (uint8_t *)dst_bits + dst_y * dst_stride + dst_x * bpp;
++
++ if (src_bpp != 16 && src_bpp != 32)
+ {
+- src_stride = src_stride * (int) sizeof (uint32_t) / 4;
+- dst_stride = dst_stride * (int) sizeof (uint32_t) / 4;
+- src_bytes = (uint8_t *)(((uint32_t *)src_bits) + src_stride * (src_y) + (src_x));
+- dst_bytes = (uint8_t *)(((uint32_t *)dst_bits) + dst_stride * (dst_y) + (dst_x));
+- byte_width = 4 * width;
+- src_stride *= 4;
+- dst_stride *= 4;
++ pixman_blt_helper (src_bytes, dst_bytes, src_stride, dst_stride,
++ width, height);
++ return TRUE;
+ }
+- else
++
++ if (src_bytes < dst_bytes && src_bytes + src_stride * height > dst_bytes)
+ {
+- return FALSE;
++ src_bytes += src_stride * height - src_stride;
++ dst_bytes += dst_stride * height - dst_stride;
++ dst_stride = -dst_stride;
++ src_stride = -src_stride;
++
++ if (src_bytes + width > dst_bytes)
++ {
++ /* TODO: reverse scanline copy using MMX */
++ while (--height >= 0)
++ {
++ memmove (dst_bytes, src_bytes, width);
++ dst_bytes += dst_stride;
++ src_bytes += src_stride;
++ }
++ return TRUE;
++ }
+ }
+
+ while (height--)
+@@ -3039,7 +3048,7 @@ pixman_blt_mmx (uint32_t *src_bits,
+ uint8_t *d = dst_bytes;
+ src_bytes += src_stride;
+ dst_bytes += dst_stride;
+- w = byte_width;
++ w = width;
+
+ while (w >= 2 && ((unsigned long)d & 3))
+ {
+--
+1.6.2.4
+
diff --git a/recipes/xorg-lib/pixman/0005-Support-of-overlapping-src-dst-for-pixman_blt_sse2.patch b/recipes/xorg-lib/pixman/0005-Support-of-overlapping-src-dst-for-pixman_blt_sse2.patch
new file mode 100644
index 0000000000..3704fbf1cf
--- /dev/null
+++ b/recipes/xorg-lib/pixman/0005-Support-of-overlapping-src-dst-for-pixman_blt_sse2.patch
@@ -0,0 +1,91 @@
+From edc80b41c6480b7c80ec5f7c835c92b2debb3774 Mon Sep 17 00:00:00 2001
+From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
+Date: Thu, 22 Oct 2009 05:45:54 +0300
+Subject: [PATCH 5/6] Support of overlapping src/dst for pixman_blt_sse2
+
+---
+ pixman/pixman-sse2.c | 55 +++++++++++++++++++++++++++++--------------------
+ 1 files changed, 32 insertions(+), 23 deletions(-)
+
+diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
+index 78b0ad1..b84636b 100644
+--- a/pixman/pixman-sse2.c
++++ b/pixman/pixman-sse2.c
+@@ -5300,34 +5300,43 @@ pixman_blt_sse2 (uint32_t *src_bits,
+ {
+ uint8_t * src_bytes;
+ uint8_t * dst_bytes;
+- int byte_width;
++ int bpp;
+
+- if (src_bpp != dst_bpp)
++ if (src_bpp != dst_bpp || src_bpp & 7)
+ return FALSE;
+
+- if (src_bpp == 16)
+- {
+- src_stride = src_stride * (int) sizeof (uint32_t) / 2;
+- dst_stride = dst_stride * (int) sizeof (uint32_t) / 2;
+- src_bytes =(uint8_t *)(((uint16_t *)src_bits) + src_stride * (src_y) + (src_x));
+- dst_bytes = (uint8_t *)(((uint16_t *)dst_bits) + dst_stride * (dst_y) + (dst_x));
+- byte_width = 2 * width;
+- src_stride *= 2;
+- dst_stride *= 2;
+- }
+- else if (src_bpp == 32)
++ bpp = src_bpp >> 3;
++ width *= bpp;
++ src_stride *= 4;
++ dst_stride *= 4;
++ src_bytes = (uint8_t *)src_bits + src_y * src_stride + src_x * bpp;
++ dst_bytes = (uint8_t *)dst_bits + dst_y * dst_stride + dst_x * bpp;
++
++ if (src_bpp != 16 && src_bpp != 32)
+ {
+- src_stride = src_stride * (int) sizeof (uint32_t) / 4;
+- dst_stride = dst_stride * (int) sizeof (uint32_t) / 4;
+- src_bytes = (uint8_t *)(((uint32_t *)src_bits) + src_stride * (src_y) + (src_x));
+- dst_bytes = (uint8_t *)(((uint32_t *)dst_bits) + dst_stride * (dst_y) + (dst_x));
+- byte_width = 4 * width;
+- src_stride *= 4;
+- dst_stride *= 4;
++ pixman_blt_helper (src_bytes, dst_bytes, src_stride, dst_stride,
++ width, height);
++ return TRUE;
+ }
+- else
++
++ if (src_bytes < dst_bytes && src_bytes + src_stride * height > dst_bytes)
+ {
+- return FALSE;
++ src_bytes += src_stride * height - src_stride;
++ dst_bytes += dst_stride * height - dst_stride;
++ dst_stride = -dst_stride;
++ src_stride = -src_stride;
++
++ if (src_bytes + width > dst_bytes)
++ {
++ /* TODO: reverse scanline copy using SSE2 */
++ while (--height >= 0)
++ {
++ memmove (dst_bytes, src_bytes, width);
++ dst_bytes += dst_stride;
++ src_bytes += src_stride;
++ }
++ return TRUE;
++ }
+ }
+
+ cache_prefetch ((__m128i*)src_bytes);
+@@ -5340,7 +5349,7 @@ pixman_blt_sse2 (uint32_t *src_bits,
+ uint8_t *d = dst_bytes;
+ src_bytes += src_stride;
+ dst_bytes += dst_stride;
+- w = byte_width;
++ w = width;
+
+ cache_prefetch_next ((__m128i*)s);
+ cache_prefetch_next ((__m128i*)d);
+--
+1.6.2.4
+
diff --git a/recipes/xorg-lib/pixman/0006-Support-of-overlapping-src-dst-for-pixman_blt_neon.patch b/recipes/xorg-lib/pixman/0006-Support-of-overlapping-src-dst-for-pixman_blt_neon.patch
new file mode 100644
index 0000000000..af75716bb8
--- /dev/null
+++ b/recipes/xorg-lib/pixman/0006-Support-of-overlapping-src-dst-for-pixman_blt_neon.patch
@@ -0,0 +1,93 @@
+From 86870ff530b5e435034bd80207e5758466d96cff Mon Sep 17 00:00:00 2001
+From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
+Date: Wed, 18 Nov 2009 06:08:48 +0200
+Subject: [PATCH 6/6] Support of overlapping src/dst for pixman_blt_neon
+
+---
+ pixman/pixman-arm-neon.c | 63 ++++++++++++++++++++++++++++++++++++++-------
+ 1 files changed, 53 insertions(+), 10 deletions(-)
+
+diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
+index 495fda4..c632ff5 100644
+--- a/pixman/pixman-arm-neon.c
++++ b/pixman/pixman-arm-neon.c
+@@ -306,23 +306,66 @@ pixman_blt_neon (uint32_t *src_bits,
+ int width,
+ int height)
+ {
++ uint8_t * src_bytes;
++ uint8_t * dst_bytes;
++ int bpp;
++
++ if (src_bpp != dst_bpp || src_bpp & 7)
++ return FALSE;
++
++ bpp = src_bpp >> 3;
++ width *= bpp;
++ src_stride *= 4;
++ dst_stride *= 4;
++ src_bytes = (uint8_t *)src_bits + src_y * src_stride + src_x * bpp;
++ dst_bytes = (uint8_t *)dst_bits + dst_y * dst_stride + dst_x * bpp;
++
++ if (src_bpp != 16 && src_bpp != 32)
++ {
++ pixman_blt_helper (src_bytes, dst_bytes, src_stride, dst_stride,
++ width, height);
++ return TRUE;
++ }
++
++ if (src_bytes < dst_bytes && src_bytes + src_stride * height > dst_bytes)
++ {
++ src_bytes += src_stride * height - src_stride;
++ dst_bytes += dst_stride * height - dst_stride;
++ dst_stride = -dst_stride;
++ src_stride = -src_stride;
++
++ if (src_bytes + width > dst_bytes)
++ {
++ /* TODO: reverse scanline copy using NEON */
++ while (--height >= 0)
++ {
++ memmove (dst_bytes, src_bytes, width);
++ dst_bytes += dst_stride;
++ src_bytes += src_stride;
++ }
++ return TRUE;
++ }
++ }
++
+ switch (src_bpp)
+ {
+ case 16:
+ pixman_composite_src_0565_0565_asm_neon (
+- width, height,
+- (uint16_t *)(((char *) dst_bits) +
+- dst_y * dst_stride * 4 + dst_x * 2), dst_stride * 2,
+- (uint16_t *)(((char *) src_bits) +
+- src_y * src_stride * 4 + src_x * 2), src_stride * 2);
++ width >> 1,
++ height,
++ (uint16_t *) dst_bytes,
++ dst_stride >> 1,
++ (uint16_t *) src_bytes,
++ src_stride >> 1);
+ return TRUE;
+ case 32:
+ pixman_composite_src_8888_8888_asm_neon (
+- width, height,
+- (uint32_t *)(((char *) dst_bits) +
+- dst_y * dst_stride * 4 + dst_x * 4), dst_stride,
+- (uint32_t *)(((char *) src_bits) +
+- src_y * src_stride * 4 + src_x * 4), src_stride);
++ width >> 2,
++ height,
++ (uint32_t *) dst_bytes,
++ dst_stride >> 2,
++ (uint32_t *) src_bytes,
++ src_stride >> 2);
+ return TRUE;
+ default:
+ return FALSE;
+--
+1.6.2.4
+
diff --git a/recipes/xorg-lib/pixman_git.bb b/recipes/xorg-lib/pixman_git.bb
index dd02828e37..1b5ca6388f 100644
--- a/recipes/xorg-lib/pixman_git.bb
+++ b/recipes/xorg-lib/pixman_git.bb
@@ -3,17 +3,24 @@ PRIORITY = "optional"
DESCRIPTION = "Low-level pixel manipulation library."
LICENSE = "X11"
-PV = "0.17.1"
+PV = "0.17.3"
PR = "r4"
PR_append = "+gitr${SRCREV}"
-SRCREV = "abefe68ae2a422fecf315f17430c0cda5561be66"
+SRCREV = "c97b1e803fc214e9880eaeff98410c8fa37f9ddc"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_angstrom = "1"
+DEFAULT_PREFERENCE_shr = "1"
SRC_URI = "git://anongit.freedesktop.org/pixman;protocol=git \
file://nearest-neighbour.patch;patch=1 \
+ file://0001-ARM-NEON-optimized-pixman_blt.patch;patch=1 \
+ file://0002-Test-program-for-pixman_blt-function.patch;patch=1 \
+ file://0003-Generic-C-implementation-of-pixman_blt-with-overlapp.patch;patch=1 \
+ file://0004-Support-of-overlapping-src-dst-for-pixman_blt_mmx.patch;patch=1 \
+ file://0005-Support-of-overlapping-src-dst-for-pixman_blt_sse2.patch;patch=1 \
+ file://0006-Support-of-overlapping-src-dst-for-pixman_blt_neon.patch;patch=1 \
"
S = "${WORKDIR}/git"