Annotation of ntddk/src/video/displays/vga256/brush.c, revision 1.1.1.1

1.1       root        1: /******************************Module*Header*******************************\
                      2: * Module Name: Brush.c
                      3: *
                      4: * Brush support.
                      5: *
                      6: * Copyright (c) 1992-1993 Microsoft Corporation
                      7: *
                      8: \**************************************************************************/
                      9: 
                     10: #include "driver.h"
                     11: 
                     12: /****************************************************************************
                     13:  * DrvRealizeBrush
                     14:  ***************************************************************************/
                     15: 
                     16: BOOL DrvRealizeBrush(
                     17: BRUSHOBJ* pbo,
                     18: SURFOBJ*  psoTarget,
                     19: SURFOBJ*  psoPattern,
                     20: SURFOBJ*  psoMask,
                     21: XLATEOBJ* pxlo,
                     22: ULONG     iHatch)
                     23: {
                     24:     RBRUSH* prb;        // Pointer to where realization goes
                     25:     ULONG*  pulSrc;     // Temporary pointer
                     26:     ULONG*  pulDst;     // Temporary pointer
                     27:     BYTE*   pjSrc;
                     28:     BYTE*   pjDst;
                     29:     ULONG*  pulRBits;   // Points to RBRUSH pattern bits
                     30:     BYTE    jBkColor;
                     31:     BYTE    jFgColor;
                     32:     LONG    i;
                     33:     LONG    j;
                     34: 
                     35:     PPDEV   ppdev = (PPDEV) psoTarget->dhsurf;
                     36: 
                     37:     // For now, we only accelerate patterns using the latches, and we
                     38:     // sometimes need offscreen memory as a temporary work space to
                     39:     // initialize the latches for 2-color patterns:
                     40: 
                     41:     if ((ppdev->fl & (DRIVER_PLANAR_CAPABLE | DRIVER_HAS_OFFSCREEN)) !=
                     42:         (DRIVER_PLANAR_CAPABLE | DRIVER_HAS_OFFSCREEN) )
                     43:     {
                     44:         return(FALSE);
                     45:     }
                     46: 
                     47:     // See if it's a default hatch brush:
                     48: 
                     49:     if (iHatch < HS_DDI_MAX)
                     50:     {
                     51:         DISPDBG((1, "\n  RBrush: Default"));
                     52: 
                     53:         prb = BRUSHOBJ_pvAllocRbrush(pbo, sizeof(RBRUSH));
                     54:         if (prb == NULL)
                     55:             return(FALSE);
                     56: 
                     57:         prb->xBrush    = 0;
                     58:         prb->ulBkColor = (pxlo->pulXlate[0] & 0xff);
                     59:         prb->ulFgColor = (pxlo->pulXlate[1] & 0xff);
                     60: 
                     61:         if (prb->ulFgColor == 0xff && prb->ulBkColor == 0x00)
                     62:         {
                     63:             prb->fl = RBRUSH_BLACKWHITE;
                     64:             memcpy(&prb->aulPattern[0],
                     65:                    &gaaulPlanarPat[iHatch][0],
                     66:                    8 * sizeof(DWORD));
                     67:         }
                     68:         else if (prb->ulFgColor == 0x00 && prb->ulBkColor == 0xff)
                     69:         {
                     70:             // We have to invert the brush:
                     71: 
                     72:             prb->fl = RBRUSH_BLACKWHITE;
                     73:             for (i = 0; i < 8; i++)
                     74:             {
                     75:                 prb->aulPattern[i] = ~gaaulPlanarPat[iHatch][i];
                     76:             }
                     77:         }
                     78:         else
                     79:         {
                     80:             prb->fl = RBRUSH_2COLOR;
                     81:             memmove(&prb->aulPattern[0], &gaaulPlanarPat[iHatch][0], 32);
                     82:         }
                     83: 
                     84:         return(TRUE);
                     85:     }
                     86: 
                     87:     // We only accelerate 8x8 patterns:
                     88: 
                     89:     if (psoPattern->sizlBitmap.cx != 8 || psoPattern->sizlBitmap.cy != 8)
                     90:         return(FALSE);
                     91: 
                     92:     // We only implement n-color patterns on devices that have multiple
                     93:     // or separate read/write banks:
                     94: 
                     95:     if (ppdev->vbtPlanarType == VideoBanked1RW)
                     96:         return(FALSE);
                     97: 
                     98:     // We also only handle 1bpp, 4bpp and 8bpp patterns:
                     99: 
                    100:     if (psoPattern->iBitmapFormat > BMF_8BPP)
                    101:         return(FALSE);
                    102: 
                    103:     // At this point, we're definitely going to realize the brush:
                    104: 
                    105:     prb = BRUSHOBJ_pvAllocRbrush(pbo, sizeof(RBRUSH));
                    106:     if (prb == NULL)
                    107:         return(FALSE);
                    108: 
                    109:     pulRBits = &prb->aulPattern[0];
                    110: 
                    111:     DISPDBG((1, "\n  RBrush: "));
                    112: 
                    113:     // If 8bpp or 4bpp, copy the bitmap to our local buffer:
                    114: 
                    115:     if (psoPattern->iBitmapFormat == BMF_1BPP)
                    116:     {
                    117:         ULONG ulFlippedGlyph;
                    118: 
                    119:         DISPDBG((1, "1bpp "));
                    120: 
                    121:         // First, convert the bits to our desired format:
                    122: 
                    123:         pjSrc  = psoPattern->pvScan0;
                    124:         pulDst = pulRBits;
                    125:         for (i = 8; i > 0; i--)
                    126:         {
                    127:             // We want to take the byte with bits 76543210 and convert it
                    128:             // to the word 4567012301234567.  The pjGlyphFlipTable gives
                    129:             // us 45670123 from 76543210.
                    130: 
                    131:             ulFlippedGlyph = (ULONG) ppdev->pjGlyphFlipTable[*pjSrc];
                    132:             *pulDst = (ulFlippedGlyph << 8) | ((ulFlippedGlyph & 15) << 4) |
                    133:                       (ulFlippedGlyph >> 4);
                    134: 
                    135:             pulDst++;
                    136:             pjSrc += psoPattern->lDelta;
                    137:         }
                    138: 
                    139:         // Now initialize the rest of the RBrush fields:
                    140: 
                    141:         prb->xBrush    = 0;
                    142:         prb->ulBkColor = (pxlo->pulXlate[0] & 0xff);
                    143:         prb->ulFgColor = (pxlo->pulXlate[1] & 0xff);
                    144: 
                    145:         if (prb->ulFgColor == 0xff && prb->ulBkColor == 0x00)
                    146:         {
                    147:             prb->fl = RBRUSH_BLACKWHITE;
                    148:         }
                    149:         else if (prb->ulFgColor == 0x00 && prb->ulBkColor == 0xff)
                    150:         {
                    151:             // We have to invert the brush:
                    152: 
                    153:             prb->fl = RBRUSH_BLACKWHITE;
                    154:             for (i = 0; i < 8; i++)
                    155:             {
                    156:                 prb->aulPattern[i] = ~prb->aulPattern[i];
                    157:             }
                    158:         }
                    159:         else
                    160:         {
                    161:             prb->fl = RBRUSH_2COLOR;
                    162:         }
                    163: 
                    164:         return(TRUE);
                    165:     }
                    166:     else if (psoPattern->iBitmapFormat == BMF_8BPP)
                    167:     {
                    168: 
                    169:         if (pxlo == NULL || pxlo->flXlate & XO_TRIVIAL)
                    170:         {
                    171:             pulSrc = psoPattern->pvScan0;
                    172:             pulDst = pulRBits;
                    173: 
                    174:             DISPDBG((1, "8bpp noxlate "));
                    175: 
                    176:             // 8bpp no translate case:
                    177: 
                    178:             for (i = 4; i > 0; i--)
                    179:             {
                    180:                 *(pulDst)     = *(pulSrc);
                    181:                 *(pulDst + 1) = *(pulSrc + 1);
                    182:                 pulSrc = (ULONG*) ((BYTE*) pulSrc + psoPattern->lDelta);
                    183: 
                    184:                 *(pulDst + 2) = *(pulSrc);
                    185:                 *(pulDst + 3) = *(pulSrc + 1);
                    186: 
                    187:                 pulSrc = (ULONG*) ((BYTE*) pulSrc + psoPattern->lDelta);
                    188:                 pulDst += 4;
                    189:             }
                    190:         }
                    191:         else
                    192:         {
                    193:             pjSrc = (BYTE*) psoPattern->pvScan0;
                    194:             pjDst = (BYTE*) pulRBits;
                    195: 
                    196:             DISPDBG((1, "8bpp xlate "));
                    197: 
                    198:             // 8bpp translate case:
                    199: 
                    200:             for (i = 8; i > 0; i--)
                    201:             {
                    202:                 for (j = 8; j > 0; j--)
                    203:                 {
                    204:                     *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc++];
                    205:                 }
                    206: 
                    207:                 pjSrc += psoPattern->lDelta - 8;
                    208:             }
                    209:         }
                    210:     }
                    211:     else
                    212:     {
                    213:         DISPDBG((1, "4bpp xlate "));
                    214: 
                    215:         ASSERTVGA(psoPattern->iBitmapFormat == BMF_4BPP, "Extra case added?");
                    216: 
                    217:         // 4bpp case:
                    218: 
                    219:         pjSrc = (BYTE*) psoPattern->pvScan0;
                    220:         pjDst = (BYTE*) pulRBits;
                    221: 
                    222:         for (i = 8; i > 0; i--)
                    223:         {
                    224:             // Inner loop is repeated only 4 times because each loop handles
                    225:             // 2 pixels:
                    226: 
                    227:             for (j = 4; j > 0; j--)
                    228:             {
                    229:                 *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc >> 4];
                    230:                 *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc & 15];
                    231:                 pjSrc++;
                    232:             }
                    233: 
                    234:             pjSrc += psoPattern->lDelta - 4;
                    235:         }
                    236:     }
                    237: 
                    238:     // We want to check if the 4bpp or 8bpp patterns are actually
                    239:     // only two colors:
                    240: 
                    241:     if (b2ColorBrush(pulRBits, &jFgColor, &jBkColor))
                    242:     {
                    243:         DISPDBG((1, "2 color "));
                    244: 
                    245:         // ??? We could actually also handle this case even if we have only
                    246:         // 1 r/w window in planar format:
                    247: 
                    248:         prb->xBrush    = 0;
                    249:         prb->ulBkColor = (ULONG) jBkColor;
                    250:         prb->ulFgColor = (ULONG) jFgColor;
                    251:         prb->fl        = RBRUSH_2COLOR;
                    252: 
                    253:         if (jFgColor == 0x00 && jBkColor == 0xff)
                    254:         {
                    255:             // Monochrome brushes always have to have the '0' bits
                    256:             // as black and the '1' bits as white, so we'll have to
                    257:             // invert the 1bpp pattern:
                    258: 
                    259:             prb->fl = RBRUSH_BLACKWHITE;
                    260:             for (i = 0; i < 8; i++)
                    261:             {
                    262:                 prb->aulPattern[i] = ~prb->aulPattern[i];
                    263:             }
                    264:         }
                    265: 
                    266:         return(TRUE);
                    267:     }
                    268: 
                    269:     // For n-color brushes, we maintain a brush cache in offscreen memory.
                    270:     // If the DRIVER_USE_OFFSCREEN flag isn't set (i.e., the offscreen
                    271:     // memory isn't being refreshed), the cache is pretty useless.  In that
                    272:     // case, we simply disable n-color patterns:
                    273: 
                    274:     if ((ppdev->fl & DRIVER_USE_OFFSCREEN) == 0)
                    275:     {
                    276:         return(FALSE);
                    277:     }
                    278: 
                    279:     prb->fl     = RBRUSH_NCOLOR;
                    280:     prb->cy     = 8;
                    281:     prb->cyLog2 = 3;
                    282: 
                    283:     // xBrush is the brush alignment for the cached brush, and this value
                    284:     // will get compared to (pptlBrush->x & 7) to see if the cache brush
                    285:     // is correctly aligned with the brush requested.  Since it will never
                    286:     // match with -1, the brush will be correctly aligned and placed in
                    287:     // the cache (which, of course, is what we want to finish our
                    288:     // initialization):
                    289: 
                    290:     prb->xBrush = -1;
                    291: 
                    292:     // Copy those bitmap bits:
                    293: 
                    294:     // See if pattern is really only 4 scans long:
                    295: 
                    296:     if (pulRBits[0] == pulRBits[8]  && pulRBits[1] == pulRBits[9]  &&
                    297:         pulRBits[2] == pulRBits[10] && pulRBits[3] == pulRBits[11] &&
                    298:         pulRBits[4] == pulRBits[12] && pulRBits[5] == pulRBits[13] &&
                    299:         pulRBits[6] == pulRBits[14] && pulRBits[7] == pulRBits[15])
                    300:     {
                    301:         prb->cy     = 4;
                    302:         prb->cyLog2 = 2;
                    303: 
                    304:         // See if pattern is really only 2 scans long:
                    305: 
                    306:         if (pulRBits[0] == pulRBits[4] && pulRBits[1] == pulRBits[5] &&
                    307:             pulRBits[2] == pulRBits[6] && pulRBits[3] == pulRBits[7])
                    308:         {
                    309:             DISPDBG((1, "cy = 2 "));
                    310: 
                    311:             prb->cy     = 2;
                    312:             prb->cyLog2 = 1;
                    313:         }
                    314:         else
                    315:         {
                    316:             DISPDBG((1, "cy = 4 "));
                    317:         }
                    318:     }
                    319: 
                    320:     // See if pattern is really only 4 pels wide:
                    321: 
                    322:     pulDst = pulRBits;
                    323:     for (i = prb->cy / 2; i > 0; i--)
                    324:     {
                    325:         if (*(pulDst    ) != *(pulDst + 1) ||
                    326:             *(pulDst + 2) != *(pulDst + 3))
                    327:             goto done_this_realize_brush_stuff;
                    328: 
                    329:         pulDst += 4;
                    330:     }
                    331: 
                    332:     DISPDBG((1, "4pels wide"));
                    333: 
                    334:     prb->fl |= RBRUSH_4PELS_WIDE;
                    335: 
                    336: done_this_realize_brush_stuff:
                    337: 
                    338:     return(TRUE);
                    339: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.