diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-06 15:26:11 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-06 17:50:01 +0000 |
commit | 9f1935bb4e894264053d94e53c99d5ad607700fb (patch) | |
tree | 689fdc95dda28ba227cf26d9ee2347a303962bb8 /src/sna/blt.c | |
parent | 141001df6c9c3485c500ed531a214c09b46c1d3b (diff) |
sna: Support performing alpha-fixup on the source
By inlining the swizzling of the alpha-channel we can support BLT copies
from an alpha-less pixmap to an alpha-destination.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/blt.c')
-rw-r--r-- | src/sna/blt.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/sna/blt.c b/src/sna/blt.c index 7a77fa49..d28ad985 100644 --- a/src/sna/blt.c +++ b/src/sna/blt.c @@ -106,3 +106,108 @@ memcpy_blt(const void *src, void *dst, int bpp, break; } } + +void +memcpy_xor(const void *src, void *dst, int bpp, + int32_t src_stride, int32_t dst_stride, + int16_t src_x, int16_t src_y, + int16_t dst_x, int16_t dst_y, + uint16_t width, uint16_t height, + uint32_t and, uint32_t or) +{ + uint8_t *src_bytes; + uint8_t *dst_bytes; + int i; + + assert(width && height); + assert(bpp >= 8); + + DBG(("%s: src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d, bpp=%d, and=%x, xor=%x\n", + __FUNCTION__, + src_x, src_y, dst_x, dst_y, + width, height, + src_stride, dst_stride, + bpp, and, or)); + + bpp /= 8; + src_bytes = (uint8_t *)src + src_stride * src_y + src_x * bpp; + dst_bytes = (uint8_t *)dst + dst_stride * dst_y + dst_x * bpp; + + if (and == 0xffffffff) { + switch (bpp) { + case 1: + do { + for (i = 0; i < width; i++) + dst_bytes[i] = src_bytes[i] | or; + + src_bytes += src_stride; + dst_bytes += dst_stride; + } while (--height); + break; + + case 2: + do { + uint16_t *d = (uint16_t *)dst_bytes; + uint16_t *s = (uint16_t *)src_bytes; + + for (i = 0; i < width; i++) + d[i] = s[i] | or; + + src_bytes += src_stride; + dst_bytes += dst_stride; + } while (--height); + break; + + case 4: + do { + uint32_t *d = (uint32_t *)dst_bytes; + uint32_t *s = (uint32_t *)src_bytes; + + for (i = 0; i < width; i++) + d[i] = s[i] | or; + + src_bytes += src_stride; + dst_bytes += dst_stride; + } while (--height); + break; + } + } else { + switch (bpp) { + case 1: + do { + for (i = 0; i < width; i++) + dst_bytes[i] = (src_bytes[i] & and) | or; + + src_bytes += src_stride; + dst_bytes += dst_stride; + } while (--height); + break; + + case 2: + do { + uint16_t *d = (uint16_t *)dst_bytes; + uint16_t *s = (uint16_t *)src_bytes; + + for (i = 0; i < width; i++) + d[i] = (s[i] & and) | or; + + src_bytes += src_stride; + dst_bytes += dst_stride; + } while (--height); + break; + + case 4: + do { + uint32_t *d = (uint32_t *)dst_bytes; + uint32_t *s = (uint32_t *)src_bytes; + + for (i = 0; i < width; i++) + d[i] = (s[i] & and) | or; + + src_bytes += src_stride; + dst_bytes += dst_stride; + } while (--height); + break; + } + } +} |