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

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


File: drivers/video/console/bitblit.c
Instrumentation mode: function-decision-multicondition
TER: 49 % ( 76/154)

Start/ End/    
True False - Line Source

  1 /*
  2  *  linux/drivers/video/console/bitblit.c -- BitBlitting Operation
  3  *
  4  *  Originally from the 'accel_*' routines in drivers/video/console/fbcon.c
  5  *
  6  *      Copyright (C) 2004 Antonino Daplas <adaplas @pol.net>
  7  *
  8  *  This file is subject to the terms and conditions of the GNU General Public
  9  *  License.  See the file COPYING in the main directory of this archive for
  10  *  more details.
  11  */
  12 
  13 #include <linux/config.h>
  14 #include <linux/module.h>
  15 #include <linux/string.h>
  16 #include <linux/fb.h>
  17 #include <linux/vt_kern.h>
  18 #include <linux/console.h>
  19 #include <asm/types.h>
  20 #include "fbcon.h"
  21 
  22 /*
  23  * Accelerated handlers.
  24  */
 
- 25 static inline void update_attr(u8 *dst, u8 *src, int attribute,
  26                 struct vc_data *vc)
  27 {
    28    int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
- 28 ternary-?: ( vc -> vc_font . height < 10 )
  29    int width = (vc->vc_font.width + 7) >> 3;
  30    unsigned int cellsize = vc->vc_font.height * width;
  31    u8 c;
  32 
  33    offset = cellsize - (offset * width);
- 34    for (i = 0; i < cellsize; i++) {
  35       c = src[i];
- 36       if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i >= offset)
 - 36     T && T
 - 36     T && F
 - 36     F && _
  37          c = 0xff;
- 38       if (attribute & FBCON_ATTRIBUTE_BOLD)
  39          c |= c >> 1;
- 40       if (attribute & FBCON_ATTRIBUTE_REVERSE)
  41          c = ~c;
  42       dst[i] = c;
  43    }
  44 }
  45 
 
3070 3070   46 static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
  47             int sx, int dy, int dx, int height, int width)
  48 {
  49    struct fb_copyarea area;
  50 
  51    area.sx = sx * vc->vc_font.width;
  52    area.sy = sy * vc->vc_font.height;
  53    area.dx = dx * vc->vc_font.width;
  54    area.dy = dy * vc->vc_font.height;
  55    area.height = height * vc->vc_font.height;
  56    area.width = width * vc->vc_font.width;
  57 
  58    info->fbops->fb_copyarea(info, &area);
  59 }
  60 
 
3974 3974   61 static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
  62             int sx, int height, int width)
  63 {
    64    int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
3974 - 64 ternary-?: ( vc -> vc_hi_font_mask )
  65    struct fb_fillrect region;
  66 
    67    region.color = attr_bgcol_ec(bgshift, vc);
3974 - 67 ternary-?: ( vc )
  68    region.dx = sx * vc->vc_font.width;
  69    region.dy = sy * vc->vc_font.height;
  70    region.width = width * vc->vc_font.width;
  71    region.height = height * vc->vc_font.height;
  72    region.rop = ROP_COPY;
  73 
  74    info->fbops->fb_fillrect(info, &region);
  75 }
  76 
 
251125 251125   77 static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
  78                  const u16 *s, u32 attr, u32 cnt,
  79                  u32 d_pitch, u32 s_pitch, u32 cellsize,
  80                  struct fb_image *image, u8 *buf, u8 *dst)
  81 {
    82    u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
251125 - 82 ternary-?: vc -> vc_hi_font_mask
  83    u32 idx = vc->vc_font.width >> 3;
  84    u8 *src;
  85 
2796E3 251125   86    while (cnt--) {
  87       src = vc->vc_font.data + (scr_readw(s++)&
  88                  charmask)*cellsize;
  89 
2796E3 - 90       if (attr) {
  91          update_attr(buf, src, attr, vc);
  92          src = buf;
  93       }
  94 
2796E3 - 95       if (likely(idx == 1))
  96          __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
  97                   image->height);
    98       else
  99          fb_pad_aligned_buffer(dst, d_pitch, src, idx,
  100                      image->height);
  101 
  102       dst += s_pitch;
  103    }
  104 
  105    info->fbops->fb_imageblit(info, image);
  106 }
  107 
 
- 108 static inline void bit_putcs_unaligned(struct vc_data *vc,
  109                    struct fb_info *info, const u16 *s,
  110                    u32 attr, u32 cnt, u32 d_pitch,
  111                    u32 s_pitch, u32 cellsize,
  112                    struct fb_image *image, u8 *buf,
  113                    u8 *dst)
  114 {
    115    u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- 115 ternary-?: vc -> vc_hi_font_mask
  116    u32 shift_low = 0, mod = vc->vc_font.width % 8;
  117    u32 shift_high = 8;
  118    u32 idx = vc->vc_font.width >> 3;
  119    u8 *src;
  120 
- 121    while (cnt--) {
  122       src = vc->vc_font.data + (scr_readw(s++)&
  123                  charmask)*cellsize;
  124 
- 125       if (attr) {
  126          update_attr(buf, src, attr, vc);
  127          src = buf;
  128       }
  129 
  130       fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
  131                image->height, shift_high,
  132                shift_low, mod);
  133       shift_low += mod;
    134       dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
- 134   ternary-?: ( shift_low >= 8 )
  135       shift_low &= 7;
  136       shift_high = 8 - shift_low;
  137    }
  138 
  139    info->fbops->fb_imageblit(info, image);
  140 
  141 }
  142 
 
251125 251125   143 static void bit_putcs(struct vc_data *vc, struct fb_info *info,
  144             const unsigned short *s, int count, int yy, int xx,
  145             int fg, int bg)
  146 {
  147    struct fb_image image;
  148    u32 width = (vc->vc_font.width + 7)/8;
  149    u32 cellsize = width * vc->vc_font.height;
  150    u32 maxcnt = info->pixmap.size/cellsize;
  151    u32 scan_align = info->pixmap.scan_align - 1;
  152    u32 buf_align = info->pixmap.buf_align - 1;
  153    u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
  154    u32 attribute = get_attribute(info, scr_readw(s));
  155    u8 *dst, *buf = NULL;
  156 
  157    image.fg_color = fg;
  158    image.bg_color = bg;
  159    image.dx = xx * vc->vc_font.width;
  160    image.dy = yy * vc->vc_font.height;
  161    image.height = vc->vc_font.height;
  162    image.depth = 1;
  163 
251125 - 164    if (attribute) {
  165       buf = kmalloc(cellsize, GFP_KERNEL);
- 166       if (!buf)
 - 167          return;
  168    }
  169 
251125 251125   170    while (count) {
251125 - 171       if (count > maxcnt)
  172          cnt = maxcnt;
    173       else
  174          cnt = count;
  175 
  176       image.width = vc->vc_font.width * cnt;
  177       pitch = ((image.width + 7) >> 3) + scan_align;
  178       pitch &= ~scan_align;
  179       size = pitch * image.height + buf_align;
  180       size &= ~buf_align;
  181       dst = fb_get_buffer_offset(info, &info->pixmap, size);
  182       image.data = dst;
  183 
251125 - 184       if (!mod)
  185          bit_putcs_aligned(vc, info, s, attribute, cnt, pitch,
  186                  width, cellsize, &image, buf, dst);
    187       else
  188          bit_putcs_unaligned(vc, info, s, attribute, cnt,
  189                    pitch, width, cellsize, &image,
  190                    buf, dst);
  191 
  192       image.dx += cnt * vc->vc_font.width;
  193       count -= cnt;
  194       s += cnt;
  195    }
  196 
  197    /* buf is always NULL except when in monochrome mode, so in this case
  198       it's a gain to check buf against NULL even though kfree() handles
  199       NULL pointers just fine */
251125 - 200    if (unlikely(buf))
  201       kfree(buf);
  202 
  203 }
  204 
 
52 52   205 static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
  206                int bottom_only)
  207 {
    208    int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
52 - 208 ternary-?: ( vc -> vc_hi_font_mask )
  209    unsigned int cw = vc->vc_font.width;
  210    unsigned int ch = vc->vc_font.height;
  211    unsigned int rw = info->var.xres - (vc->vc_cols*cw);
  212    unsigned int bh = info->var.yres - (vc->vc_rows*ch);
  213    unsigned int rs = info->var.xres - rw;
  214    unsigned int bs = info->var.yres - bh;
  215    struct fb_fillrect region;
  216 
    217    region.color = attr_bgcol_ec(bgshift, vc);
52 - 217 ternary-?: ( vc )
  218    region.rop = ROP_COPY;
  219 
52 - 220    if (rw && !bottom_only) {
 - 220   T && T
 - 220   T && F
 52   220   F && _
  221       region.dx = info->var.xoffset + rs;
  222       region.dy = 0;
  223       region.width = rw;
  224       region.height = info->var.yres_virtual;
  225       info->fbops->fb_fillrect(info, &region);
  226    }
  227 
52 - 228    if (bh) {
  229       region.dx = info->var.xoffset;
  230       region.dy = info->var.yoffset + bs;
  231       region.width = rs;
  232       region.height = bh;
  233       info->fbops->fb_fillrect(info, &region);
  234    }
  235 }
  236 
 
38656 38656   237 static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
  238              int softback_lines, int fg, int bg)
  239 {
  240    struct fb_cursor cursor;
  241    struct fbcon_ops *ops = info->fbcon_par;
    242    unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
38656 - 242 ternary-?: vc -> vc_hi_font_mask
  243    int w = (vc->vc_font.width + 7) >> 3, c;
  244    int y = real_y(ops->p, vc->vc_y);
  245    int attribute, use_sw = (vc->vc_cursor_type & 0x10);
  246    int err = 1;
  247    char *src;
  248 
  249    cursor.set = 0;
  250 
38656 - 251    if (softback_lines) {
- 252       if (y + softback_lines >= vc->vc_rows) {
  253          mode = CM_ERASE;
  254          ops->cursor_flash = 0;
 - 255          return;
    256       } else
  257          y += softback_lines;
  258    }
  259 
  260     c = scr_readw((u16 *) vc->vc_pos);
  261    attribute = get_attribute(info, c);
  262    src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
  263 
  264    if (ops->cursor_state.image.data != src ||
5106 33550   265        ops->cursor_reset) {
5052    265   T || _
54    265   F || T
 33550   265   F || F
  266        ops->cursor_state.image.data = src;
  267        cursor.set |= FB_CUR_SETIMAGE;
  268    }
  269 
38656 - 270    if (attribute) {
  271       u8 *dst;
  272 
  273       dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
- 274       if (!dst)
 - 275          return;
  276       kfree(ops->cursor_data);
  277       ops->cursor_data = dst;
  278       update_attr(dst, src, attribute, vc);
  279       src = dst;
  280    }
  281 
  282    if (ops->cursor_state.image.fg_color != fg ||
  283        ops->cursor_state.image.bg_color != bg ||
854 37802   284        ops->cursor_reset) {
800    284   T || _ || _
 - 284   F || T || _
54    284   F || F || T
 37802   284   F || F || F
  285       ops->cursor_state.image.fg_color = fg;
  286       ops->cursor_state.image.bg_color = bg;
  287       cursor.set |= FB_CUR_SETCMAP;
  288    }
  289 
  290    if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->vc_x)) ||
  291        (ops->cursor_state.image.dy != (vc->vc_font.height * y)) ||
9990 28666   292        ops->cursor_reset) {
9406    292   (T) || (_) || _
546    292   (F) || (T) || _
38    292   (F) || (F) || T
 28666   292   (F) || (F) || F
  293       ops->cursor_state.image.dx = vc->vc_font.width * vc->vc_x;
  294       ops->cursor_state.image.dy = vc->vc_font.height * y;
  295       cursor.set |= FB_CUR_SETPOS;
  296    }
  297 
  298    if (ops->cursor_state.image.height != vc->vc_font.height ||
  299        ops->cursor_state.image.width != vc->vc_font.width ||
60 38596   300        ops->cursor_reset) {
   300   T || _ || _
 - 300   F || T || _
54    300   F || F || T
 38596   300   F || F || F
  301       ops->cursor_state.image.height = vc->vc_font.height;
  302       ops->cursor_state.image.width = vc->vc_font.width;
  303       cursor.set |= FB_CUR_SETSIZE;
  304    }
  305 
  306    if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
54 38602   307        ops->cursor_reset) {
 - 307   T || _ || _
 - 307   F || T || _
54    307   F || F || T
 38602   307   F || F || F
  308       ops->cursor_state.hot.x = cursor.hot.y = 0;
  309       cursor.set |= FB_CUR_SETHOT;
  310    }
  311 
  312    if (cursor.set & FB_CUR_SETSIZE ||
  313        vc->vc_cursor_type != ops->p->cursor_shape ||
  314        ops->cursor_state.mask == NULL ||
66 38590   315        ops->cursor_reset) {
60    315   T || _ || _ || _
   315   F || T || _ || _
 - 315   F || F || T || _
 - 315   F || F || F || T
 38590   315   F || F || F || F
  316       char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
  317       int cur_height, size, i = 0;
  318       u8 msk = 0xff;
  319 
66 - 320       if (!mask)
 - 321          return;
  322 
  323       kfree(ops->cursor_state.mask);
  324       ops->cursor_state.mask = mask;
  325 
  326       ops->p->cursor_shape = vc->vc_cursor_type;
  327       cursor.set |= FB_CUR_SETSHAPE;
  328 
    329       switch (ops->p->cursor_shape & CUR_HWMASK) {
 - 330       case CUR_NONE:
  331          cur_height = 0;
 - 332          break;
66    333       case CUR_UNDERLINE:
    334          cur_height = (vc->vc_font.height < 10) ? 1 : 2;
66 - 334     ternary-?: ( vc -> vc_font . height < 10 )
66    335          break;
 - 336       case CUR_LOWER_THIRD:
  337          cur_height = vc->vc_font.height/3;
 - 338          break;
 - 339       case CUR_LOWER_HALF:
  340          cur_height = vc->vc_font.height >> 1;
 - 341          break;
 - 342       case CUR_TWO_THIRDS:
  343          cur_height = (vc->vc_font.height << 1)/3;
 - 344          break;
 - 345       case CUR_BLOCK:
 - 346       default:
  347          cur_height = vc->vc_font.height;
 - 348          break;
  349       }
  350       size = (vc->vc_font.height - cur_height) * w;
924 66   351       while (size--)
  352          mask[i++] = ~msk;
  353       size = cur_height * w;
132 66   354       while (size--)
  355          mask[i++] = msk;
  356    }
  357 
    358    switch (mode) {
20628    359    case CM_ERASE:
  360       ops->cursor_state.enable = 0;
20628    361       break;
18028    362    case CM_DRAW:
 - 363    case CM_MOVE:
 - 364    default:
    365       ops->cursor_state.enable = (use_sw) ? 0 : 1;
18028 - 365   ternary-?: ( use_sw )
18028    366       break;
  367    }
  368 
  369    cursor.image.data = src;
  370    cursor.image.fg_color = ops->cursor_state.image.fg_color;
  371    cursor.image.bg_color = ops->cursor_state.image.bg_color;
  372    cursor.image.dx = ops->cursor_state.image.dx;
  373    cursor.image.dy = ops->cursor_state.image.dy;
  374    cursor.image.height = ops->cursor_state.image.height;
  375    cursor.image.width = ops->cursor_state.image.width;
  376    cursor.hot.x = ops->cursor_state.hot.x;
  377    cursor.hot.y = ops->cursor_state.hot.y;
  378    cursor.mask = ops->cursor_state.mask;
  379    cursor.enable = ops->cursor_state.enable;
  380    cursor.image.depth = 1;
  381    cursor.rop = ROP_XOR;
  382 
38656 - 383    if (info->fbops->fb_cursor)
  384       err = info->fbops->fb_cursor(info, &cursor);
  385 
38656 - 386    if (err)
  387       soft_cursor(info, &cursor);
  388 
  389    ops->cursor_reset = 0;
  390 }
  391 
 
40   392 static int bit_update_start(struct fb_info *info)
  393 {
  394    struct fbcon_ops *ops = info->fbcon_par;
  395    int err;
  396 
  397    err = fb_pan_display(info, &ops->var);
  398    ops->var.xoffset = info->var.xoffset;
  399    ops->var.yoffset = info->var.yoffset;
  400    ops->var.vmode = info->var.vmode;
40    401    return err;
  402 }
  403 
 
137 137   404 void fbcon_set_bitops(struct fbcon_ops *ops)
  405 {
  406    ops->bmove = bit_bmove;
  407    ops->clear = bit_clear;
  408    ops->putcs = bit_putcs;
  409    ops->clear_margins = bit_clear_margins;
  410    ops->cursor = bit_cursor;
  411    ops->update_start = bit_update_start;
  412    ops->rotate_font = NULL;
  413 
137 - 414    if (ops->rotate)
    415       fbcon_set_rotate(ops);
- 415   do-while (0)
  416 }
  417 
  418 EXPORT_SYMBOL(fbcon_set_bitops);
  419 
  420 MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
  421 MODULE_DESCRIPTION("Bit Blitting Operation");
  422 MODULE_LICENSE("GPL");
  423 
***TER 49% (76/154) of SOURCE FILE bitblit.c

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