When using xvideo on alignement critical architectures (for example a sparc64 with the XVR100 graphics adapter) some screen positions (easily reproducable with xfce and gmplayer by moving the video window partly out of the screen on the left side) cause misaligned pointers being passed to RADEONCopySwap - and cause the X server to crash.
This may be bugs in the calling code (e.g. RADEONPutImage), but it only seems to try to align to 16 bit anyway - and actually some calls end up even with only byte aligned buffers. This change notices the misalignement and uses less efficient, smaller copies. But at least the X server does not crash (and all usual screen positions seem to end up in proper aligned buffers). Signed-off-by: Martin Husemann <[email protected]> --- src/radeon_accel.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/radeon_accel.c b/src/radeon_accel.c index 8eff5c5..bb8726f 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -141,7 +141,30 @@ void RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap) return; } case RADEON_HOST_DATA_SWAP_32BIT: - { + if (((uintptr_t)dst & 1) || ((uintptr_t)src & 1)) { + uint8_t *d = (uint8_t *)dst; + uint8_t *s = (uint8_t *)src; + unsigned int nwords = size >> 2; + + for (; nwords > 0; --nwords, d+=4, s+=4) { + d[0] = s[3]; + d[1] = s[2]; + d[2] = s[1]; + d[3] = s[0]; + } + return; + } else if (((uintptr_t)dst & 3) || ((uintptr_t)src & 3)) { + /* copy 16bit wise */ + uint16_t *d = (uint16_t *)dst; + uint16_t *s = (uint16_t *)src; + unsigned int nwords = size >> 2; + + for (; nwords > 0; --nwords, d+=2, s+=2) { + d[0] = ((s[1] >> 8) & 0xff) | ((s[1] & 0xff) << 8); + d[1] = ((s[0] >> 8) & 0xff) | ((s[0] & 0xff) << 8); + } + return; + } else { unsigned int *d = (unsigned int *)dst; unsigned int *s = (unsigned int *)src; unsigned int nwords = size >> 2; -- 1.8.5.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
