CTC++ Coverage Report - Execution Profile    #816/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/video/cfbimgblt.c
Instrumentation mode: function-decision-multicondition
TER: 43 % ( 33/ 76)

Start/ End/    
True False - Line Source

  1 /*
  2  *  Generic BitBLT function for frame buffer with packed pixels of any depth.
  3  *
  4  *      Copyright (C)  June 1999 James Simmons
  5  *
  6  *  This file is subject to the terms and conditions of the GNU General Public
  7  *  License.  See the file COPYING in the main directory of this archive for
  8  *  more details.
  9  *
  10  * NOTES:
  11  *
  12  *    This function copys a image from system memory to video memory. The
  13  *  image can be a bitmap where each 0 represents the background color and
  14  *  each 1 represents the foreground color. Great for font handling. It can
  15  *  also be a color image. This is determined by image_depth. The color image
  16  *  must be laid out exactly in the same format as the framebuffer. Yes I know
  17  *  their are cards with hardware that coverts images of various depths to the
  18  *  framebuffer depth. But not every card has this. All images must be rounded
  19  *  up to the nearest byte. For example a bitmap 12 bits wide must be two 
  20  *  bytes width. 
  21  *
  22  *  Tony: 
  23  *  Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API.  This speeds 
  24  *  up the code significantly.
  25  *  
  26  *  Code for depths not multiples of BITS_PER_LONG is still kludgy, which is
  27  *  still processed a bit at a time.   
  28  *
  29  *  Also need to add code to deal with cards endians that are different than
  30  *  the native cpu endians. I also need to deal with MSB position in the word.
  31  */
  32 #include <linux/config.h>
  33 #include <linux/module.h>
  34 #include <linux/string.h>
  35 #include <linux/fb.h>
  36 #include <asm/types.h>
  37 
  38 #define DEBUG
  39 
  40 #ifdef DEBUG
  41 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt,__FUNCTION__,## args)
  42 #else
  43 #define DPRINTK(fmt, args...)
  44 #endif
  45 
  46 static u32 cfb_tab8[] = {
  47 #if defined(__BIG_ENDIAN)
  48     0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
  49     0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
  50     0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
  51     0xffff0000,0xffff00ff,0xffffff00,0xffffffff
  52 #elif defined(__LITTLE_ENDIAN)
  53     0x00000000,0xff000000,0x00ff0000,0xffff0000,
  54     0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
  55     0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
  56     0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
  57 #else
  58 #error FIXME: No endianness??
  59 #endif
  60 };
  61 
  62 static u32 cfb_tab16[] = {
  63 #if defined(__BIG_ENDIAN)
  64     0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
  65 #elif defined(__LITTLE_ENDIAN)
  66     0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
  67 #else
  68 #error FIXME: No endianness??
  69 #endif
  70 };
  71 
  72 static u32 cfb_tab32[] = {
  73    0x00000000, 0xffffffff
  74 };
  75 
  76 #define FB_WRITEL fb_writel
  77 #define FB_READL  fb_readl
  78 
 
  79 static inline void color_imageblit(const struct fb_image *image, 
  80                struct fb_info *p, u8 __iomem *dst1, 
  81                u32 start_index,
  82                u32 pitch_index)
  83 {
  84    /* Draw the penguin */
  85    u32 __iomem *dst, *dst2;
  86    u32 color = 0, val, shift;
  87    int i, n, bpp = p->var.bits_per_pixel;
  88    u32 null_bits = 32 - bpp;
  89    u32 *palette = (u32 *) p->pseudo_palette;
  90    const u8 *src = image->data;
  91 
  92    dst2 = (u32 __iomem *) dst1;
480   93    for (i = image->height; i--; ) {
  94       n = image->width;
  95       dst = (u32 __iomem *) dst1;
  96       shift = 0;
  97       val = 0;
  98       
480 - 99       if (start_index) {
  100          u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, start_index));
  101          val = FB_READL(dst) & start_mask;
  102          shift = start_index;
  103       }
38400 480   104       while (n--) {
  105          if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
38400 - 106              p->fix.visual == FB_VISUAL_DIRECTCOLOR )
 - 106       T || _
 - 106       F || T
 38400   106       F || F
  107             color = palette[*src];
    108          else
  109             color = *src;
  110          color <<= FB_LEFT_POS(bpp);
  111          val |= FB_SHIFT_HIGH(color, shift);
9600 28800   112          if (shift >= null_bits) {
  113             FB_WRITEL(val, dst++);
  114    
    115             val = (shift == null_bits) ? 0 : 
9600 - 115       ternary-?: ( shift == null_bits )
  116                FB_SHIFT_LOW(color, 32 - shift);
  117          }
  118          shift += bpp;
  119          shift &= (32 - 1);
  120          src++;
  121       }
480 - 122       if (shift) {
  123          u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
  124 
  125          FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
  126       }
  127       dst1 += p->fix.line_length;
480 - 128       if (pitch_index) {
  129          dst2 += p->fix.line_length;
  130          dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1));
  131 
  132          start_index += pitch_index;
  133          start_index &= 32 - 1;
  134       }
  135    }
  136 }
  137 
 
- 138 static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, 
  139               u8 __iomem *dst1, u32 fgcolor,
  140               u32 bgcolor, 
  141               u32 start_index,
  142               u32 pitch_index)
  143 {
  144    u32 shift, color = 0, bpp = p->var.bits_per_pixel;
  145    u32 __iomem *dst, *dst2;
  146    u32 val, pitch = p->fix.line_length;
  147    u32 null_bits = 32 - bpp;
  148    u32 spitch = (image->width+7)/8;
  149    const u8 *src = image->data, *s;
  150    u32 i, j, l;
  151    
  152    dst2 = (u32 __iomem *) dst1;
  153    fgcolor <<= FB_LEFT_POS(bpp);
  154    bgcolor <<= FB_LEFT_POS(bpp);
  155 
- 156    for (i = image->height; i--; ) {
  157       shift = val = 0;
  158       l = 8;
  159       j = image->width;
  160       dst = (u32 __iomem *) dst1;
  161       s = src;
  162 
  163       /* write leading bits */
- 164       if (start_index) {
  165          u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index));
  166          val = FB_READL(dst) & start_mask;
  167          shift = start_index;
  168       }
  169 
- 170       while (j--) {
  171          l--;
    172          color = (*s & (1 << l)) ? fgcolor : bgcolor;
- 172     ternary-?: ( * s & ( 1 << l ) )
  173          val |= FB_SHIFT_HIGH(color, shift);
  174          
  175          /* Did the bitshift spill bits to the next long? */
- 176          if (shift >= null_bits) {
  177             FB_WRITEL(val, dst++);
    178             val = (shift == null_bits) ? 0 :
- 178       ternary-?: ( shift == null_bits )
  179                FB_SHIFT_LOW(color,32 - shift);
  180          }
  181          shift += bpp;
  182          shift &= (32 - 1);
- 183          if (!l) { l = 8; s++; };
  184       }
  185 
  186       /* write trailing bits */
- 187        if (shift) {
  188          u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
  189 
  190          FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
  191       }
  192       
  193       dst1 += pitch;
  194       src += spitch;   
- 195       if (pitch_index) {
  196          dst2 += pitch;
  197          dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1));
  198          start_index += pitch_index;
  199          start_index &= 32 - 1;
  200       }
  201       
  202    }
  203 }
  204 
  205 /*
  206  * fast_imageblit - optimized monochrome color expansion
  207  *
  208  * Only if:  bits_per_pixel == 8, 16, or 32
  209  *           image->width is divisible by pixel/dword (ppw);
  210  *           fix->line_legth is divisible by 4;
  211  *           beginning and end of a scanline is dword aligned
  212  */
 
289781 289781   213 static inline void fast_imageblit(const struct fb_image *image, struct fb_info *p, 
  214               u8 __iomem *dst1, u32 fgcolor, 
  215               u32 bgcolor) 
  216 {
  217    u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
  218    u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
  219    u32 bit_mask, end_mask, eorx, shift;
  220    const char *s = image->data, *src;
  221    u32 __iomem *dst;
  222    u32 *tab = NULL;
  223    int i, j, k;
  224       
    225    switch (bpp) {
289781    226    case 8:
  227       tab = cfb_tab8;
289781    228       break;
 - 229    case 16:
  230       tab = cfb_tab16;
 - 231       break;
 - 232    case 32:
  233       tab = cfb_tab32;
 - 234       break;
  235    }
  236 
869343 289781   237    for (i = ppw-1; i--; ) {
  238       fgx <<= bpp;
  239       bgx <<= bpp;
  240       fgx |= fgcolor;
  241       bgx |= bgcolor;
  242    }
  243    
  244    bit_mask = (1 << ppw) - 1;
  245    eorx = fgx ^ bgx;
  246    k = image->width/ppw;
  247 
4636E3 289781   248    for (i = image->height; i--; ) {
  249       dst = (u32 __iomem *) dst1, shift = 8; src = s;
  250       
9071E4 4636E3   251       for (j = k; j--; ) {
  252          shift -= ppw;
  253          end_mask = tab[(*src >> shift) & bit_mask];
  254          FB_WRITEL((end_mask & eorx)^bgx, dst++);
4535E4 4535E4   255          if (!shift) { shift = 8; src++; }      
  256       }
  257       dst1 += p->fix.line_length;
  258       s += spitch;
  259    }
  260 }   
  261    
 
289787 289787   262 void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
  263 {
  264    u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
  265    u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
  266    u32 width = image->width;
  267    u32 dx = image->dx, dy = image->dy;
  268    u8 __iomem *dst1;
  269 
289787 - 270    if (p->state != FBINFO_STATE_RUNNING)
 - 271       return;
  272 
  273    bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
  274    start_index = bitstart & (32 - 1);
  275    pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
  276 
  277    bitstart /= 8;
  278    bitstart &= ~(bpl - 1);
  279    dst1 = p->screen_base + bitstart;
  280 
289787 - 281    if (p->fbops->fb_sync)
  282       p->fbops->fb_sync(p);
  283 
289781   284    if (image->depth == 1) {
  285       if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
289781 - 286           p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 - 286     T || _
 - 286     F || T
 289781   286     F || F
  287          fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color];
  288          bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color];
    289       } else {
  290          fgcolor = image->fg_color;
  291          bgcolor = image->bg_color;
  292       }   
  293       
  294       if (32 % bpp == 0 && !start_index && !pitch_index && 
  295           ((width & (32/bpp-1)) == 0) &&
289781 - 296           bpp >= 8 && bpp <= 32)          
289781    296     T && T && T && (T) && T && T
 - 296     T && T && T && (T) && T && F
 - 296     T && T && T && (T) && F && _
 - 296     T && T && T && (F) && _ && _
 - 296     T && T && F && (_) && _ && _
 - 296     T && F && _ && (_) && _ && _
 - 296     F && _ && _ && (_) && _ && _
  297          fast_imageblit(image, p, dst1, fgcolor, bgcolor);
    298       else 
  299          slow_imageblit(image, p, dst1, fgcolor, bgcolor,
  300                start_index, pitch_index);
    301    } else
  302       color_imageblit(image, p, dst1, start_index, pitch_index);
  303 }
  304 
  305 EXPORT_SYMBOL(cfb_imageblit);
  306 
  307 MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
  308 MODULE_DESCRIPTION("Generic software accelerated imaging drawing");
  309 MODULE_LICENSE("GPL");
  310 
***TER 43% (33/76) of SOURCE FILE cfbimgblt.c

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last | Top