fbdev: Support for byte-reversed framebuffer formats
PATCH 3/12 fbdev: Support for byte-reversed framebuffer formats
From: Pavel Pisa <[email protected]>
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.
---
drivers/video/Kconfig | 9 ++++++ drivers/video/cfbcopyarea.c | 17 ++++++----- drivers/video/cfbfillrect.c | 20 ++++++++----- drivers/video/cfbimgblt.c | 17 ++++++----- drivers/video/fb_draw.h | 68 +++++++++++++++++++++++++++++++++++++++++++ include/linux/fb.h | 1 + 6 files changed, 109 insertions(+), 23 deletions(-)
drivers/video/Kconfig +9 -0
@@ -102,6 +102,15 @@ config FB_CFB_IMAGEBLIT blitting. This is used by drivers that don't provide their own (accelerated) version. +config FB_CFB_REV_PIXELS_IN_BYTE + bool + depends on FB + default n + ---help--- + Allow generic frame-buffer functions to work on displays with 1, 2 + and 4 bits per pixel depths which has opposite order of pixels in + byte order to bytes in long order. + config FB_SYS_FILLRECT tristate depends on FB
drivers/video/cfbcopyarea.c +9 -8
@@ -45,14 +45,14 @@ #endifstatic void bitcpy (unsigned long __iomem *dst,int dst_idx,const unsigned long __iomem *src, -int src_idx,int bits,unsigned n) +int src_idx,int bits,unsigned n,u32 bswapmask) {unsigned long first, last;int const shift = dst_idx-src_idx;int left, right; - first =FB_SHIFT_HIGH (~0UL , dst_idx); - last = ~(FB_SHIFT_HIGH (~0UL , (dst_idx+n) % bits)); + first =fb_shifted_pixels_mask_long (dst_idx, bswapmask); + last = ~fb_shifted_pixels_mask_long ((dst_idx+n) % bits, bswapmask);if (!shift) {// Same alignment for source and dest
@@ -185,7 +185,7 @@ bitcpy(unsigned long __iomem *dst, int dstatic void bitcpy_rev (unsigned long __iomem *dst,int dst_idx,const unsigned long __iomem *src, -int src_idx,int bits,unsigned n) +int src_idx,int bits,unsigned n,u32 bswapmask) {unsigned long first, last;int shift;
@@ -203,8 +203,8 @@ bitcpy_rev(unsigned long __iomem *dst, i shift = dst_idx-src_idx; - first =FB_SHIFT_LOW (~0UL , bits -1 - dst_idx); - last = ~(FB_SHIFT_LOW (~0UL , bits -1 - ((dst_idx-n) % bits))); + first =fb_shifted_pixels_mask_long (bits -1 - dst_idx, bswapmask); + last = ~fb_shifted_pixels_mask_long (bits -1 - ((dst_idx-n) % bits), bswapmask);if (!shift) {// Same alignment for source and dest
@@ -336,6 +336,7 @@ void cfb_copyarea(struct fb_info *p, conunsigned long __iomem *dst =NULL , *src =NULL ;int bits =BITS_PER_LONG , bytes = bits >>3 ;int dst_idx =0 , src_idx =0 , rev_copy =0 ; +u32 bswapmask =fb_compute_bswapmask (p);if (p->state !=FBINFO_STATE_RUNNING )return ;
@@ -368,7 +369,7 @@ void cfb_copyarea(struct fb_info *p, con src += src_idx >> (ffs (bits) -1 ); src_idx &= (bytes -1 );bitcpy_rev (dst, dst_idx, src, src_idx, bits, - width*p->var.bits_per_pixel); + width*p->var.bits_per_pixel, bswapmask); } }else {while (height--) {
@@ -377,7 +378,7 @@ void cfb_copyarea(struct fb_info *p, con src += src_idx >> (ffs (bits) -1 ); src_idx &= (bytes -1 );bitcpy (dst, dst_idx, src, src_idx, bits, - width*p->var.bits_per_pixel); + width*p->var.bits_per_pixel, bswapmask); dst_idx += bits_per_line; src_idx += bits_per_line; }
drivers/video/cfbfillrect.c +12 -8
@@ -36,15 +36,16 @@ #endif*/ static void -bitfill_aligned (unsigned long __iomem *dst,int dst_idx,unsigned long pat,unsigned n,int bits) +bitfill_aligned (unsigned long __iomem *dst,int dst_idx,unsigned long pat, +unsigned n,int bits,u32 bswapmask) {unsigned long first, last;if (!n)return ; - first =FB_SHIFT_HIGH (~0UL , dst_idx); - last = ~(FB_SHIFT_HIGH (~0UL , (dst_idx+n) % bits)); + first =fb_shifted_pixels_mask_long (dst_idx, bswapmask); + last = ~fb_shifted_pixels_mask_long ((dst_idx+n) % bits, bswapmask);if (dst_idx+n <= bits) {// Single word
@@ -146,7 +147,8 @@ bitfill_unaligned(unsigned long __iomem* Aligned pattern invert using 32/64-bit memory accesses */ static void -bitfill_aligned_rev (unsigned long __iomem *dst,int dst_idx,unsigned long pat,unsigned n,int bits) +bitfill_aligned_rev (unsigned long __iomem *dst,int dst_idx,unsigned long pat, +unsigned n,int bits,u32 bswapmask) {unsigned long val = pat, dat;unsigned long first, last;
@@ -154,8 +156,8 @@ bitfill_aligned_rev(unsigned long __iomeif (!n)return ; - first =FB_SHIFT_HIGH (~0UL , dst_idx); - last = ~(FB_SHIFT_HIGH (~0UL , (dst_idx+n) % bits)); + first =fb_shifted_pixels_mask_long (dst_idx, bswapmask); + last = ~fb_shifted_pixels_mask_long ((dst_idx+n) % bits, bswapmask);if (dst_idx+n <= bits) {// Single word
@@ -303,8 +305,10 @@ void cfb_fillrect(struct fb_info *p, conif (p->fbops->fb_sync) p->fbops->fb_sync (p);if (!left) { +u32 bswapmask =fb_compute_bswapmask (p);void (*fill_op32)(unsigned long __iomem *dst,int dst_idx, -unsigned long pat,unsigned n,int bits) =NULL ; +unsigned long pat,unsigned n,int bits, +u32 bswapmask) =NULL ;switch (rect->rop) {case ROP_XOR :
@@ -321,7 +325,7 @@ void cfb_fillrect(struct fb_info *p, conwhile (height--) { dst += dst_idx >> (ffs (bits) -1 ); dst_idx &= (bits -1 ); -fill_op32 (dst, dst_idx, pat, width*bpp, bits); +fill_op32 (dst, dst_idx, pat, width*bpp, bits, bswapmask); dst_idx += p->fix.line_length*8 ; } }else {
drivers/video/cfbimgblt.c +10 -7
@@ -33,6 +33,7 @@ #include <linux/module.h>#include <linux/string.h> #include <linux/fb.h> #include <asm/types.h> +#include "fb_draw.h" #define DEBUG
@@ -87,6 +88,7 @@ static inline void color_imageblit(constu32 null_bits =32 - bpp;u32 *palette = (u32 *) p->pseudo_palette;const u8 *src = image->data; +u32 bswapmask =fb_compute_bswapmask (p); dst2 = (u32 __iomem *) dst1;for (i = image->height; i--; ) {
@@ -96,7 +98,7 @@ static inline void color_imageblit(const val =0 ;if (start_index) { -u32 start_mask = ~(FB_SHIFT_HIGH (~(u32 )0 , start_index)); +u32 start_mask = ~fb_shifted_pixels_mask_u32 (start_index, bswapmask); val =FB_READL (dst) & start_mask; shift = start_index; }
@@ -107,7 +109,7 @@ static inline void color_imageblit(constelse color = *src; color <<=FB_LEFT_POS (bpp); - val |=FB_SHIFT_HIGH (color, shift); + val |=FB_SHIFT_HIGH (color, shift ^ bswapmask);if (shift >= null_bits) {FB_WRITEL (val, dst++);
@@ -119,7 +121,7 @@ static inline void color_imageblit(const src++; }if (shift) { -u32 end_mask =FB_SHIFT_HIGH (~(u32 )0 , shift); +u32 end_mask =fb_shifted_pixels_mask_u32 (shift, bswapmask);FB_WRITEL ((FB_READL (dst) & end_mask) | val, dst); }
@@ -147,7 +149,8 @@ static inline void slow_imageblit(constu32 spitch = (image->width+7 )/8 ;const u8 *src = image->data, *s;u32 i, j, l; - +u32 bswapmask =fb_compute_bswapmask (p); + dst2 = (u32 __iomem *) dst1; fgcolor <<=FB_LEFT_POS (bpp); bgcolor <<=FB_LEFT_POS (bpp);
@@ -161,7 +164,7 @@ static inline void slow_imageblit(const/* write leading bits */ if (start_index) { -u32 start_mask = ~(FB_SHIFT_HIGH (~(u32 )0 ,start_index)); +u32 start_mask = ~fb_shifted_pixels_mask_u32 (start_index, bswapmask); val =FB_READL (dst) & start_mask; shift = start_index; }
@@ -169,7 +172,7 @@ static inline void slow_imageblit(constwhile (j--) { l--; color = (*s & (1 << l)) ? fgcolor : bgcolor; - val |=FB_SHIFT_HIGH (color, shift); + val |=FB_SHIFT_HIGH (color, shift ^ bswapmask);/* Did the bitshift spill bits to the next long? */ if (shift >= null_bits) {
@@ -184,7 +187,7 @@ static inline void slow_imageblit(const/* write trailing bits */ if (shift) { -u32 end_mask =FB_SHIFT_HIGH (~(u32 )0 , shift); +u32 end_mask =fb_shifted_pixels_mask_u32 (shift, bswapmask);FB_WRITEL ((FB_READL (dst) & end_mask) | val, dst); }
drivers/video/fb_draw.h +68 -0
78 lines not on this page · raw message
include/linux/fb.h +1 -0
@@ -180,6 +180,7 @@ struct fb_bitfield { };#define FB_NONSTD_HAM 1/* Hold-And-Modify (HAM) */ +#define FB_NONSTD_REV_PIX_IN_B 2/* order of pixels in each byte is reversed */ #define FB_ACTIVATE_NOW 0/* set values immediately (or vbl)*/ #define FB_ACTIVATE_NXTOPEN 1/* activate on next open */
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/