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

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


File: drivers/video/cfbfillrect.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/113)

Start/ End/    
True False - Line Source

  1 /*
  2  *  Generic fillrect for frame buffers with packed pixels of any depth.
  3  *
  4  *      Copyright (C)  2000 James Simmons (jsimmons@linux-fbdev.org)
  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  *  The code for depths like 24 that don't have integer number of pixels per
  13  *  long is broken and needs to be fixed. For now I turned these types of
  14  *  mode off.
  15  *
  16  *  Also need to add code to deal with cards endians that are different than
  17  *  the native cpu endians. I also need to deal with MSB position in the word.
  18  *
  19  */
  20 #include <linux/config.h>
  21 #include <linux/module.h>
  22 #include <linux/string.h>
  23 #include <linux/fb.h>
  24 #include <asm/types.h>
  25 
  26 #if BITS_PER_LONG == 32
  27 #  define FB_WRITEL fb_writel
  28 #  define FB_READL  fb_readl
  29 #else
  30 #  define FB_WRITEL fb_writeq
  31 #  define FB_READL  fb_readq
  32 #endif
  33 
  34     /*
  35      *  Compose two values, using a bitmask as decision value
  36      *  This is equivalent to (a & mask) | (b & ~mask)
  37      */
  38 
  39 static inline unsigned long
 
- 40 comp(unsigned long a, unsigned long b, unsigned long mask)
  41 {
 - 42     return ((a ^ b) & mask) ^ b;
  43 }
  44 
  45     /*
  46      *  Create a pattern with the given pixel's color
  47      */
  48 
  49 #if BITS_PER_LONG == 64
  50 static inline unsigned long
 
- 51 pixel_to_pat( u32 bpp, u32 pixel)
  52 {
    53    switch (bpp) {
 - 54    case 1:
 - 55       return 0xfffffffffffffffful*pixel;
 - 56    case 2:
 - 57       return 0x5555555555555555ul*pixel;
 - 58    case 4:
 - 59       return 0x1111111111111111ul*pixel;
 - 60    case 8:
 - 61       return 0x0101010101010101ul*pixel;
 - 62    case 12:
 - 63       return 0x0001001001001001ul*pixel;
 - 64    case 16:
 - 65       return 0x0001000100010001ul*pixel;
 - 66    case 24:
 - 67       return 0x0000000001000001ul*pixel;
 - 68    case 32:
 - 69       return 0x0000000100000001ul*pixel;
 - 70    default:
  71       panic("pixel_to_pat(): unsupported pixelformat\n");
  72     }
  73 }
  74 #else
  75 static inline unsigned long
  76 pixel_to_pat( u32 bpp, u32 pixel)
  77 {
  78    switch (bpp) {
  79    case 1:
  80       return 0xfffffffful*pixel;
  81    case 2:
  82       return 0x55555555ul*pixel;
  83    case 4:
  84       return 0x11111111ul*pixel;
  85    case 8:
  86       return 0x01010101ul*pixel;
  87    case 12:
  88       return 0x00001001ul*pixel;
  89    case 16:
  90       return 0x00010001ul*pixel;
  91    case 24:
  92       return 0x00000001ul*pixel;
  93    case 32:
  94       return 0x00000001ul*pixel;
  95    default:
  96       panic("pixel_to_pat(): unsupported pixelformat\n");
  97     }
  98 }
  99 #endif
  100 
  101     /*
  102      *  Aligned pattern fill using 32/64-bit memory accesses
  103      */
  104 
  105 static void
 
- 106 bitfill_aligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsigned n, int bits)
  107 {
  108    unsigned long first, last;
  109 
- 110    if (!n)
 - 111       return;
  112 
  113    first = FB_SHIFT_HIGH(~0UL, dst_idx);
  114    last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
  115 
- 116    if (dst_idx+n <= bits) {
  117       // Single word
- 118       if (last)
  119          first &= last;
  120       FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
    121    } else {
  122       // Multiple destination words
  123 
  124       // Leading bits
- 125       if (first!= ~0UL) {
  126          FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
  127          dst++;
  128          n -= bits - dst_idx;
  129       }
  130 
  131       // Main chunk
  132       n /= bits;
- 133       while (n >= 8) {
  134          FB_WRITEL(pat, dst++);
  135          FB_WRITEL(pat, dst++);
  136          FB_WRITEL(pat, dst++);
  137          FB_WRITEL(pat, dst++);
  138          FB_WRITEL(pat, dst++);
  139          FB_WRITEL(pat, dst++);
  140          FB_WRITEL(pat, dst++);
  141          FB_WRITEL(pat, dst++);
  142          n -= 8;
  143       }
- 144       while (n--)
  145          FB_WRITEL(pat, dst++);
  146 
  147       // Trailing bits
- 148       if (last)
  149          FB_WRITEL(comp(pat, FB_READL(dst), last), dst);
  150    }
  151 }
  152 
  153 
  154     /*
  155      *  Unaligned generic pattern fill using 32/64-bit memory accesses
  156      *  The pattern must have been expanded to a full 32/64-bit value
  157      *  Left/right are the appropriate shifts to convert to the pattern to be
  158      *  used for the next 32/64-bit word
  159      */
  160 
  161 static void
 
- 162 bitfill_unaligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
  163          int left, int right, unsigned n, int bits)
  164 {
  165    unsigned long first, last;
  166 
- 167    if (!n)
 - 168       return;
  169 
  170    first = FB_SHIFT_HIGH(~0UL, dst_idx);
  171    last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
  172 
- 173    if (dst_idx+n <= bits) {
  174       // Single word
- 175       if (last)
  176          first &= last;
  177       FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
    178    } else {
  179       // Multiple destination words
  180       // Leading bits
- 181       if (first) {
  182          FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
  183          dst++;
  184          pat = pat << left | pat >> right;
  185          n -= bits - dst_idx;
  186       }
  187 
  188       // Main chunk
  189       n /= bits;
- 190       while (n >= 4) {
  191          FB_WRITEL(pat, dst++);
  192          pat = pat << left | pat >> right;
  193          FB_WRITEL(pat, dst++);
  194          pat = pat << left | pat >> right;
  195          FB_WRITEL(pat, dst++);
  196          pat = pat << left | pat >> right;
  197          FB_WRITEL(pat, dst++);
  198          pat = pat << left | pat >> right;
  199          n -= 4;
  200       }
- 201       while (n--) {
  202          FB_WRITEL(pat, dst++);
  203          pat = pat << left | pat >> right;
  204       }
  205 
  206       // Trailing bits
- 207       if (last)
  208          FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
  209    }
  210 }
  211 
  212     /*
  213      *  Aligned pattern invert using 32/64-bit memory accesses
  214      */
  215 static void
 
- 216 bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsigned n, int bits)
  217 {
  218    unsigned long val = pat, dat;
  219    unsigned long first, last;
  220 
- 221    if (!n)
 - 222       return;
  223 
  224    first = FB_SHIFT_HIGH(~0UL, dst_idx);
  225    last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
  226 
- 227    if (dst_idx+n <= bits) {
  228       // Single word
- 229       if (last)
  230          first &= last;
  231       dat = FB_READL(dst);
  232       FB_WRITEL(comp(dat ^ val, dat, first), dst);
    233    } else {
  234       // Multiple destination words
  235       // Leading bits
- 236       if (first!=0UL) {
  237          dat = FB_READL(dst);
  238          FB_WRITEL(comp(dat ^ val, dat, first), dst);
  239          dst++;
  240          n -= bits - dst_idx;
  241       }
  242 
  243       // Main chunk
  244       n /= bits;
- 245       while (n >= 8) {
  246          FB_WRITEL(FB_READL(dst) ^ val, dst);
  247          dst++;
  248          FB_WRITEL(FB_READL(dst) ^ val, dst);
  249          dst++;
  250          FB_WRITEL(FB_READL(dst) ^ val, dst);
  251          dst++;
  252          FB_WRITEL(FB_READL(dst) ^ val, dst);
  253          dst++;
  254          FB_WRITEL(FB_READL(dst) ^ val, dst);
  255          dst++;
  256          FB_WRITEL(FB_READL(dst) ^ val, dst);
  257          dst++;
  258          FB_WRITEL(FB_READL(dst) ^ val, dst);
  259          dst++;
  260          FB_WRITEL(FB_READL(dst) ^ val, dst);
  261          dst++;
  262          n -= 8;
  263       }
- 264       while (n--) {
  265          FB_WRITEL(FB_READL(dst) ^ val, dst);
  266          dst++;
  267       }
  268       // Trailing bits
- 269       if (last) {
  270          dat = FB_READL(dst);
  271          FB_WRITEL(comp(dat ^ val, dat, last), dst);
  272       }
  273    }
  274 }
  275 
  276 
  277     /*
  278      *  Unaligned generic pattern invert using 32/64-bit memory accesses
  279      *  The pattern must have been expanded to a full 32/64-bit value
  280      *  Left/right are the appropriate shifts to convert to the pattern to be
  281      *  used for the next 32/64-bit word
  282      */
  283 
  284 static void
 
- 285 bitfill_unaligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
  286          int left, int right, unsigned n, int bits)
  287 {
  288    unsigned long first, last, dat;
  289 
- 290    if (!n)
 - 291       return;
  292 
  293    first = FB_SHIFT_HIGH(~0UL, dst_idx);
  294    last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
  295 
- 296    if (dst_idx+n <= bits) {
  297       // Single word
- 298       if (last)
  299          first &= last;
  300       dat = FB_READL(dst);
  301       FB_WRITEL(comp(dat ^ pat, dat, first), dst);
    302    } else {
  303       // Multiple destination words
  304 
  305       // Leading bits
- 306       if (first != 0UL) {
  307          dat = FB_READL(dst);
  308          FB_WRITEL(comp(dat ^ pat, dat, first), dst);
  309          dst++;
  310          pat = pat << left | pat >> right;
  311          n -= bits - dst_idx;
  312       }
  313 
  314       // Main chunk
  315       n /= bits;
- 316       while (n >= 4) {
  317          FB_WRITEL(FB_READL(dst) ^ pat, dst);
  318          dst++;
  319          pat = pat << left | pat >> right;
  320          FB_WRITEL(FB_READL(dst) ^ pat, dst);
  321          dst++;
  322          pat = pat << left | pat >> right;
  323          FB_WRITEL(FB_READL(dst) ^ pat, dst);
  324          dst++;
  325          pat = pat << left | pat >> right;
  326          FB_WRITEL(FB_READL(dst) ^ pat, dst);
  327          dst++;
  328          pat = pat << left | pat >> right;
  329          n -= 4;
  330       }
- 331       while (n--) {
  332          FB_WRITEL(FB_READL(dst) ^ pat, dst);
  333          dst++;
  334          pat = pat << left | pat >> right;
  335       }
  336 
  337       // Trailing bits
- 338       if (last) {
  339          dat = FB_READL(dst);
  340          FB_WRITEL(comp(dat ^ pat, dat, last), dst);
  341       }
  342    }
  343 }
  344 
 
- 345 void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
  346 {
  347    unsigned long pat, fg;
  348    unsigned long width = rect->width, height = rect->height;
  349    int bits = BITS_PER_LONG, bytes = bits >> 3;
  350    u32 bpp = p->var.bits_per_pixel;
  351    unsigned long __iomem *dst;
  352    int dst_idx, left;
  353 
- 354    if (p->state != FBINFO_STATE_RUNNING)
 - 355       return;
  356 
  357    if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
- 358        p->fix.visual == FB_VISUAL_DIRECTCOLOR )
 - 358   T || _
 - 358   F || T
 - 358   F || F
  359       fg = ((u32 *) (p->pseudo_palette))[rect->color];
    360    else
  361       fg = rect->color;
  362 
  363    pat = pixel_to_pat( bpp, fg);
  364 
  365    dst = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));
  366    dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8;
  367    dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp;
  368    /* FIXME For now we support 1-32 bpp only */
  369    left = bits % bpp;
- 370    if (p->fbops->fb_sync)
  371       p->fbops->fb_sync(p);
- 372    if (!left) {
  373       void (*fill_op32)(unsigned long __iomem *dst, int dst_idx,
  374                         unsigned long pat, unsigned n, int bits) = NULL;
  375 
    376       switch (rect->rop) {
 - 377       case ROP_XOR:
  378          fill_op32 = bitfill_aligned_rev;
 - 379          break;
 - 380       case ROP_COPY:
  381          fill_op32 = bitfill_aligned;
 - 382          break;
 - 383       default:
  384          printk( KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY\n");
  385          fill_op32 = bitfill_aligned;
 - 386          break;
  387       }
- 388       while (height--) {
  389          dst += dst_idx >> (ffs(bits) - 1);
  390          dst_idx &= (bits - 1);
  391          fill_op32(dst, dst_idx, pat, width*bpp, bits);
  392          dst_idx += p->fix.line_length*8;
  393       }
    394    } else {
  395       int right;
  396       int r;
  397       int rot = (left-dst_idx) % bpp;
  398       void (*fill_op)(unsigned long __iomem *dst, int dst_idx,
  399                       unsigned long pat, int left, int right,
  400                       unsigned n, int bits) = NULL;
  401 
  402       /* rotate pattern to correct start position */
  403       pat = pat << rot | pat >> (bpp-rot);
  404 
  405       right = bpp-left;
    406       switch (rect->rop) {
 - 407       case ROP_XOR:
  408          fill_op = bitfill_unaligned_rev;
 - 409          break;
 - 410       case ROP_COPY:
  411          fill_op = bitfill_unaligned;
 - 412          break;
 - 413       default:
  414          printk( KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY\n");
  415          fill_op = bitfill_unaligned;
 - 416          break;
  417       }
- 418       while (height--) {
  419          dst += dst_idx >> (ffs(bits) - 1);
  420          dst_idx &= (bits - 1);
  421          fill_op(dst, dst_idx, pat, left, right,
  422             width*bpp, bits);
  423          r = (p->fix.line_length*8) % bpp;
  424          pat = pat << (bpp-r) | pat >> r;
  425          dst_idx += p->fix.line_length*8;
  426       }
  427    }
  428 }
  429 
  430 EXPORT_SYMBOL(cfb_fillrect);
  431 
  432 MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
  433 MODULE_DESCRIPTION("Generic software accelerated fill rectangle");
  434 MODULE_LICENSE("GPL");
***TER 0% (0/113) of SOURCE FILE cfbfillrect.c

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