blit: fix alignment errors on ARM

Depending on 'src_w' and 'dst_w', different lines of a block to copy may be
32-bit aligned or not, so the alignment of each line needs to get checked.

Fixes #1111.
This commit is contained in:
Christian Prochaska 2014-05-20 22:52:56 +02:00 committed by Norman Feske
parent 031cabf862
commit 9580954d81

View File

@ -37,9 +37,9 @@ static inline void copy_16bit_column(char const *src, int src_w,
* \param src_w width of source buffer in bytes * \param src_w width of source buffer in bytes
* \param dst_w width of destination buffer in bytes * \param dst_w width of destination buffer in bytes
*/ */
static void copy_block_32bit(char const *src, int src_w, static inline void copy_block_32bit(char const *src, int src_w,
char *dst, int dst_w, char *dst, int dst_w,
int w, int h) int w, int h)
{ {
src_w -= w*4; src_w -= w*4;
dst_w -= w*4; dst_w -= w*4;
@ -60,17 +60,28 @@ static inline void copy_block_32byte(char const *src, int src_w,
char *dst, int dst_w, char *dst, int dst_w,
int w, int h) int w, int h)
{ {
if (((long)src & 3) || ((long)dst & 3)) for (; h > 0; h--) {
copy_block_32bit(src, src_w, dst, dst_w, w*8, h); /*
else { * Depending on 'src_w' and 'dst_w', some lines may be properly aligned,
src_w -= w*32; * while others may be not, so we need to check each line.
dst_w -= w*32; */
for (; h--; src += src_w, dst += dst_w) if (((long)src & 3) || ((long)dst & 3)) {
for (int i = w; i--;) copy_block_32bit(src, src_w, dst, dst_w, w*8, 1);
src += src_w;
dst += dst_w;
} else {
for (int i = w; i > 0; i--)
asm volatile ("ldmia %0!, {r3 - r10} \n\t" asm volatile ("ldmia %0!, {r3 - r10} \n\t"
"stmia %1!, {r3 - r10} \n\t" "stmia %1!, {r3 - r10} \n\t"
: "+r" (src), "+r" (dst) : "+r" (src), "+r" (dst)
:: "r3","r4","r5","r6","r7","r8","r9","r10"); :: "r3","r4","r5","r6","r7","r8","r9","r10");
/*
* 'src' and 'dst' got auto-incremented by the copy code, so only
* the remainder needs to get added
*/
src += (src_w - w*32);
dst += (dst_w - w*32);
}
} }
} }