The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/rasops/rasops24.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: rasops24.c,v 1.17 2002/09/05 08:02:29 petrov Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Andrew Doran.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.17 2002/09/05 08:02:29 petrov Exp $");
   41 
   42 #include "opt_rasops.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/time.h>
   47 
   48 #include <machine/endian.h>
   49 #include <machine/bswap.h>
   50 
   51 #include <dev/wscons/wsdisplayvar.h>
   52 #include <dev/wscons/wsconsio.h>
   53 #include <dev/rasops/rasops.h>
   54 
   55 static void     rasops24_erasecols __P((void *, int, int, int, long));
   56 static void     rasops24_eraserows __P((void *, int, int, long));
   57 static void     rasops24_putchar __P((void *, int, int, u_int, long attr));
   58 #ifndef RASOPS_SMALL
   59 static void     rasops24_putchar8 __P((void *, int, int, u_int, long attr));
   60 static void     rasops24_putchar12 __P((void *, int, int, u_int, long attr));
   61 static void     rasops24_putchar16 __P((void *, int, int, u_int, long attr));
   62 static void     rasops24_makestamp __P((struct rasops_info *, long));
   63 #endif
   64 
   65 /*
   66  * 4x1 stamp for optimized character blitting
   67  */
   68 static int32_t  stamp[64];
   69 static long     stamp_attr;
   70 static int      stamp_mutex;    /* XXX see note in readme */
   71 
   72 /*
   73  * XXX this confuses the hell out of gcc2 (not egcs) which always insists
   74  * that the shift count is negative.
   75  *
   76  * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
   77  * destination int32_t[0] = STAMP_READ(offset)
   78  * destination int32_t[1] = STAMP_READ(offset + 4)
   79  * destination int32_t[2] = STAMP_READ(offset + 8)
   80  */
   81 #define STAMP_SHIFT(fb,n)       ((n*4-4) >= 0 ? (fb)>>(n*4-4):(fb)<<-(n*4-4))
   82 #define STAMP_MASK              (0xf << 4)
   83 #define STAMP_READ(o)           (*(int32_t *)((caddr_t)stamp + (o)))
   84 
   85 /*
   86  * Initialize rasops_info struct for this colordepth.
   87  */
   88 void
   89 rasops24_init(ri)
   90         struct rasops_info *ri;
   91 {
   92 
   93         switch (ri->ri_font->fontwidth) {
   94 #ifndef RASOPS_SMALL
   95         case 8:
   96                 ri->ri_ops.putchar = rasops24_putchar8;
   97                 break;
   98         case 12:
   99                 ri->ri_ops.putchar = rasops24_putchar12;
  100                 break;
  101         case 16:
  102                 ri->ri_ops.putchar = rasops24_putchar16;
  103                 break;
  104 #endif
  105         default:
  106                 ri->ri_ops.putchar = rasops24_putchar;
  107                 break;
  108         }
  109 
  110         if (ri->ri_rnum == 0) {
  111                 ri->ri_rnum = 8;
  112                 ri->ri_rpos = 0;
  113                 ri->ri_gnum = 8;
  114                 ri->ri_gpos = 8;
  115                 ri->ri_bnum = 8;
  116                 ri->ri_bpos = 16;
  117         }
  118 
  119         ri->ri_ops.erasecols = rasops24_erasecols;
  120         ri->ri_ops.eraserows = rasops24_eraserows;
  121 }
  122 
  123 /*
  124  * Put a single character. This is the generic version.
  125  * XXX this bites - we should use masks.
  126  */
  127 static void
  128 rasops24_putchar(cookie, row, col, uc, attr)
  129         void *cookie;
  130         int row, col;
  131         u_int uc;
  132         long attr;
  133 {
  134         int fb, width, height, cnt, clr[2];
  135         struct rasops_info *ri;
  136         u_char *dp, *rp, *fr;
  137 
  138         ri = (struct rasops_info *)cookie;
  139 
  140 #ifdef RASOPS_CLIPPING
  141         /* Catches 'row < 0' case too */
  142         if ((unsigned)row >= (unsigned)ri->ri_rows)
  143                 return;
  144 
  145         if ((unsigned)col >= (unsigned)ri->ri_cols)
  146                 return;
  147 #endif
  148 
  149         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  150         height = ri->ri_font->fontheight;
  151         width = ri->ri_font->fontwidth;
  152 
  153         clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
  154         clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
  155 
  156         if (uc == ' ') {
  157                 u_char c = clr[0];
  158                 while (height--) {
  159                         dp = rp;
  160                         rp += ri->ri_stride;
  161 
  162                         for (cnt = width; cnt; cnt--) {
  163                                 *dp++ = c >> 16;
  164                                 *dp++ = c >> 8;
  165                                 *dp++ = c;
  166                         }
  167                 }
  168         } else {
  169                 uc -= ri->ri_font->firstchar;
  170                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  171 
  172                 while (height--) {
  173                         dp = rp;
  174                         fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
  175                             (fr[0] << 24);
  176                         fr += ri->ri_font->stride;
  177                         rp += ri->ri_stride;
  178 
  179                         for (cnt = width; cnt; cnt--, fb <<= 1) {
  180                                 if ((fb >> 31) & 1) {
  181                                         *dp++ = clr[1] >> 16;
  182                                         *dp++ = clr[1] >> 8;
  183                                         *dp++ = clr[1];
  184                                 } else {
  185                                         *dp++ = clr[0] >> 16;
  186                                         *dp++ = clr[0] >> 8;
  187                                         *dp++ = clr[0];
  188                                 }
  189                         }
  190                 }
  191         }
  192 
  193         /* Do underline */
  194         if ((attr & 1) != 0) {
  195                 u_char c = clr[1];
  196 
  197                 rp -= ri->ri_stride << 1;
  198 
  199                 while (width--) {
  200                         *rp++ = c >> 16;
  201                         *rp++ = c >> 8;
  202                         *rp++ = c;
  203                 }
  204         }
  205 }
  206 
  207 #ifndef RASOPS_SMALL
  208 /*
  209  * Recompute the blitting stamp.
  210  */
  211 static void
  212 rasops24_makestamp(ri, attr)
  213         struct rasops_info *ri;
  214         long attr;
  215 {
  216         u_int fg, bg, c1, c2, c3, c4;
  217         int i;
  218 
  219         fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffffff;
  220         bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffffff;
  221         stamp_attr = attr;
  222 
  223         for (i = 0; i < 64; i += 4) {
  224 #if BYTE_ORDER == LITTLE_ENDIAN
  225                 c1 = (i & 32 ? fg : bg);
  226                 c2 = (i & 16 ? fg : bg);
  227                 c3 = (i & 8 ? fg : bg);
  228                 c4 = (i & 4 ? fg : bg);
  229 #else
  230                 c1 = (i & 8 ? fg : bg);
  231                 c2 = (i & 4 ? fg : bg);
  232                 c3 = (i & 16 ? fg : bg);
  233                 c4 = (i & 32 ? fg : bg);
  234 #endif
  235                 stamp[i+0] = (c1 <<  8) | (c2 >> 16);
  236                 stamp[i+1] = (c2 << 16) | (c3 >>  8);
  237                 stamp[i+2] = (c3 << 24) | c4;
  238 
  239 #if BYTE_ORDER == LITTLE_ENDIAN
  240                 if ((ri->ri_flg & RI_BSWAP) == 0) {
  241 #else
  242                 if ((ri->ri_flg & RI_BSWAP) != 0) {
  243 #endif
  244                         stamp[i+0] = bswap32(stamp[i+0]);
  245                         stamp[i+1] = bswap32(stamp[i+1]);
  246                         stamp[i+2] = bswap32(stamp[i+2]);
  247                 }
  248         }
  249 }
  250 
  251 /*
  252  * Put a single character. This is for 8-pixel wide fonts.
  253  */
  254 static void
  255 rasops24_putchar8(cookie, row, col, uc, attr)
  256         void *cookie;
  257         int row, col;
  258         u_int uc;
  259         long attr;
  260 {
  261         struct rasops_info *ri;
  262         int height, so, fs;
  263         int32_t *rp;
  264         u_char *fr;
  265 
  266         /* Can't risk remaking the stamp if it's already in use */
  267         if (stamp_mutex++) {
  268                 stamp_mutex--;
  269                 rasops24_putchar(cookie, row, col, uc, attr);
  270                 return;
  271         }
  272 
  273         ri = (struct rasops_info *)cookie;
  274 
  275 #ifdef RASOPS_CLIPPING
  276         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  277                 stamp_mutex--;
  278                 return;
  279         }
  280 
  281         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  282                 stamp_mutex--;
  283                 return;
  284         }
  285 #endif
  286 
  287         /* Recompute stamp? */
  288         if (attr != stamp_attr)
  289                 rasops24_makestamp(ri, attr);
  290 
  291         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  292         height = ri->ri_font->fontheight;
  293 
  294         if (uc == (u_int)-1) {
  295                 int32_t c = stamp[0];
  296                 while (height--) {
  297                         rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
  298                         DELTA(rp, ri->ri_stride, int32_t *);
  299                 }
  300         } else {
  301                 uc -= ri->ri_font->firstchar;
  302                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  303                 fs = ri->ri_font->stride;
  304 
  305                 while (height--) {
  306                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  307                         rp[0] = STAMP_READ(so);
  308                         rp[1] = STAMP_READ(so + 4);
  309                         rp[2] = STAMP_READ(so + 8);
  310 
  311                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  312                         rp[3] = STAMP_READ(so);
  313                         rp[4] = STAMP_READ(so + 4);
  314                         rp[5] = STAMP_READ(so + 8);
  315 
  316                         fr += fs;
  317                         DELTA(rp, ri->ri_stride, int32_t *);
  318                 }
  319         }
  320 
  321         /* Do underline */
  322         if ((attr & 1) != 0) {
  323                 int32_t c = STAMP_READ(52);
  324 
  325                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  326                 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
  327         }
  328 
  329         stamp_mutex--;
  330 }
  331 
  332 /*
  333  * Put a single character. This is for 12-pixel wide fonts.
  334  */
  335 static void
  336 rasops24_putchar12(cookie, row, col, uc, attr)
  337         void *cookie;
  338         int row, col;
  339         u_int uc;
  340         long attr;
  341 {
  342         struct rasops_info *ri;
  343         int height, so, fs;
  344         int32_t *rp;
  345         u_char *fr;
  346 
  347         /* Can't risk remaking the stamp if it's already in use */
  348         if (stamp_mutex++) {
  349                 stamp_mutex--;
  350                 rasops24_putchar(cookie, row, col, uc, attr);
  351                 return;
  352         }
  353 
  354         ri = (struct rasops_info *)cookie;
  355 
  356 #ifdef RASOPS_CLIPPING
  357         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  358                 stamp_mutex--;
  359                 return;
  360         }
  361 
  362         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  363                 stamp_mutex--;
  364                 return;
  365         }
  366 #endif
  367 
  368         /* Recompute stamp? */
  369         if (attr != stamp_attr)
  370                 rasops24_makestamp(ri, attr);
  371 
  372         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  373         height = ri->ri_font->fontheight;
  374 
  375         if (uc == (u_int)-1) {
  376                 int32_t c = stamp[0];
  377                 while (height--) {
  378                         rp[0] = rp[1] = rp[2] = rp[3] = 
  379                         rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
  380                         DELTA(rp, ri->ri_stride, int32_t *);
  381                 }
  382         } else {
  383                 uc -= ri->ri_font->firstchar;
  384                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  385                 fs = ri->ri_font->stride;
  386 
  387                 while (height--) {
  388                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  389                         rp[0] = STAMP_READ(so);
  390                         rp[1] = STAMP_READ(so + 4);
  391                         rp[2] = STAMP_READ(so + 8);
  392 
  393                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  394                         rp[3] = STAMP_READ(so);
  395                         rp[4] = STAMP_READ(so + 4);
  396                         rp[5] = STAMP_READ(so + 8);
  397 
  398                         so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
  399                         rp[6] = STAMP_READ(so);
  400                         rp[7] = STAMP_READ(so + 4);
  401                         rp[8] = STAMP_READ(so + 8);
  402 
  403                         fr += fs;
  404                         DELTA(rp, ri->ri_stride, int32_t *);
  405                 }
  406         }
  407 
  408         /* Do underline */
  409         if ((attr & 1) != 0) {
  410                 int32_t c = STAMP_READ(52);
  411 
  412                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  413                 rp[0] = rp[1] = rp[2] = rp[3] =
  414                 rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
  415         }
  416 
  417         stamp_mutex--;
  418 }
  419 
  420 /*
  421  * Put a single character. This is for 16-pixel wide fonts.
  422  */
  423 static void
  424 rasops24_putchar16(cookie, row, col, uc, attr)
  425         void *cookie;
  426         int row, col;
  427         u_int uc;
  428         long attr;
  429 {
  430         struct rasops_info *ri;
  431         int height, so, fs;
  432         int32_t *rp;
  433         u_char *fr;
  434 
  435         /* Can't risk remaking the stamp if it's already in use */
  436         if (stamp_mutex++) {
  437                 stamp_mutex--;
  438                 rasops24_putchar(cookie, row, col, uc, attr);
  439                 return;
  440         }
  441 
  442         ri = (struct rasops_info *)cookie;
  443 
  444 #ifdef RASOPS_CLIPPING
  445         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  446                 stamp_mutex--;
  447                 return;
  448         }
  449 
  450         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  451                 stamp_mutex--;
  452                 return;
  453         }
  454 #endif
  455 
  456         /* Recompute stamp? */
  457         if (attr != stamp_attr)
  458                 rasops24_makestamp(ri, attr);
  459 
  460         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  461         height = ri->ri_font->fontheight;
  462 
  463         if (uc == (u_int)-1) {
  464                 int32_t c = stamp[0];
  465                 while (height--) {
  466                         rp[0] = rp[1] = rp[2] = rp[3] = 
  467                         rp[4] = rp[5] = rp[6] = rp[7] = 
  468                         rp[8] = rp[9] = rp[10] = rp[11] = c;
  469                         DELTA(rp, ri->ri_stride, int32_t *);
  470                 }
  471         } else {
  472                 uc -= ri->ri_font->firstchar;
  473                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  474                 fs = ri->ri_font->stride;
  475 
  476                 while (height--) {
  477                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  478                         rp[0] = STAMP_READ(so);
  479                         rp[1] = STAMP_READ(so + 4);
  480                         rp[2] = STAMP_READ(so + 8);
  481 
  482                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  483                         rp[3] = STAMP_READ(so);
  484                         rp[4] = STAMP_READ(so + 4);
  485                         rp[5] = STAMP_READ(so + 8);
  486 
  487                         so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
  488                         rp[6] = STAMP_READ(so);
  489                         rp[7] = STAMP_READ(so + 4);
  490                         rp[8] = STAMP_READ(so + 8);
  491 
  492                         so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
  493                         rp[9] = STAMP_READ(so);
  494                         rp[10] = STAMP_READ(so + 4);
  495                         rp[11] = STAMP_READ(so + 8);
  496 
  497                         DELTA(rp, ri->ri_stride, int32_t *);
  498                         fr += fs;
  499                 }
  500         }
  501 
  502         /* Do underline */
  503         if ((attr & 1) != 0) {
  504                 int32_t c = STAMP_READ(52);
  505 
  506                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  507                 rp[0] = rp[1] = rp[2] = rp[3] = 
  508                 rp[4] = rp[5] = rp[6] = rp[7] = 
  509                 rp[8] = rp[9] = rp[10] = rp[11] = c;
  510         }
  511 
  512         stamp_mutex--;
  513 }
  514 #endif  /* !RASOPS_SMALL */
  515 
  516 /*
  517  * Erase rows. This is nice and easy due to alignment.
  518  */
  519 static void
  520 rasops24_eraserows(cookie, row, num, attr)
  521         void *cookie;
  522         int row, num;
  523         long attr;
  524 {
  525         int n9, n3, n1, cnt, stride, delta;
  526         u_int32_t *dp, clr, stamp[3];
  527         struct rasops_info *ri;
  528 
  529         /*
  530          * If the color is gray, we can cheat and use the generic routines
  531          * (which are faster, hopefully) since the r,g,b values are the same.
  532          */
  533         if ((attr & 4) != 0) {
  534                 rasops_eraserows(cookie, row, num, attr);
  535                 return;
  536         }
  537 
  538         ri = (struct rasops_info *)cookie;
  539 
  540 #ifdef RASOPS_CLIPPING
  541         if (row < 0) {
  542                 num += row;
  543                 row = 0;
  544         }
  545 
  546         if ((row + num) > ri->ri_rows)
  547                 num = ri->ri_rows - row;
  548 
  549         if (num <= 0)
  550                 return;
  551 #endif
  552 
  553         clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
  554         stamp[0] = (clr <<  8) | (clr >> 16);
  555         stamp[1] = (clr << 16) | (clr >>  8);
  556         stamp[2] = (clr << 24) | clr;
  557 
  558 #if BYTE_ORDER == LITTLE_ENDIAN
  559         if ((ri->ri_flg & RI_BSWAP) == 0) {
  560 #else
  561         if ((ri->ri_flg & RI_BSWAP) != 0) {
  562 #endif
  563                 stamp[0] = bswap32(stamp[0]);
  564                 stamp[1] = bswap32(stamp[1]);
  565                 stamp[2] = bswap32(stamp[2]);
  566         }
  567 
  568         /*
  569          * XXX the wsdisplay_emulops interface seems a little deficient in
  570          * that there is no way to clear the *entire* screen. We provide a
  571          * workaround here: if the entire console area is being cleared, and
  572          * the RI_FULLCLEAR flag is set, clear the entire display.
  573          */
  574         if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
  575                 stride = ri->ri_stride;
  576                 num = ri->ri_height;
  577                 dp = (int32_t *)ri->ri_origbits;
  578                 delta = 0;
  579         } else {
  580                 stride = ri->ri_emustride;
  581                 num *= ri->ri_font->fontheight;
  582                 dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
  583                 delta = ri->ri_delta;
  584         }
  585 
  586         n9 = stride / 36;
  587         cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
  588         n3 = (stride - cnt) / 12;
  589         cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
  590         n1 = (stride - cnt) >> 2;
  591 
  592         while (num--) {
  593                 for (cnt = n9; cnt; cnt--) {
  594                         dp[0] = stamp[0];
  595                         dp[1] = stamp[1];
  596                         dp[2] = stamp[2];
  597                         dp[3] = stamp[0];
  598                         dp[4] = stamp[1];
  599                         dp[5] = stamp[2];
  600                         dp[6] = stamp[0];
  601                         dp[7] = stamp[1];
  602                         dp[8] = stamp[2];
  603                         dp += 9;
  604                 }
  605 
  606                 for (cnt = n3; cnt; cnt--) {
  607                         dp[0] = stamp[0];
  608                         dp[1] = stamp[1];
  609                         dp[2] = stamp[2];
  610                         dp += 3;
  611                 }
  612 
  613                 for (cnt = 0; cnt < n1; cnt++)
  614                         *dp++ = stamp[cnt];
  615 
  616                 DELTA(dp, delta, int32_t *);
  617         }
  618 }
  619 
  620 /*
  621  * Erase columns.
  622  */
  623 static void
  624 rasops24_erasecols(cookie, row, col, num, attr)
  625         void *cookie;
  626         int row, col, num;
  627         long attr;
  628 {
  629         int n12, n4, height, cnt, slop, clr, stamp[3];
  630         struct rasops_info *ri;
  631         int32_t *dp, *rp;
  632         u_char *dbp;
  633 
  634         /*
  635          * If the color is gray, we can cheat and use the generic routines
  636          * (which are faster, hopefully) since the r,g,b values are the same.
  637          */
  638         if ((attr & 4) != 0) {
  639                 rasops_erasecols(cookie, row, col, num, attr);
  640                 return;
  641         }
  642 
  643         ri = (struct rasops_info *)cookie;
  644 
  645 #ifdef RASOPS_CLIPPING
  646         /* Catches 'row < 0' case too */
  647         if ((unsigned)row >= (unsigned)ri->ri_rows)
  648                 return;
  649 
  650         if (col < 0) {
  651                 num += col;
  652                 col = 0;
  653         }
  654 
  655         if ((col + num) > ri->ri_cols)
  656                 num = ri->ri_cols - col;
  657 
  658         if (num <= 0)
  659                 return;
  660 #endif
  661 
  662         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  663         num *= ri->ri_font->fontwidth;
  664         height = ri->ri_font->fontheight;
  665 
  666         clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
  667         stamp[0] = (clr <<  8) | (clr >> 16);
  668         stamp[1] = (clr << 16) | (clr >>  8);
  669         stamp[2] = (clr << 24) | clr;
  670 
  671 #if BYTE_ORDER == LITTLE_ENDIAN
  672         if ((ri->ri_flg & RI_BSWAP) == 0) {
  673 #else
  674         if ((ri->ri_flg & RI_BSWAP) != 0) {
  675 #endif
  676                 stamp[0] = bswap32(stamp[0]);
  677                 stamp[1] = bswap32(stamp[1]);
  678                 stamp[2] = bswap32(stamp[2]);
  679         }
  680 
  681         /*
  682          * The current byte offset mod 4 tells us the number of 24-bit pels
  683          * we need to write for alignment to 32-bits. Once we're aligned on
  684          * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so
  685          * the stamp does not need to be rotated. The following shows the
  686          * layout of 4 pels in a 3 word region and illustrates this:
  687          *
  688          *      aaab bbcc cddd
  689          */
  690         slop = (int)(long)rp & 3;       num -= slop;
  691         n12 = num / 12;         num -= (n12 << 3) + (n12 << 2);
  692         n4 = num >> 2;          num &= 3;
  693 
  694         while (height--) {
  695                 dbp = (u_char *)rp;
  696                 DELTA(rp, ri->ri_stride, int32_t *);
  697 
  698                 /* Align to 4 bytes */
  699                 /* XXX handle with masks, bring under control of RI_BSWAP */
  700                 for (cnt = slop; cnt; cnt--) {
  701                         *dbp++ = (clr >> 16);
  702                         *dbp++ = (clr >> 8);
  703                         *dbp++ = clr;
  704                 }
  705 
  706                 dp = (int32_t *)dbp;
  707 
  708                 /* 12 pels per loop */
  709                 for (cnt = n12; cnt; cnt--) {
  710                         dp[0] = stamp[0];
  711                         dp[1] = stamp[1];
  712                         dp[2] = stamp[2];
  713                         dp[3] = stamp[0];
  714                         dp[4] = stamp[1];
  715                         dp[5] = stamp[2];
  716                         dp[6] = stamp[0];
  717                         dp[7] = stamp[1];
  718                         dp[8] = stamp[2];
  719                         dp += 9;
  720                 }
  721 
  722                 /* 4 pels per loop */
  723                 for (cnt = n4; cnt; cnt--) {
  724                         dp[0] = stamp[0];
  725                         dp[1] = stamp[1];
  726                         dp[2] = stamp[2];
  727                         dp += 3;
  728                 }
  729 
  730                 /* Trailing slop */
  731                 /* XXX handle with masks, bring under control of RI_BSWAP */
  732                 dbp = (u_char *)dp;
  733                 for (cnt = num; cnt; cnt--) {
  734                         *dbp++ = (clr >> 16);
  735                         *dbp++ = (clr >> 8);
  736                         *dbp++ = clr;
  737                 }
  738         }
  739 }

Cache object: e75857520a68f283e632c03a50b4e945


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.