diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2007-10-16 04:29:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:19 -0400 |
commit | 779121e9f17525769c04a00475fd85600c8c04eb (patch) | |
tree | 757aad067bed869bfdd2dc2eb2f652a7f4e5e071 /drivers/video/cfbcopyarea.c | |
parent | 3c03ec209af1dd8223888630482f1b2353dc6284 (diff) |
fbdev: Support for byte-reversed framebuffer formats
Allow generic frame-buffer code to correctly write texts and blit images for
1, 2 and 4 bit per pixel frame-buffer organizations when pixels in bytes are
organized to in opposite order than bytes in long type.
Overhead should be reasonable. If option is not selected, than compiler
should eliminate completely all overhead.
The feature is disabled at compile time if CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is
not set.
[adaplas]
Convert helper functions to macros if feature is not enabled.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/cfbcopyarea.c')
-rw-r--r-- | drivers/video/cfbcopyarea.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c index 032210f45be3..1c67885a1f4f 100644 --- a/drivers/video/cfbcopyarea.c +++ b/drivers/video/cfbcopyarea.c | |||
@@ -45,14 +45,14 @@ | |||
45 | 45 | ||
46 | static void | 46 | static void |
47 | bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src, | 47 | bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src, |
48 | int src_idx, int bits, unsigned n) | 48 | int src_idx, int bits, unsigned n, u32 bswapmask) |
49 | { | 49 | { |
50 | unsigned long first, last; | 50 | unsigned long first, last; |
51 | int const shift = dst_idx-src_idx; | 51 | int const shift = dst_idx-src_idx; |
52 | int left, right; | 52 | int left, right; |
53 | 53 | ||
54 | first = FB_SHIFT_HIGH(~0UL, dst_idx); | 54 | first = fb_shifted_pixels_mask_long(dst_idx, bswapmask); |
55 | last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); | 55 | last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask); |
56 | 56 | ||
57 | if (!shift) { | 57 | if (!shift) { |
58 | // Same alignment for source and dest | 58 | // Same alignment for source and dest |
@@ -185,7 +185,7 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src | |||
185 | 185 | ||
186 | static void | 186 | static void |
187 | bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src, | 187 | bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src, |
188 | int src_idx, int bits, unsigned n) | 188 | int src_idx, int bits, unsigned n, u32 bswapmask) |
189 | { | 189 | { |
190 | unsigned long first, last; | 190 | unsigned long first, last; |
191 | int shift; | 191 | int shift; |
@@ -203,8 +203,8 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem | |||
203 | 203 | ||
204 | shift = dst_idx-src_idx; | 204 | shift = dst_idx-src_idx; |
205 | 205 | ||
206 | first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx); | 206 | first = fb_shifted_pixels_mask_long(bits - 1 - dst_idx, bswapmask); |
207 | last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits))); | 207 | last = ~fb_shifted_pixels_mask_long(bits - 1 - ((dst_idx-n) % bits), bswapmask); |
208 | 208 | ||
209 | if (!shift) { | 209 | if (!shift) { |
210 | // Same alignment for source and dest | 210 | // Same alignment for source and dest |
@@ -336,6 +336,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) | |||
336 | unsigned long __iomem *dst = NULL, *src = NULL; | 336 | unsigned long __iomem *dst = NULL, *src = NULL; |
337 | int bits = BITS_PER_LONG, bytes = bits >> 3; | 337 | int bits = BITS_PER_LONG, bytes = bits >> 3; |
338 | int dst_idx = 0, src_idx = 0, rev_copy = 0; | 338 | int dst_idx = 0, src_idx = 0, rev_copy = 0; |
339 | u32 bswapmask = fb_compute_bswapmask(p); | ||
339 | 340 | ||
340 | if (p->state != FBINFO_STATE_RUNNING) | 341 | if (p->state != FBINFO_STATE_RUNNING) |
341 | return; | 342 | return; |
@@ -368,7 +369,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) | |||
368 | src += src_idx >> (ffs(bits) - 1); | 369 | src += src_idx >> (ffs(bits) - 1); |
369 | src_idx &= (bytes - 1); | 370 | src_idx &= (bytes - 1); |
370 | bitcpy_rev(dst, dst_idx, src, src_idx, bits, | 371 | bitcpy_rev(dst, dst_idx, src, src_idx, bits, |
371 | width*p->var.bits_per_pixel); | 372 | width*p->var.bits_per_pixel, bswapmask); |
372 | } | 373 | } |
373 | } else { | 374 | } else { |
374 | while (height--) { | 375 | while (height--) { |
@@ -377,7 +378,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) | |||
377 | src += src_idx >> (ffs(bits) - 1); | 378 | src += src_idx >> (ffs(bits) - 1); |
378 | src_idx &= (bytes - 1); | 379 | src_idx &= (bytes - 1); |
379 | bitcpy(dst, dst_idx, src, src_idx, bits, | 380 | bitcpy(dst, dst_idx, src, src_idx, bits, |
380 | width*p->var.bits_per_pixel); | 381 | width*p->var.bits_per_pixel, bswapmask); |
381 | dst_idx += bits_per_line; | 382 | dst_idx += bits_per_line; |
382 | src_idx += bits_per_line; | 383 | src_idx += bits_per_line; |
383 | } | 384 | } |